diff -u --recursive --new-file v2.3.47/linux/CREDITS linux/CREDITS
--- v2.3.47/linux/CREDITS	Sun Feb 20 21:12:38 2000
+++ linux/CREDITS	Fri Feb 25 10:26:41 2000
@@ -1259,6 +1259,12 @@
 E: ajk@iehk.rwth-aachen.de
 D: 6pack driver for AX.25
 
+N: Harald Koerfgen
+E: harald@unix-ag.org
+D: DECstation port
+S: D-50931 Koeln
+S: Germany
+
 N: Willy Konynenberg
 E: willy@xos.nl
 W: http://www.xos.nl/
@@ -1505,15 +1511,17 @@
 S: USA
 
 N: Martin Mares
-E: mj@atrey.karlin.mff.cuni.cz
+E: mj@suse.cz
+E: mj@ucw.cz
 W: http://atrey.karlin.mff.cuni.cz/~mj/
 D: BIOS video mode handling code
 D: MOXA C-218 serial board driver
 D: Network autoconfiguration
+D: PCI subsystem
 D: Random kernel hacking
 S: Kankovskeho 1241
 S: 182 00 Praha 8
-S: Czech Republic 
+S: Czech Republic
 
 N: John A. Martin
 E: jam@acm.org
@@ -2017,6 +2025,14 @@
 S: Canberra ACT 2601
 S: Australia
 
+N: Sampo Saaristo
+E: sambo@cs.tut.fi
+D: Co-author of Multi-Protocol Over ATM (MPOA)
+S: Tampere University of Technology / Telecom lab
+S: Hermiankatu 12C
+S: FIN-33720 Tampere
+S: Finland
+
 N: Thomas Sailer
 E: sailer@ife.ee.ethz.ch
 E: HB9JNX@HB9W.CHE.EU (packet radio)
@@ -2399,6 +2415,14 @@
 S: Nashua, New Hampshire 03062
 S: USA
 
+N: Heikki Vatiainen
+E: hessu@cs.tut.fi
+D: Co-author of Multi-Protocol Over ATM (MPOA), some LANE hacks
+S: Tampere University of Technology / Telecom lab
+S: Hermiankatu 12C
+S: FIN-33720 Tampere
+S: Finland
+
 N: Andrew Veliath
 E: andrewtv@usa.net
 D: Turtle Beach MultiSound sound driver
@@ -2425,6 +2449,14 @@
 S: 1098 VA Amsterdam 
 S: The Netherlands
 
+N: Peter Shaobo Wang
+E: pwang@mmdcorp.com
+W: http://www.mmdcorp.com/pw/linux
+D: Driver for Interphase ATM (i)Chip SAR adapter card family (x575, x525, x531).
+S: 1513 Brewster Dr.
+S: Carrollton, TX 75010
+S: USA
+
 N: Tim Waugh
 E: tim@cyberelk.demon.co.uk
 D: Co-architect of the parallel-port sharing system
@@ -2463,6 +2495,14 @@
 S: Computer Science Division
 S: UC Berkeley
 S: Berkeley, CA 94720-1776
+S: USA
+
+N: Bill Wendling
+E: wendling@ganymede.isdn.uiuc.edu
+W: http://www.ncsa.uiuc.edu/~wendling/
+D: Various random hacks. Mostly on poll/select logic.
+S: 605 E. Springfield Ave.
+S: Champaign, IL 61820
 S: USA
 
 N: Mike Westall
diff -u --recursive --new-file v2.3.47/linux/Documentation/Changes linux/Documentation/Changes
--- v2.3.47/linux/Documentation/Changes	Tue Jan 11 22:31:35 2000
+++ linux/Documentation/Changes	Mon Feb 21 11:04:30 2000
@@ -33,7 +33,7 @@
    Also, don't forget http://www.linuxhq.com/ for all your Linux kernel
 needs.
 
-Last updated: March 16, 1999
+Last updated: Feb 21, 2000
 Current Author: Chris Ricker (kaboom@gatech.edu or chris.ricker@m.cc.utah.edu).
 
 Current Minimal Requirements
@@ -512,6 +512,12 @@
 Older isdn4k-utils versions don't support EXTRAVERSION into kernel version
 string.
 
+Logical Volume Manager
+======================
+Since 2.3.47 the kernel contains the Logical Volume Manager aka LVM. To use it,
+you need to install the LVM tools. More information can be found at the home page
+of the LVM project at http://linux.msede.com/lvm/.
+
 
 Where to get the files
 **********************
@@ -751,9 +757,9 @@
 PCI utils
 =========
 
-The 2.0 release:
-ftp://atrey.karlin.mff.cuni.cz/pub/linux/pci/pciutils-2.0.tar.gz
-ftp://metalab.unc.edu/pub/Linux/hardware/pciutils-2.0.tar.gz
+The 2.1.5 release:
+ftp://atrey.karlin.mff.cuni.cz/pub/linux/pci/pciutils-2.1.5.tar.gz
+ftp://metalab.unc.edu/pub/Linux/hardware/pciutils-2.1.5.tar.gz
 
 Powertweak
 ==========
@@ -795,8 +801,16 @@
 
 ISDN4Linux
 ==========
+
 The v3.1beta7 release:
 ftp://ftp.isdn4linux.de/pub/isdn4linux/utils/testing/isdn4k-utils.v3.1beta7.tar.gz
+
+Logical Volume Manager
+======================
+
+The 0.7 release:
+ftp://linux.msede.com/lvm/v0.7/lvm_0.7.tar.gz
+
 
 Other Info
 ==========
diff -u --recursive --new-file v2.3.47/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.3.47/linux/Documentation/Configure.help	Sun Feb 20 21:12:38 2000
+++ linux/Documentation/Configure.help	Sat Feb 26 20:32:12 2000
@@ -323,27 +323,31 @@
 Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support
 CONFIG_BLK_DEV_IDE
   If you say Y here, you will use the full-featured IDE driver to
-  control up to eight IDE interfaces, each being able to serve a
-  "master" and a "slave" device, for a total of up to sixteen IDE
+  control up to ten ATA/IDE interfaces, each being able to serve a
+  "master" and a "slave" device, for a total of up to twenty ATA/IDE
   disk/cdrom/tape/floppy drives. People with SCSI-only systems
-  can say N here.
+  can say N or M here.
 
   Useful information about large (>540 MB) IDE disks, multiple
-  interfaces, what to do if IDE devices are not automatically
-  detected, sound card IDE ports, module support, and other topics, is
-  contained in Documentation/ide.txt. For detailed information about
+  interfaces, what to do if ATA/IDE devices are not automatically
+  detected, sound card ATA/IDE ports, module support, and other topics, is
+  contained in Documentation/ata-ide.txt. For detailed information about
   hard drives, consult the Disk-HOWTO and the Multi-Disk-HOWTO,
   available from http://www.linuxdoc.org/docs.html#howto .
 
-  To fine-tune IDE drive/interface parameters for improved
+  To fine-tune ATA/IDE drive/interface parameters for improved
+  performance, look for the hdparm package at
+  ftp://metalab.unc.edu/pub/Linux/kernel/patches/diskdrives/ .
+
+  To fine-tune ATA/IDE drive/interface parameters for improved
   performance, look for the hdparm package at
   ftp://metalab.unc.edu/pub/Linux/kernel/patches/diskdrives/ .
 
   If you want to compile this driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
   say M here and read Documentation/modules.txt and
-  Documentation/ide.txt. The module will be called ide.o. Do not
-  compile this driver as a module if your root file system (the one
+  Documentation/ide.txt. The module will be called ide-mod.o. Do not
+  compile this driver as a module if your root filesystem (the one
   containing the directory /) is located on an IDE device.
 
   If you have one or more IDE drives, say Y or M here. If your system
@@ -557,13 +561,6 @@
 
   People with SCSI-only systems should say N here. If unsure, say Y.
 
-Cyrix CS5530 MediaGX chipset support
-CONFIG_BLK_DEV_CS5530
-  Include support for UDMA on the Cyrix MediaGX 5530 chipset. This
-  will automatically be detected and configured if found.
-
-  It is safe to say Y to this question.
-
 Generic PCI IDE chipset support
 CONFIG_BLK_DEV_IDEPCI
   Say Y here for PCI systems which use IDE drive(s).
@@ -572,6 +569,15 @@
   
   People with SCSI-only systems should say N here; if unsure say Y.
 
+Support for sharing PCI IDE interrupts
+CONFIG_IDEPCI_SHARE_IRQ
+  Some ATA/IDE chipsets have hardware support which allows for
+  sharing a single IRQ with other cards. To enable support for
+  this in the ATA/IDE driver, say Y here.
+
+  It is safe to say Y to this question, in most cases.
+  If unsure, say N.
+
 Generic PCI bus-master DMA support
 CONFIG_BLK_DEV_IDEDMA_PCI
   If your PCI system uses IDE drive(s) (as opposed to SCSI, say) and
@@ -584,7 +590,7 @@
   the latest version of the hdparm utility from
   ftp://metalab.unc.edu/pub/Linux/system/hardware/ .
 
-  Read the comments at the beginning of drivers/block/idedma.c and the
+  Read the comments at the beginning of drivers/block/ide-dma.c and the
   file Documentation/ide.txt for more information. 
 
   It is safe to say Y to this question.
@@ -614,7 +620,7 @@
 
   If you say Y here, and you actually want to reverse the device scan
   order as explained above, you also need to issue the kernel command
-  line option "pci=reverse". (Try "man bootparam" or see the
+  line option "ide=reverse". (Try "man bootparam" or see the
   documentation of your boot loader (lilo or loadlin) about how to
   pass options to the kernel at boot time. The lilo procedure is also
   explained in the SCSI-HOWTO, available from
@@ -639,6 +645,23 @@
   It is normally safe to answer Y to this question unless your
   motherboard uses a VIA VP2 chipset, in which case you should say N.
 
+Various ATA, Work(s) In Progress (EXPERIMENTAL)
+CONFIG_IDEDMA_PCI_WIP
+  If you enable this you will be capable of using and testing
+  highly developmentail projects.
+
+  It is SAFEST to say N to this question.
+
+3ware Hardware ATA-RAID support (EXPERIMENTAL)
+CONFIG_BLK_DEV_3W_XXXX_RAID
+  3ware is the only hardware ATA-Raid product in Linux to date.
+  This card is 2,4, or 8 channel master mode support only.
+  SCSI support required!!!
+
+  http://www.3ware.com/
+
+  Please read the comments at the top of drivers/scsi/3w-xxxx.c  
+
 AEC6210 chipset support
 CONFIG_BLK_DEV_AEC6210
   This driver adds up to 4 more EIDE devices sharing a single
@@ -648,6 +671,12 @@
   available".
 
   Please read the comments at the top of drivers/block/aec6210.c
+  If you say Y here, then say Y to "Use DMA by default when available" as well.
+
+AEC6210 Tuning support (WIP)
+CONFIG_AEC6210_TUNING
+  Please read the comments at the top of drivers/block/aec6210.c  
+  If unsure, say N.
 
 ALI M15x3 chipset support
 CONFIG_BLK_DEV_ALI15X3
@@ -655,9 +684,8 @@
   1535, 1535D onboard chipsets.  It also tests for Simplex mode and
   enables normal dual channel support.
 
-  If you say Y here, you also need to say Y to "Use DMA by default
-  when available", above.
   Please read the comments at the top of drivers/block/alim15x3.c
+  If you say Y here, then say Y to "Use DMA by default when available" as well.
 
   If unsure, say N.
 
@@ -665,10 +693,14 @@
 CONFIG_BLK_DEV_AMD7409
   This driver ensures (U)DMA support for AMD756 Viper chipset.
 
-  If you say Y here, you also need to say Y to "Use DMA by default
-  when available", above.
   Please read the comments at the top of drivers/block/amd7409.c
+  If you say Y here, then say Y to "Use DMA by default when available" as well.
+  If unsure, say N.
 
+AMD Viper ATA-66 Override support (WIP)
+CONFIG_AMD7409_OVERRIDE
+  This option auto-forces the ata66 flag.
+  This effect can be also invoked by calling "idex=ata66"
   If unsure, say N.
 
 CMD64X chipset support
@@ -676,8 +708,8 @@
   Say Y here if you have an IDE controller which uses any of these chipsets,
   CMD643, CMD646, or CMD648.
 
-CMD64X chipset RAID support (EXPERIMENTAL) (WIP)
-CONFIG_BLK_DEV_CMD64X
+CMD64X chipset RAID support (WIP)
+CONFIG_CMD64X_RAID
   Work in progress for hardware raid ata-33/66..........rev 7 minimum.
   Say N for now.
 
@@ -686,8 +718,14 @@
   This driver adds detection and support for the CY82C693 chipset
   used on Digital's PC-Alpha 164SX boards.
 
-  If you say Y here, you need to say Y to "Use DMA by default
-  when available" as well.
+  If you say Y here, then say Y to "Use DMA by default when available" as well.
+
+Cyrix CS5530 MediaGX chipset support
+CONFIG_BLK_DEV_CS5530
+  Include support for UDMA on the Cyrix MediaGX 5530 chipset. This
+  will automatically be detected and configured if found.
+
+  It is safe to say Y to this question.
 
 HPT34X chipset support
 CONFIG_BLK_DEV_HPT34X
@@ -698,12 +736,13 @@
   chipset during the ide-probe at boot time. It is reported to support
   DVD II drives, by the manufacturer.
 
-HPT34X DMA support (EXPERIMENTAL)
-CONFIG_BLK_DEV_HPT34X_DMA
-  you need to say Y to "Use DMA by default when available" if you say
-  Y here.
-
+HPT34X AUTODMA support (WIP)
+CONFIG_HPT34X_AUTODMA
+  This is a dangerous thing to attempt currently!
   Please read the comments at the top of drivers/block/hpt34x.c
+  If you say Y here, then say Y to "Use DMA by default when available" as well.
+
+  If unsure, say N.
 
 HPT366 chipset support
 CONFIG_BLK_DEV_HPT366
@@ -716,13 +755,14 @@
   manufacturer.
 
   Please read the comments at the top of drivers/block/hpt366.c
+  If you say Y here, then say Y to "Use DMA by default when available" as well.
 
-HPT366 Fast Interrupt support (EXPERIMENTAL) (WIP)
-CONFIG_HPT366_FAST_IRQ_PREDICTION
+HPT366 Fast Interrupts (WIP)
+CONFIG_HPT366_FIP
 
   If unsure, say N.
 
-HPT366 mode three unsupported (EXPERIMENTAL) (WIP)
+HPT366 mode three unsupported (WIP)
 CONFIG_HPT366_MODE3
   This is an undocumented mode that the HA366 can default to in many cases.
   If unsure, say N.
@@ -748,11 +788,11 @@
 
   Please read the comments at the top of drivers/block/piix.c
 
-  Should also include "PIIXn Tuning support" CONFIG_BLK_DEV_PIIX_TUNING
+  Should also include "PIIXn Tuning support" CONFIG_PIIX_TUNING
   If unsure, say Y.
 
 PIIXn Tuning support
-CONFIG_BLK_DEV_PIIX_TUNING
+CONFIG_PIIX_TUNING
   This driver extension adds DMA mode setting and tuning for all PIIX
   IDE controllers by Intel. Since the BIOS can sometimes improperly
   set up the device/adapter combination and speed limits, it has
@@ -784,15 +824,13 @@
   boot-time for max-speed. Note tested limits are UDMA-2. Ultra66 BIOS
   1.11 or newer required.
 
-  If you say Y here, you need to say Y to "Use DMA by default when
-  available" as well.
-
+  If you say Y here, then say Y to "Use DMA by default when available" as well.
   Please read the comments at the top of drivers/block/pdc202xx.c
 
   If unsure, say N.
 
 Special UDMA Feature
-CONFIG_PDC202XX_FORCE_BURST_BIT
+CONFIG_PDC202XX_BURST
   For PDC20246 and PDC20262 Ultra DMA chipsets. Designed originally
   for PDC20246/Ultra33 that has BIOS setup failures when using 3 or
   more cards.
@@ -801,8 +839,8 @@
 
   If unsure, say N.
 
-Special Mode Feature (EXPERIMENTAL)
-CONFIG_PDC202XX_FORCE_MASTER_MODE
+Special Mode Feature (WIP)
+CONFIG_PDC202XX_MASTER
   For PDC20246 and PDC20262 Ultra DMA chipsets. This is reserved for
   possible Hardware RAID 0,1 for the FastTrak Series.
 
@@ -832,8 +870,7 @@
   (while running a "cat") provided you enabled "proc" support.
   Please read the comments at the top of drivers/block/via82cxxx.c
 
-  If you say Y here, you also need to say Y to "Use DMA by default
-  when available", above.
+  If you say Y here, then say Y to "Use DMA by default when available" as well.
 
   If unsure, say N.
 
@@ -908,16 +945,6 @@
   See the files Documentation/ide.txt and drivers/block/umc8672.c for
   more info.
 
-PS/2 ESDI hard disk support
-CONFIG_BLK_DEV_PS2
-  Say Y here if you have a PS/2 machine with a MCA bus and an ESDI
-  hard disk.
-  
-  If you want to compile the driver as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you want),
-  say M here and read Documentation/modules.txt. The module will be
-  called ps2esdi.o.
-
 Amiga builtin Gayle IDE interface support
 CONFIG_BLK_DEV_GAYLE
   This is the IDE driver for the builtin IDE interface on some Amiga
@@ -968,7 +995,14 @@
 
 Use DMA by default
 CONFIG_IDEDMA_PMAC_AUTO
-  No help for CONFIG_IDEDMA_PMAC_AUTO
+  Prior to kernel version 2.1.112, Linux used to automatically use
+  DMA for IDE drives and chipsets which support it. Due to concerns
+  about a couple of cases where buggy hardware may have caused damage,
+  the default is now to NOT use DMA automatically. To revert to the
+  previous behaviour, say Y to this question.
+
+  If you suspect your hardware is at all flakey, say N here.
+  Do NOT email the IDE kernel people regarding this issue!
 
 Macintosh Quadra/Powerbook IDE interface support
 CONFIG_BLK_DEV_MAC_IDE
@@ -981,9 +1015,16 @@
   devices (hard disks, CD-ROM drives, etc.) that are connected to the
   builtin IDE interface.
 
+IDE card support
+CONFIG_BLK_DEV_IDE_CARDS
+  On Acorn systems, say Y here if you wish to use an IDE interface
+  expansion card. If you do not or are unsure, say N to this.
+
 ICS IDE interface support
 CONFIG_BLK_DEV_IDE_ICSIDE
-  No help for CONFIG_BLK_DEV_IDE_ICSIDE
+  On Acorn systems, say Y here if you wish to use the ICS IDE
+  interface card.  This is not required for ICS partition support.
+  If you are unsure, say N to this.
 
 ICS DMA support
 CONFIG_BLK_DEV_IDEDMA_ICS
@@ -991,7 +1032,14 @@
 
 Use ICS DMA by default
 CONFIG_IDEDMA_ICS_AUTO
-  No help for CONFIG_IDEDMA_ICS_AUTO
+  Prior to kernel version 2.1.112, Linux used to automatically use
+  DMA for IDE drives and chipsets which support it. Due to concerns
+  about a couple of cases where buggy hardware may have caused damage,
+  the default is now to NOT use DMA automatically. To revert to the
+  previous behaviour, say Y to this question.
+
+  If you suspect your hardware is at all flakey, say N here.
+  Do NOT email the IDE kernel people regarding this issue!
 
 RapIDE interface support
 CONFIG_BLK_DEV_IDE_RAPIDE
@@ -1009,6 +1057,16 @@
 
   It's pretty unlikely that you have one of these: say N.
 
+PS/2 ESDI hard disk support
+CONFIG_BLK_DEV_PS2
+  Say Y here if you have a PS/2 machine with a MCA bus and an ESDI
+  hard disk.
+
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. The module will be
+  called ps2esdi.o.
+
 Mylex DAC960/DAC1100 PCI RAID Controller support
 CONFIG_BLK_DEV_DAC960
   This driver adds support for the Mylex DAC960, AcceleRAID, and
@@ -1392,20 +1450,47 @@
   This is a machine with a R4400 100 MHz CPU. To compile a Linux
   kernel that runs on these, say Y here. For details about Linux
   on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
-  http://lena.fnet.fr/ .
+  http://oss.sgi.com/mips.
 
 Support for Acer PICA 1 chipset
 CONFIG_ACER_PICA_61
   This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
   kernel that runs on these, say Y here. For details about Linux on
   the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
-  http://lena.fnet.fr/ .
+  http://oss.sgi.com/mips.
 
 Support for Algorithmics P4032 (EXPERIMENTAL)
 CONFIG_ALGOR_P4032
   This is an evaluation board of the British company Algorithmics. The
   board uses the R4300 and a R5230 CPUs. For more information about
-  this board see http://www.algor.co.uk .
+  this board see http://www.algor.co.uk.
+
+Support for BAGET MIPS series
+CONFIG_BAGET_MIPS
+  This enables support for the Baget, a Russian embedded system.  For 
+  more details about the Baget see the Linux/MIPS FAQ on 
+  http://oss.sgi.com/mips.
+
+Support for DECstations
+CONFIG_DECSTATION
+  This enables support for DEC's MIPS based workstations.  For details
+  see the Linux/MIPS FAQ on http://oss.sgi.com/mips. the 
+  DECstation porting pages on http://decstation.unix-ag.org.
+
+  If you have one of the following DECstation Models you definitely
+  want to choose R4xx0 for the CPU Type:
+
+	DECstation 5000/50
+	DECstation 5000/150
+	DECstation 5000/260
+	DECsystem 5900/260
+
+  otherwise choose R3000.
+
+Support for NEC DDB Vrc-5074
+CONFIG_DDB5074
+  This enables support for the VR5000-based NEC DDB Vrc-5074 evaluation
+  board.
 
 IDE card support
 CONFIG_BLK_DEV_IDE_CARDS
@@ -1423,34 +1508,67 @@
   This allows Linux on Acorn systems to determine its partitions in
   the 'non-ADFS' partition area of the hard disk - usually located
   after the ADFS partition.  You are probably using this system, so
-  you should say Y here.
+  you should say Y it.
 
 Support for Mips Magnum 4000
 CONFIG_MIPS_MAGNUM_4000
   This is a machine with a R4000 100 MHz CPU. To compile a Linux
   kernel that runs on these, say Y here. For details about Linux on
   the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
-  http://lena.fnet.fr/ .
+  http://oss.sgi.com/mips.
 
 Support for Olivetti M700
 CONFIG_OLIVETTI_M700
   This is a machine with a R4000 100 MHz CPU. To compile a Linux
   kernel that runs on these, say Y here. For details about Linux on
   the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
-  http://lena.fnet.fr/ .
+  http://oss.sgi.com/mips.
+
+Support for SGI IP22
+CONFIG_SGI_IP22
+  This are the SGI Indy, Challenge S and Indigo2, as well as certain OEM
+  variants like the Tandem CMN B006S.  To compile a Linux kernel that
+  runs on these, say Y here.
+
+Support for SGI IP27
+  This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
+  workstations.  To compile a Linux kernel that runs on these, say Y
+  here.
+
+IP27 N-Mode
+CONFIG_SGI_SN0_N_MODE
+  The nodes of Origin 200, Origin 2000 and Onyx 2 systems can be
+  configured in either N-Modes which allows for more nodes or M-Mode
+  which allows for more more memory.  Your system is most probly
+  running in M-Mode, so you should say N here.
+
+MIPS JAZZ onboard SONIC Ethernet support
+CONFIG_MIPS_JAZZ_SONIC
+  This is the driver for the onboard card of of MIPS Magnum 4000,
+  Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
+
+MIPS JAZZ FAS216 SCSI support
+CONFIG_JAZZ_ESP
+  This is the driver for the onboard SCSI hostadapter of MIPS Magnum 4000,
+  Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
 
 CPU type
 CONFIG_CPU_R3000
-  Give the type of your machine's MIPS CPU. For this question, it
-  suffices to give a unique prefix of the option you want to choose.
-  In case of doubt select the R3000 CPU. The kernel will then run on
-  other MIPS machines but with slightly reduced performance.
-
-Compile the kernel into the ECOFF object format
-CONFIG_ECOFF_KERNEL
-  Some machines require a kernel in the ECOFF format. You will have to
-  say Y here for example if you want to use a Mips Magnum 3000 or a
-  DECstation.
+  Please make shure to pick the right CPU type. Linux/MIPS is not
+  designed to be generic, i.e. Kernels compiled for R3000 CPUs will
+  *not* work on R4000 Machines and vice versa.
+  However, since most the supported Machines have an R4000 (or similar)
+  CPU R4xx0 might be a safe bet.
+  If the resulting Kernel does not work try to recompile with R3000.
+
+Support for large 64-bit configurations
+CONFIG_MIPS_INSANE_LARGE
+  MIPS R10000 does support a 44 bit / 16TB address space as opposed to
+  previous 64-bit processors which only did only support 40 bit / 1TB.  If
+  you need processes of more than 1TB virtual address space activate this.
+  Activating CONFIG_MIPS_INSANE_LARGE results in additional memory usage,
+  so only activate this if you really need.  Very few people will need
+  this.
 
 Generate little endian code
 CONFIG_CPU_LITTLE_ENDIAN
@@ -1539,7 +1657,7 @@
   Chances are that you should say Y here if you compile a kernel which
   will run as a router and N for regular hosts. If unsure, say N.
  
-SIN flood protection
+SYN flood protection
 CONFIG_SYN_COOKIES
   Normal TCP/IP networking is open to an attack known as "SYN
   flooding". This denial-of-service attack prevents legitimate remote
@@ -1712,6 +1830,10 @@
   servicing. Say Y here to enable the serial driver to take advantage
   of those special I/O ports.
 
+SGI PROM Console Support
+CONFIG_SGI_PROM_CONSOLE
+  Enable this if you want to use the PROMs for console I/O.
+
 SGI Zilog85C30 serial support
 CONFIG_SGI_SERIAL
   If you want to use your SGI's built-in serial ports under Linux,
@@ -1724,6 +1846,25 @@
   /dev/graphics and /dev/gfx drivers into the kernel for supporting
   virtualized access to your graphics hardware.
 
+SGI Newport Console support
+CONFIG_SGI_NEWPORT_CONSOLE
+  Enable this if you want the console on the Newport aka XL graphics
+  card of your Indy.  Most people say Y here.
+
+SGI DS1286 RTC support
+CONFIG_SGI_DS1286
+  If you say Y here and create a character special file /dev/rtc with
+  major number 10 and minor number 135 using mknod ("man mknod"), you
+  will get access to the real time clock built into your computer.
+  Every SGI has such a clock built in.  It reports status information 
+  via the file /proc/rtc and its behaviour is set by various ioctls on 
+  /dev/rtc.
+
+SGI Vino Video For Linux (EXPERIMENTAL)
+CONFIG_SGI_VIDEO_VINO
+  Support for the SGI Vino Video hardware which is part of the Newport
+  aka XL graphics card.  Most people will say N here.
+
 Support the Bell Technologies HUB6 card
 CONFIG_HUB6
   Say Y here to enable support in the dumb serial driver to support
@@ -1899,7 +2040,7 @@
   Say Y here if you would like Linux to configure your Plug and Play
   devices. You should then also say Y to "ISA Plug and Play support",
   below. Alternatively, you can configure your PnP devices using the
-  user space utilities contained in the ISAPNP tools package.
+  user space utilities contained in the isapnptools package.
   
   This support is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -2457,6 +2598,52 @@
   you select "Advanced lowlevel driver options", you should check 8
   bpp packed pixel, 16 bpp packed pixel, 24 bpp packed pixel and 32
   bpp packed pixel. You can also use font widths different from 8.
+  
+  If you need support for G400 secondary head, you must first enable
+  I2C support and I2C bit-banging support in character devices section,
+  and then Matrox I2C support and G400 secondary head support here
+  in framebuffer section.
+
+Matrox I2C support
+CONFIG_FB_MATROX_I2C
+  This drivers creates I2C buses which are needed for accessing
+  DDC (I2C) bus present on all Matroxes, I2C bus which interconnects
+  Matrox optional devices, like MGA-TVO on G200 and G400, and
+  secondary head DDC bus, present on G400 only.
+  
+  You can say Y or M here if you want to experiment with monitor 
+  detection code. You must say Y or M here if you want to use either
+  second head of G400 or MGA-TVO on G200 or G400.
+  
+  If you compile it as module, it will create module named i2c-matroxfb.o.
+  
+Matrox G400 second head support
+CONFIG_FB_MATROX_MAVEN
+  Say Y or M here if you want to use secondary head on G400 or MGA-TVO
+  add-on on G200. Secondary head is not compatible with accelerated
+  XFree 3.3.x SVGA servers - secondary head output is blanked while you
+  are in X. With XFree 3.9.17 preview you can use both heads if you use
+  SVGA over fbdev or fbdev driver on first head and fbdev driver on
+  second head.
+  
+  If you compile it as module, two modules are created, matroxfb_crtc2.o
+  and matroxfb_maven.o. Matroxfb_maven is needed for both G200 and G400,
+  matroxfb_crtc2 is needed only by G400. You must also load i2c-matroxfb
+  to get it to run.
+  
+  Driver starts in monitor mode and you must use matroxset tool (available
+  at ftp://platan.vc.cvut.cz/pub/linux/matrox-latest) to switch it to PAL
+  or NTSC or to swap primary and secondary head outputs. Secondary head
+  driver also always start in 640x480 resolution, you must use fbset to
+  change it.
+  
+  Also do not forget that second head supports only 16 and 32 bpp packed
+  pixels, so it is good idea to compile them into kernel too. You can
+  use only some font widths, as driver uses generic painting procedures
+  (secondary head does not use acceleration engine).
+  
+  There is no need for enabling 'Matrox multihead support' if you have
+  only one Matrox card in the box.
 
 Matrox unified driver multihead support
 CONFIG_FB_MATROX_MULTIHEAD
@@ -4143,6 +4330,82 @@
   speed of the driver, and the size of your syslog files! When
   inactive, they will have only a modest impact on performance.
 
+FORE Systems 200E-series
+CONFIG_ATM_FORE200E
+  This is a driver for the FORE Systems 200E-series ATM adapter
+  cards. It simultaneously supports PCA-200E and SBA-200E models
+  on PCI and SBUS hosts. Say Y (or M to compile as a module
+  named fore_200e.o) here if you have one of these ATM adapters.
+ 
+  See the file Documentation/networking/fore200e.txt for further
+  details.
+ 
+Enable PCA-200E card support on PCI-based hosts
+CONFIG_ATM_FORE200E_PCA
+  Enable this if you want your PCA-200E cards to be probed.
+ 
+Use default PCA-200E firmware
+CONFIG_ATM_FORE200E_PCA_DEFAULT_FW
+  Use the default PCA-200E firmware data shipped with the driver.
+ 
+  Normal users do not have to deal with the firmware stuff, so
+  this feature is normally enabled.
+ 
+Pathname of user-supplied binary firmware
+CONFIG_ATM_FORE200E_PCA_FW
+  This defines the pathname of an alternative PCA-200E binary
+  firmware image supplied by the user. This pathname may be
+  absolute or relative to the drivers/atm directory.
+ 
+  The driver comes with an adequate firmware image, so normal users
+  do not have to supply an alternative one. They just enable the use
+  of the default firmware instead.
+ 
+Enable SBA-200E card support on SBUS-based hosts
+CONFIG_ATM_FORE200E_SBA
+  Enable this if you want your SBA-200E cards to be probed.
+ 
+Use default SBA-200E firmware
+CONFIG_ATM_FORE200E_SBA_DEFAULT_FW
+  Use the default SBA-200E firmware data shipped with the driver.
+ 
+  Normal users do not have to deal with the firmware stuff, so
+  this feature is normally enabled.
+ 
+Pathname of user-supplied binary firmware
+CONFIG_ATM_FORE200E_SBA_FW
+  This defines the pathname of an alternative SBA-200E binary
+  firmware image supplied by the user. This pathname may be
+  absolute or relative to the drivers/atm directory.
+ 
+  The driver comes with an adequate firmware image, so normal users
+  do not have to supply an alternative one. They just enable the use
+  of the default firmware instead.
+ 
+Maximum number of tx retries
+CONFIG_ATM_FORE200E_TX_RETRY
+  Specifies the number of times the driver attempts to transmit
+  a message before giving up, if the transmit queue of the ATM card
+  is transiently saturated.
+ 
+  Saturation of the transmit queue may occur only under extreme
+  conditions, e.g. when a fast host continuously submits very small
+  frames (<64 bytes) or raw AAL0 cells (48 bytes) to the ATM adapter.
+ 
+  Note that under common conditions, it is unlikely that you encounter
+  a saturation of the transmit queue, so the retry mechanism never
+  comes into play.
+
+Debugging level (0-3)
+CONFIG_ATM_FORE200E_DEBUG
+  Specifies the level of debugging messages issued by the driver.
+  The verbosity of the driver increases with the value of this
+  parameter.
+ 
+  When active, these messages can have a significant impact on
+  the performances of the driver, and the size of your syslog files!
+  Keep the debugging level to 0 during normal operations.
+
 SCSI support?
 CONFIG_SCSI
   If you want to use a SCSI hard disk, SCSI tape drive, SCSI CDROM or
@@ -7475,6 +7738,11 @@
   module, say M here and read Documentation/modules.txt as well as
   Documentation/networking/net-modules.txt.
 
+EtherExpress PRO/100 support
+CONFIG_EEPRO100_PM (EXPERIMENTAL)
+  If you want to play around with power management code
+  that has reported to lock up some machines, say Y here.
+
 ICL EtherTeam 16i/32 support (EXPERIMENTAL)
 CONFIG_ETH16I
   If you have a network (Ethernet) card of this type, say Y and read
@@ -11679,6 +11947,12 @@
   Say Y here if you are compiling the kernel on a different
   architecture than the one it is intended to run on.
 
+Kernel support for Linux/MIPS 32-bit binary compatibility
+CONFIG_MIPS32_COMPAT
+  Select this option this option if you want Linux/MIPS 32-bit binary
+  compatibility.  Since all software available available for Linux/MIPS
+  is currently 32-bit you should say Y here.
+
 Build fp exception handler module
 CONFIG_MIPS_FPE_MODULE
   Build the floating point exception handler module. This option is
@@ -13938,7 +14212,7 @@
 # LocalWords:  PMAX MILO Alphas Multia Tseng linuxelf endian mipsel mips drv HT
 # LocalWords:  kerneld callouts AdvanSys advansys Admin WDT DataStor EP verden
 # LocalWords:  wdt hdb hdc bugfix SiS vlb Acculogic CSA DTC dtc Holtek ht QDI
-# LocalWords:  QD qd UMC umc ALI ali lena fnet fr azstarnet cdr fb MDA ps esdi
+# LocalWords:  QD qd UMC umc ALI ali oss sgi com azstarnet cdr fb MDA ps esdi
 # LocalWords:  Avanti XL AlphaStations Jensen DECpc AXPpci UDB Cabriolet MCA RC
 # LocalWords:  AlphaPC mca AOUT OUTput PPro sipx gwdg lo nwe FourPort Boca unm
 # LocalWords:  Keepalive linefill RELCOM keepalive analogue CDR conf CDI INIT
diff -u --recursive --new-file v2.3.47/linux/Documentation/IRQ-affinity.txt linux/Documentation/IRQ-affinity.txt
--- v2.3.47/linux/Documentation/IRQ-affinity.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/IRQ-affinity.txt	Thu Feb 24 22:41:16 2000
@@ -0,0 +1,37 @@
+
+SMP IRQ affinity, started by Ingo Molnar <mingo@redhat.com>
+
+
+/proc/irq/IRQ#/smp_affinity specifies which target CPUs are permitted
+for a given IRQ source. It's a bitmask of allowed CPUs. It's not allowed
+to turn off all CPUs, and if an IRQ controller does not support IRQ
+affinity then the value will not change from the default 0xffffffff.
+
+Here is an example of restricting IRQ44 (eth1) to CPU0-3 then restricting
+the IRQ to CPU4-8 (this is an 8-CPU SMP box):
+
+[root@moon 44]# cat smp_affinity
+ffffffff
+[root@moon 44]# echo 0f > smp_affinity
+[root@moon 44]# cat smp_affinity
+0000000f
+[root@moon 44]# ping -f h
+PING hell (195.4.7.3): 56 data bytes
+...
+--- hell ping statistics ---
+6029 packets transmitted, 6027 packets received, 0% packet loss
+round-trip min/avg/max = 0.1/0.1/0.4 ms
+[root@moon 44]# cat /proc/interrupts | grep 44:
+ 44:          0       1785       1785       1783       1783          1
+1          0   IO-APIC-level  eth1
+[root@moon 44]# echo f0 > smp_affinity
+[root@moon 44]# ping -f h
+PING hell (195.4.7.3): 56 data bytes
+..
+--- hell ping statistics ---
+2779 packets transmitted, 2777 packets received, 0% packet loss
+round-trip min/avg/max = 0.1/0.5/585.4 ms
+[root@moon 44]# cat /proc/interrupts | grep 44:
+ 44:       1068       1785       1785       1784       1784       1069       1070       1069   IO-APIC-level  eth1
+[root@moon 44]#
+
diff -u --recursive --new-file v2.3.47/linux/Documentation/fb/matroxfb.txt linux/Documentation/fb/matroxfb.txt
--- v2.3.47/linux/Documentation/fb/matroxfb.txt	Thu Apr 29 11:53:41 1999
+++ linux/Documentation/fb/matroxfb.txt	Mon Feb 21 11:08:22 2000
@@ -105,7 +105,7 @@
 Configuration
 =============
 
-You can pass kernel command line options to vesafb with
+You can pass kernel command line options to matroxfb with
 `video=matrox:option1,option2:value2,option3' (multiple options should be 
 separated by comma, values are separated from options by `:'). 
 Accepted options:
@@ -276,16 +276,16 @@
  + color keying is not supported
  + feature connector of Mystique and Gx00 is set to VGA mode (it is disabled
    by BIOS)
- + DCC (monitor detection) protocol is not implemented
+ + DDC (monitor detection) is supported through dualhead driver
  + some check for input values are not so strict how it should be (you can
    specify vslen=4000 and so on).
  + maybe more...
 And following features:
  + 4bpp is available only on Millennium I and Millennium II. It is hardware
    limitation.
- + current fbset is not able to set 15bpp videomode: you must specify
-   depth==16 and green.length==5. fbset does not allow you to set 
-   green.length.
+ + selection between 1:5:5:5 and 5:6:5 16bpp videomode is done by -rgba 
+   option of fbset: "fbset -depth 16 -rgba 5,5,5" selects 1:5:5:5, anything
+   else selects 5:6:5 mode.
  + text mode uses 6 bit VGA palette instead of 8 bit (one of 262144 colors
    instead of one of 16M colors). It is due to hardware limitation of 
    Millennium I/II and SVGALib compatibility.
@@ -329,6 +329,27 @@
         8x16
 	Millennium I  G200
 TEXT     3.29         1.50
+
+
+Dualhead G400
+=============
+Driver supports dualhead G400 with some limitations:
+ + secondary head shares videomemory with primary head. It is not problem
+   if you have 32MB of videoram, but if you have only 16MB, you may have
+   to think twice before choosing videomode (for example twice 1880x1440x32bpp
+   is not possible).
+ + due to hardware limitation, secondary head can use only 16 and 32bpp
+   videomodes.
+ + secondary head is not accelerated. There were bad problems with accelerated
+   XFree when secondary head used to use acceleration.
+ + secondary head always powerups in 640x480@60-32 videomode. You have to use
+   fbset to change this mode.
+ + secondary head always powerups in monitor mode. You have to use matroxset
+   to change it to TV mode. Also, you must select at least 525 lines for
+   NTSC output and 625 lines for PAL output.
+ + kernel is not fully multihead ready. So some things are impossible to do.
+ + if you compiled it as module, you must insert i2c-matroxfb, matroxfb_maven
+   and matroxfb_crtc2 into kernel.
 
 	
 * Yes, it is slower than Millennium I.
diff -u --recursive --new-file v2.3.47/linux/Documentation/floppy.txt linux/Documentation/floppy.txt
--- v2.3.47/linux/Documentation/floppy.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/floppy.txt	Mon Feb 21 11:04:30 2000
@@ -0,0 +1,222 @@
+This file describes the floppy driver.
+
+FAQ list:
+=========
+
+ A FAQ list may be found in the fdutils package (see below), and also
+at http://fdutils.linux.lu/FAQ.html
+
+
+LILO configuration options (Thinkpad users, read this)
+======================================================
+
+ The floppy driver is configured using the 'floppy=' option in
+lilo. This option can be typed at the boot prompt, or entered in the
+lilo configuration file.
+ Example: If your kernel is called linux-2.2.13, type the following line
+at the lilo boot prompt (if you have a thinkpad):
+ linux-2.2.13 floppy=thinkpad
+You may also enter the following line in /etc/lilo.conf, in the description
+of linux-2.2.13:
+ append = "floppy=thinkpad"
+
+ Several floppy related options may be given, example:
+ linux-2.2.13 floppy=daring floppy=two_fdc
+ append = "floppy=daring floppy=two_fdc"
+
+ If you give options both in the lilo config file and on the boot
+prompt, the option strings of both places are concatenated, the boot
+prompt options coming last. That's why there are also options to
+restore the default behavior.
+
+ If you use the floppy driver as a module, use the following syntax:
+ insmod floppy <options>
+
+Example:
+ insmod floppy daring two_fdc
+
+ Some versions of insmod are buggy in one way or another. If you have
+any problems (options not being passed correctly, segfaults during
+insmod), first check whether there is a more recent version.
+
+ The floppy related options include:
+
+ floppy=asus_pci
+	Sets the bit mask to allow only units 0 and 1. (default)
+
+ floppy=daring
+	Tells the floppy driver that you have a well behaved floppy controller.
+	This allows more efficient and smoother operation, but may fail on
+	certain controllers. This may speed up certain operations.
+
+ floppy=0,daring
+	Tells the floppy driver that your floppy controller should be used
+	with caution.
+
+ floppy=one_fdc
+	Tells the floppy driver that you have only one floppy controller.
+	(default)
+
+ floppy=two_fdc
+ floppy=<address>,two_fdc
+	Tells the floppy driver that you have two floppy controllers.
+	The second floppy controller is assumed to be at <address>.
+	This option is not needed if the second controller is at address
+	0x370, and if you use the 'cmos' option.
+
+ floppy=thinkpad
+	Tells the floppy driver that you have a Thinkpad. Thinkpads use an
+	inverted convention for the disk change line.
+
+ floppy=0,thinkpad
+	Tells the floppy driver that you don't have a Thinkpad.
+
+ floppy=omnibook
+ floppy=nodma
+	Tells the floppy driver not to use Dma for data transfers.
+	This is needed on HP Omnibooks, which don't have a workable
+	DMA channel for the floppy driver. This option is also useful
+	if you frequently get "Unable to allocate DMA memory" messages.
+	Indeed, dma memory needs to be continuous in physical memory,
+	and is thus harder to find, whereas non-dma buffers may be
+	allocated in virtual memory. However, I advise against this if
+	you have an FDC without a FIFO (8272A or 82072). 82072A and
+	later are OK. You also need at least a 486 to use nodma.
+	If you use nodma mode, I suggest you also set the FIFO
+	threshold to 10 or lower, in order to limit the number of data
+	transfer interrupts.
+
+	If you have a FIFO-able FDC, the floppy driver automatically
+	falls back on non DMA mode if no DMA-able memory can be found.
+	If you want to avoid this, explicitely ask for 'yesdma'.
+
+ floppy=yesdma
+	Tells the floppy driver that a workable DMA channel is available.
+	(default)
+
+ floppy=nofifo
+	Disables the FIFO entirely. This is needed if you get "Bus
+	master arbitration error" messages from your Ethernet card (or
+	from other devices) while accessing the floppy.
+
+ floppy=fifo
+	Enables the FIFO. (default)
+
+ floppy=<threshold>,fifo_depth
+	Sets the FIFO threshold. This is mostly relevant in DMA
+	mode. If this is higher, the floppy driver tolerates more
+	interrupt latency, but it triggers more interrupts (i.e. it
+	imposes more load on the rest of the system). If this is
+	lower, the interrupt latency should be lower too (faster
+	processor). The benefit of a lower threshold is less
+	interrupts.
+	To tune the fifo threshold, switch on over/underrun messages
+	using 'floppycontrol --messages'. Then access a floppy
+	disk. If you get a huge amount of "Over/Underrun - retrying"
+	messages, then the fifo threshold is too low. Try with a
+	higher value, until you only get an occasional Over/Underrun.
+	It is a good idea to compile the floppy driver as a module
+	when doing this tuning. Indeed, it allows to try different
+	fifo values without rebooting the machine for each test. Note
+	that you need to do 'floppycontrol --messages' every time you
+	re-insert the module.
+	Usually, tuning the fifo threshold should not be needed, as
+	the default (0xa) is reasonable.
+
+ floppy=<drive>,<type>,cmos
+	Sets the CMOS type of <drive> to <type>. This is mandatory if
+	you have more than two floppy drives (only two can be
+	described in the physical CMOS), or if your BIOS uses
+	non-standard CMOS types. The CMOS types are:
+		0 - Use the value of the physical CMOS
+		1 - 5 1/4 DD
+		2 - 5 1/4 HD
+		3 - 3 1/2 DD
+		4 - 3 1/2 HD
+		5 - 3 1/2 ED
+		6 - 3 1/2 ED
+	       16 - unknown or not installed
+	(Note: there are two valid types for ED drives. This is because 5 was
+	initially chosen to represent floppy *tapes*, and 6 for ED drives.
+	AMI ignored this, and used 5 for ED drives. That's why the floppy
+	driver handles both.)
+
+ floppy=unexpected_interrupts
+	Print a warning message when an unexpected interrupt is received.
+	(default)
+
+ floppy=no_unexpected_interrupts
+ floppy=L40SX
+	Don't print a message when an unexpected interrupt is received. This
+	is needed on IBM L40SX laptops in certain video modes. (There seems
+	to be an interaction between video and floppy. The unexpected
+	interrupts affect only performance, and can be safely ignored.)
+
+ floppy=broken_dcl
+	Don't use the disk change line, but assume that the disk was
+	changed whenever the device node is reopened. Needed on some
+	boxes where the disk change line is broken or unsupported.
+	This should be regarded as a stopgap measure, indeed it makes
+	floppy operation less efficient due to unneeded cache
+	flushings, and slightly more unreliable. Please verify your
+	cable, connection and jumper settings if you have any DCL
+	problems. However, some older drives, and also some laptops
+	are known not to have a DCL.
+
+ floppy=debug
+	Print debugging messages.
+
+ floppy=messages
+	Print informational messages for some operations (disk change
+	notifications, warnings about over and underruns, and about
+	autodetection).
+
+ floppy=silent_dcl_clear
+	Uses a less noisy way to clear the disk change line (which
+	doesn't involve seeks). Implied by 'daring' option.
+
+ floppy=<nr>,irq
+	Sets the floppy IRQ to <nr> instead of 6.
+
+ floppy=<nr>,dma
+	Sets the floppy DMA channel to <nr> instead of 2.
+
+ floppy=slow
+	Use PS/2 stepping rate:
+	 " PS/2 floppies have much slower step rates than regular floppies.
+	   It's been recommended that take about 1/4 of the default speed
+	   in some more extreme cases."
+
+
+
+Supporting utilities and additional documentation:
+==================================================
+
+ Additional parameters of the floppy driver can be configured at
+runtime. Utilities which do this can be found in the fdutils package.
+This package also contains a new version of mtools which allows to
+access high capacity disks (up to 1992K on a high density 3 1/2 disk!).
+It also contains additional documentation about the floppy driver.
+
+The latest version can be found at fdutils homepage:
+ http://fdutils.linux.lu
+
+The fdutils-5.3 release can be found at:
+ http://fdutils.linux.lu/fdutils-5.3.src.tar.gz
+ http://www.tux.org/pub/knaff/fdutils/fdutils-5.3.src.tar.gz
+ ftp://tsx-11.mit.edu/pub/linux/sources/sbin/fdutils-5.3.src.tar.gz
+ ftp://metalab.unc.edu/pub/Linux/utils/disk-management/fdutils-5.3.src.tar.gz
+
+Reporting problems about the floppy driver
+==========================================
+
+ If you have a question or a bug report about the floppy driver, mail
+me at Alain.Knaff@poboxes.com . If you post to Usenet, preferably use
+comp.os.linux.hardware. As the volume in these groups is rather high,
+be sure to include the word "floppy" (or "FLOPPY") in the subject
+line.  If the reported problem happens when mounting floppy disks, be
+sure to mention also the type of the filesystem in the subject line.
+
+ Be sure to read the FAQ before mailing/posting any bug reports!
+
+ Alain
diff -u --recursive --new-file v2.3.47/linux/Documentation/ide.txt linux/Documentation/ide.txt
--- v2.3.47/linux/Documentation/ide.txt	Fri Jan 21 18:19:15 2000
+++ linux/Documentation/ide.txt	Sat Feb 26 20:32:12 2000
@@ -38,7 +38,7 @@
 		- interface PIO timing & prefetch parameter support
 	- experimental support for UMC 8672 interfaces
 	- support for secondary interface on the FGI/Holtek HT-6560B VLB i/f
-		- use kernel command line option:   ide0=ht6560
+		- use kernel command line option:   ide0=ht6560b
 	- experimental support for various IDE chipsets
 		- use appropriate kernel command line option from list below
 	- support for drives with a stuck WRERR_STAT bit
diff -u --recursive --new-file v2.3.47/linux/Documentation/ioctl-number.txt linux/Documentation/ioctl-number.txt
--- v2.3.47/linux/Documentation/ioctl-number.txt	Tue Nov 23 22:42:20 1999
+++ linux/Documentation/ioctl-number.txt	Mon Feb 21 11:08:22 2000
@@ -128,7 +128,8 @@
 'm'	all	linux/soundcard.h	conflict!
 'm'	all	linux/synclink.h	conflict!
 'm'	00-1F	net/irda/irmod.h	conflict!
-'n'	all	linux/ncp_fs.h
+'n'	00-7F	linux/ncp_fs.h
+'n'	E0-FF	video/matrox.h          matroxfb
 'p'	00-3F	linux/mc146818rtc.h
 'p'	40-7F	linux/nvram.h
 'p'	80-9F				user-space parport
diff -u --recursive --new-file v2.3.47/linux/Documentation/m68k/README.buddha linux/Documentation/m68k/README.buddha
--- v2.3.47/linux/Documentation/m68k/README.buddha	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/m68k/README.buddha	Mon Feb 21 11:04:30 2000
@@ -0,0 +1,210 @@
+
+The Amiga Buddha and Catweasel IDE Driver (part of ide.c) was written by
+Geert Uytterhoeven based on the following specifications:
+
+------------------------------------------------------------------------
+
+Register map of the Buddha IDE controller and the
+Buddha-part of the Catweasel Zorro-II version
+
+The Autoconfiguration has been implemented just as Commodore
+described  in  their  manuals, no tricks have been used (for
+example leaving some address lines out of the equations...).
+If you want to configure the board yourself (for example let
+a  Linux  kernel  configure the card), look at the Commodore
+Docs.  Reading the nibbles should give this information:
+
+Vendor number: 4626 ($1212)
+product number: 0 (42 for Catweasel Z-II)
+Serial number: 0
+Rom-vector: $1000
+
+The  card  should be a Z-II board, size 64K, not for freemem
+list, Rom-Vektor is valid, no second Autoconfig-board on the
+same card, no space preferrence, supports "Shutup_forever".
+
+Setting  the  base address should be done in two steps, just
+as  the Amiga Kickstart does:  The lower nibble of the 8-Bit
+address is written to $4a, then the whole Byte is written to
+$48, while it doesn't matter how often you're writing to $4a
+as  long as $48 is not touched.  After $48 has been written,
+the  whole card disappears from $e8 and is mapped to the new
+addrress just written.  Make shure $4a is written befor $48,
+otherwise your chance is only 1:16 to find the board :-).
+
+The local memory-map is even active when mapped to $e8:
+
+$0-$7e		Autokonfig-space, see Z-II docs.
+
+$80-$7fd	reserved
+
+$7fe		Speed-select Register: Read & Write
+		(description see further down)
+
+$800-$8ff	IDE-Select 0 (Port 0, Register set 0)
+
+$900-$9ff	IDE-Select 1 (Port 0, Register set 1)
+
+$a00-$aff	IDE-Select 2 (Port 1, Register set 0)
+
+$b00-$bff	IDE-Select 3 (Port 1, Register set 1)
+
+$c00-$cff	IDE-Select 4 (Port 2, Register set 0,
+                          Catweasel only!)
+
+$d00-$dff	IDE-Select 5 (Port 3, Register set 1,
+			      Catweasel only!)
+
+$e00-$eff	local expansion port, on Catweasel Z-II the 
+		Catweasel registers are also mapped here.
+		Never touch, use multidisk.device!
+		
+$f00		read only, Byte-access: Bit 7 shows the 
+		level of the IRQ-line of IDE port 0. 
+
+$f01-$f3f	mirror of $f00
+
+$f40		read only, Byte-access: Bit 7 shows the 
+		level of the IRQ-line of IDE port 1. 
+
+$f41-$f7f	mirror of $f40
+
+$f80		read only, Byte-access: Bit 7 shows the 
+		level of the IRQ-line of IDE port 2. 
+		(Catweasel only!)
+
+$f81-$fbf	mirror of $f80
+
+$fc0		write-only: Writing any value to this
+		register enables IRQs to be passed from the 
+		IDE ports to the Zorro bus. This mechanism 
+		has been implemented to be compatible with 
+		harddisks that are either defective or have
+		a buggy firmware and pull the IRQ line up 
+		while starting up. If interrupts would 
+		always be passed to the bus, the computer 
+		might not start up. Once enabled, this flag 
+		can not be disabled again. The level of the 
+		flag can not be determined by software 
+		(what for? Write to me if it's necessary!).
+
+$fc1-$fff	mirror of $fc0
+
+$1000-$ffff	Buddha-Rom with offset $1000 in the rom
+		chip. The addresses $0 to $fff of the rom 
+		chip cannot be read. Rom is Byte-wide and
+		mapped to even addresses.
+
+The  IDE ports issue an INT2.  You can read the level of the
+IRQ-lines  of  the  IDE-ports by reading from the three (two
+for  Buddha-only)  registers  $f00, $f40 and $f80.  This way
+more  than one I/O request can be handled and you can easily
+determine  what  driver  has  to serve the INT2.  Buddha and
+Catweasel  expansion  boards  can issue an INT6.  A seperate
+memory  map  is available for the I/O module and the sysop's
+I/O module.
+
+The IDE ports are fed by the address lines A2 to A4, just as
+the  Amiga  1200  and  Amiga  4000  IDE ports are.  This way
+existing  drivers  can be easily ported to Buddha.  A move.l
+polls  two  words  out of the same address of IDE port since
+every  word  is  mirrored  once.  movem is not possible, but
+it's  not  necessary  either,  because  you can only speedup
+68000  systems  with  this  technique.   A 68020 system with
+fastmem is faster with move.l.
+
+If you're using the mirrored registers of the IDE-ports with
+A6=1,  the Buddha doesn't care about the speed that you have
+selected  in  the  speed  register (see further down).  With
+A6=1  (for example $840 for port 0, register set 0), a 780ns
+access  is being made.  These registers should be used for a
+command   access   to  the  harddisk/CD-Rom,  since  command
+accesses  are Byte-wide and have to be made slower according
+to the ATA-X3T9 manual.
+
+Now  for the speed-register:  The register is byte-wide, and
+only  the  upper  three  bits are used (Bits 7 to 5).  Bit 4
+must  always  be set to 1 to be compatible with later Buddha
+versions  (if  I'll  ever  update this one).  I presume that
+I'll  never use the lower four bits, but they have to be set
+to 1 by definition.
+  The  values in this table have to be shifted 5 bits to the
+left and or'd with $1f (this sets the lower 5 bits).
+
+All  the timings have in common:  Select and IOR/IOW rise at
+the  same  time.   IOR  and  IOW have a propagation delay of
+about  30ns  to  the clocks on the Zorro bus, that's why the
+values  are no multiple of 71.  One clock-cycle is 71ns long
+(exactly 70,5 at 14,18 Mhz on PAL systems).
+
+value 0 (Default after reset)
+
+497ns Select (7 clock cycles) , IOR/IOW after 172ns (2 clock cycles)
+(same timing as the Amiga 1200 does on it's IDE port without
+accelerator card)
+
+value 1
+
+639ns Select (9 clock cycles), IOR/IOW after 243ns (3 clock cycles)
+
+value 2
+
+781ns Select (11 clock cycles), IOR/IOW after 314ns (4 clock cycles)
+
+value 3
+
+355ns Select (5 clock cycles), IOR/IOW after 101ns (1 clock cycle)
+
+value 4
+
+355ns Select (5 clock cycles), IOR/IOW after 172ns (2 clock cycles)
+
+value 5
+
+355ns Select (5 clock cycles), IOR/IOW after 243ns (3 clock cycles)
+
+value 6
+
+1065ns Select (15 clock cycles), IOR/IOW after 314ns (4 clock cycles)
+
+value 7
+
+355ns Select, (5 clock cycles), IOR/IOW after 101ns (1 clock cycle)
+
+When accessing IDE registers with A6=1 (for example $84x),
+the timing will always be mode 0 8-bit compatible, no matter
+what you have selected in the speed register:
+
+781ns select, IOR/IOW after 4 clock cycles (=314ns) aktive. 
+
+All  the  timings with a very short select-signal (the 355ns
+fast  accesses)  depend  on the accelerator card used in the
+system:  Sometimes two more clock cycles are inserted by the
+bus  interface,  making  the  whole access 497ns long.  This
+doesn't  affect  the  reliability  of the controller nor the
+performance  of  the  card,  since  this doesn't happen very
+often.
+
+All  the  timings  are  calculated  and  only  confirmed  by
+measurements  that allowed me to count the clock cycles.  If
+the  system  is clocked by an oscillator other than 28,37516
+Mhz  (for  example  the  NTSC-frequency  28,63636 Mhz), each
+clock  cycle is shortened to a bit less than 70ns (not worth
+mentioning).   You  could think of a small performance boost
+by  overclocking  the  system,  but  you would either need a
+multisync  monitor,  or  a  graphics card, and your internal
+diskdrive would go crazy, that's why you shouldn't tune your
+Amiga this way.
+
+Giving  you  the  possibility  to  write  software  that  is
+compatible  with both the Buddha and the Catweasel Z-II, The
+Buddha  acts  just  like  a  Catweasel  Z-II  with no device
+connected  to  the  third  IDE-port.   The IRQ-register $f80
+always  shows a "no IRQ here" on the Buddha, and accesses to
+the  third  IDE  port  are  going into data's Nirwana on the
+Buddha.
+
+			    Jens Schönfeld february 19th, 1997
+					updated may 27th, 1997
+			     eMail: sysop@nostlgic.tng.oche.de
+
diff -u --recursive --new-file v2.3.47/linux/Documentation/networking/8139too.txt linux/Documentation/networking/8139too.txt
--- v2.3.47/linux/Documentation/networking/8139too.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/networking/8139too.txt	Thu Feb 24 10:11:24 2000
@@ -0,0 +1,194 @@
+
+		"8139too" Fast Ethernet driver for Linux
+	  Improved support for RTL-8139 Fast Ethernet adapters
+
+	 Copyright 2000 Jeff Garzik <jgarzik@mandrakesoft.com>
+
+
+	      Architectures supported (all PCI platforms):
+		    x86, Alpha AXP, PowerPC, Sparc64
+
+
+
+
+Disclaimer
+----------
+
+THIS DRIVER IS A DEVELOPMENT RELEASE FOR A DEVELOPMENT KERNEL.  DO NOT
+USE IN A PRODUCTION ENVIRONMENT.
+
+DO NOT CONTACT DONALD BECKER FOR SUPPORT OF THIS DRIVER, his driver is
+completely different and maintained independently of the 8139too code base.
+
+
+
+Requirements
+------------
+Kernel 2.3.41 or later.
+A Fast Ethernet adapter containing an RTL8139-based chip.
+
+
+
+Introduction
+------------
+
+The "8139too" Fast Ethernet driver for Linux 2.4.0 is a substantial
+modification of the experimental rtl8139 driver from Donald Becker,
+some versions of which appeared in 2.2.x and 2.3.x kernels.  The
+RTL-8139 is a very low-cost Fast Ethernet chip, which makes it very
+popular.
+
+The step from 2.2.x to 2.4.x kernels brings many new features to Linux
+device drivers.  Features for MMIO resources, a standard hot-plug API,
+and other interfaces are now becoming requirements, as drivers move
+off the x86 platform.  With that in mind, I have begun updating the
+RTL-8139 driver to current 2.3.x (2.4) kernel standards and APIs, and
+fixing the problems that users have been encountering.
+
+
+
+Features of 8139too
+-------------------
+[note - this list intended for people familiar with kernel drivers]
+
+** 100% MMIO, for full speed operation.  All users (so far) have
+reported performance increases over their existing RTL drivers.
+
+** Multi-platform support:  x86, Alpha, PPC, ...
+
+** Use proper SMP spinlocking, fixing SMP interrupt bugs, making the
+driver portable to non-x86 SMP platforms in the process.
+
+** Use new PCI driver API for seamless, low-maintenance hot-plug support
+
+** Several bugs fixes from original rtl8139 1.08r (October 5, 1999),
+including the very common "transmit timeout" problem.
+
+* Use new resource allocation API, required for hot-plug support
+* Use new register read/write macros
+* initcall support (module_init/exit)
+* vastly improved debug tracing support
+* code formatting in many places for readability
+* use new init_etherdev() facilities
+
+...and probably some other less important changes which I forgot.
+
+
+
+Installation
+------------
+
+OPTION 1: Build inside kernel tree (into kernel image, or as module)
+
+	(overwrite 8139too driver in kernel tree with different version)
+	1) cp 8139too.c $my_source_tree/drivers/net/8139too.c
+	
+OPTION 2: Build outside kernel tree
+
+	Use the included Makefile.
+
+
+
+Tested Adapters
+---------------
+AOpen ALN-325C
+KTI KF-230TX
+KTI KF-230TX/2
+
+(please add your adapter model to this list)
+
+
+
+Status of Platform Support
+--------------------------
+
+(see errata below for details)
+
+x86:		tested, stable
+Alpha AXP:	tested, stable
+PowerPC:	tested, unstable
+Sparc64:	not tested
+
+
+
+Special Thanks
+--------------
+The following people contributed invaluable testing time, feedback
+and/or patches during the development of this driver.  Thanks to all
+of them.
+
+Donald Becker, Alan Cox, Richard Stallman, Linus Torvalds - inspiration
+
+Alan Cox, Gerard Roudier - insight on posted MMIO writes
+
+Martin Mares - code review
+
+Tigran Aivazian - testing, code review, and a bug fix
+
+Chmouel Boudjnah, Alexander Dietrich, Oleg Drokin,
+James Fidell, Taso Hatzi, Peter K - intrepid test team
+
+And thanks to every supporter free software.
+
+
+
+Known Bugs / Errata / To-Do
+---------------------------
+The following issues are known, and are actively being pursued.  Patches
+to resolve these issues is welcome.  If a problem occurs which is not in
+the list, please report it.  That's why we do beta releases, after all...
+
+
+
+1) Work with Donald to merge fixes and updates into his driver.
+
+2) 2.2.x COMPATIBILITY SUPPORT IS BROKEN.  DO NOT USE IT.
+It is included only for enterprising hackers willing to help fix it.
+
+3) PPC platform has stability problems.
+
+4) Sparc64 platform not tested at all.
+
+5) Identify and fix "rx wedge" when ping flooded.
+
+7) N-Way auto-negotiation is known to fail in some cases.  This problem
+also occurs in the rtl8139 driver in kernels 2.2.x/2.3.x.  Solution:
+Following technique in sunhme and sunbmac, use a kernel timer to
+manually perform autonegotiation in case the network or card cannot do
+it automatically.  (patches welcome)
+
+8) Much improved command line / module parameter setup.  (patches and
+suggestions welcome)
+
+9) Better documentation.  (patches welcome)
+
+10) User-mode (or maybe optional /proc) diagnostics program.
+
+
+
+
+Change History
+--------------
+Version 0.9.3.3.2 - Feb 22, 2000 - second public beta release
+
+* Begin integration of Daniel Kobras' MMIO flush patch (disabled for now)
+* Softnet logic updates to fix bugs and improve performance
+* Dynamic sizing of I/O resources (0x80 for older chips, 0xFF for newer ones)
+* Remove bogus SiS entries from PCI probe table
+* Add support for cards
+	"Delta Electronics 8139 10/100BaseTX"
+	"Addtron Technolgy 8139 10/100BaseTX"
+* Fix major bug with rx ring buffer size (also present in rtl8139.c 1.08r)
+* PCI DMA mapping by Dave Miller
+* Complete rewrite of SMP locking logic
+* Hotplug support
+* Call rtl8139_hw_start from rtl8139_open, and remove duplicated code
+  from rtl8139_open
+* Reset NWay registers to sane defaults on rtl8139_open/hw_start
+* Miscellaneous code cleanup
+
+Version 0.7.0 - Feb 7, 2000 - first public beta release
+
+
+[EOF]
+
diff -u --recursive --new-file v2.3.47/linux/Documentation/networking/fore200e.txt linux/Documentation/networking/fore200e.txt
--- v2.3.47/linux/Documentation/networking/fore200e.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/networking/fore200e.txt	Mon Feb 21 16:32:27 2000
@@ -0,0 +1,55 @@
+
+Fore PCA-200E/SBA-200E ATM NIC Firmware Copyright Notice
+--------------------------------------------------------
+
+Please read the fore200e_firmware_copyright file present
+in the linux/drivers/atm directory for details and restrictions.
+
+
+Firmware Updates
+----------------
+
+The FORE Systems 200E-series driver is shipped with firmware data being 
+uploaded to the ATM adapters at system boot time or at module loading time. 
+The supplied firmware images should work with all adapters.
+
+However, if you encounter problems (firmware doesn't start or the driver
+is unable to read PROM data), you may consider trying another firmware
+version. Alternative binary firmware images can be found somewhere on the
+ForeThough CD-ROM supplied with your adapter by FORE Systems.
+
+You can also get the latest firmware images from FORE Systems at
+http://www.fore.com. Register TACTics Online and go to
+the 'software updates' pages. The firmware binaries are part of
+the various ForeThough software distributions.
+
+Notice that different versions of the PCA-200E firmware exist, depending
+on the endianess of the host architecture. The driver is shipped with
+both little and big endian PCA firmware images.
+
+Name and location of the new firmware images can be set at kernel
+configuration time.
+
+
+Driver Rebuilding
+-----------------
+
+1. Copy the new firmware binary files (with .bin, .bin1 or .bin2 suffix)
+   to some directory, such as linux/drivers/atm.
+
+2. Reconfigure your kernel to set the new firmware name and location.
+   Expected pathnames are absolute or relative to the drivers/atm directory.
+
+3. Delete the files drivers/atm/fore200e_pca_fw.[co] and/or fore200e_sba_fw.[co]
+   to ensure that the new firmware will be used when rebuilding the kernel or
+   the module.
+
+4. Rebuild and re-install your kernel or your module.
+
+
+Feedback
+--------
+
+Feedback is welcome. Please send success stories/bug reports/
+patches/improvement/comments/flames to <lizzi@cnam.fr>.
+
diff -u --recursive --new-file v2.3.47/linux/Documentation/networking/tulip.txt linux/Documentation/networking/tulip.txt
--- v2.3.47/linux/Documentation/networking/tulip.txt	Wed May 20 18:54:34 1998
+++ linux/Documentation/networking/tulip.txt	Fri Feb 25 15:16:37 2000
@@ -1,110 +1,144 @@
                 Tulip Ethernet Card Driver
+	  Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
 
 The Tulip driver is developed by Donald Becker and changed by
-Takashi Manabe. This driver is designed to work with PCI Ethernet
-cards which use the DECchip DC21x4x family. This driver hopefully
-works with all of 1.2.x and 1.3.x kernels, but I tested only
-with 1.2.13, 1.3.39, 1.3.49, 1.3.52, 1.3.57 and later.
-
-Hopefully, the de4x5.c driver will support all cards supported
-by the tulip.c driver. However, the SMC's 9332dst card and some
-cards do not work with the de4x5.c driver. So, if your card is
-not a 9332dst, please try the de4x5.c driver first.
-
-Success List
-============
-
-+-------------------------------------+-----------+-------------+
-|vendor/card                          |chip       |system       |
-+-------------------------------------+-----------+-------------+
-|SMC                                  |           |             |
-|     EtherPower 10 PCI(8432T/8432BT) |21040/21041|Pentium      |
-+-------------------------------------+-----------+-------------+
-|SMC                                  |           |             |
-|     EtherPower 10/100 PCI(9332DST)  |21140      |Pentium/UDB  |
-+-------------------------------------+-----------+-------------+
-|DEC                                  |           |             |
-|     EtherWorks 100/10 PCI(DE500-XA) |21140      |Pentium      |
-+-------------------------------------+-----------+-------------+
-|DEC                                  |           |             |
-|     EtherWorks 10 PCI(DE450)        |21041      |Pentium      |
-+-------------------------------------+-----------+-------------+
-|DEC                                  |           |             |
-|     QSILVER's                       |21040      |UDB          |
-+-------------------------------------+-----------+-------------+
-|ZNYX                                 |           |             |
-|     312 etherarray                  |21040      |Pentium      |
-+-------------------------------------+-----------+-------------+
-|Allied Telesis                       |           |             |
-|     LA100PCI-T                      |21140      |Pentium/UDB  |
-+-------------------------------------+-----------+-------------+
-|Danpex ('Planet Japan' in Japan?)    |           |             |
-|     EN-9400                         |21040      |Pentium      |
-+-------------------------------------+-----------+-------------+
-|Cogent                               |           |             |
-|     EM110                           |21140      |Pentium      |
-+-------------------------------------+-----------+-------------+
-
-Pentium: PCI machine with Pentium CPU
-UDB:     Universal Desktop Box(aka Multia) with Alpha 21066 CPU
-
-Known bug(s)
-============
-This driver's media detection is very simple and sometimes
-it causes serious problem. The driver automatically switches
-media when it causes timeout. If you want to specify or to fix
-a media;
-
-- Modify TULIP_PORT in tulip.c, line 33.
-- Uncomment the definition of TULIP_FIX_PORT in tulip.c, line 40.
-
-or
-
-- Use patched ifconfig command and specify 'link='. The patch
-  against ifconfig.c in net-tools-1.3.50-BETA6e is included in
-  this file.
+Takashi Manabe and a cast of thousands.
 
-Thanks
+	This driver is for the Digital "Tulip" Ethernet adapter interface.
+	It should work with most DEC 21*4*-based chips/ethercards, as well as
+	with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and ASIX.
+
+	The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
+	Center of Excellence in Space Data and Information Sciences
+	   Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
+
+	Additional information available at
+	http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html
+	
+				Theory of Operation
+
+Board Compatibility
+===================
+
+This device driver is designed for the DECchip "Tulip", Digital's
+single-chip ethernet controllers for PCI.  Supported members of the family
+are the 21040, 21041, 21140, 21140A, 21142, and 21143.  Similar work-alike
+chips from Lite-On, Macronics, ASIX, Compex and other listed below are also
+supported. 
+
+These chips are used on at least 140 unique PCI board designs.  The great
+number of chips and board designs supported is the reason for the
+driver size and complexity.  Almost of the increasing complexity is in the
+board configuration and media selection code.  There is very little
+increasing in the operational critical path length.
+
+Board-specific settings
+=======================
+
+PCI bus devices are configured by the system at boot time, so no jumpers
+need to be set on the board.  The system BIOS preferably should assign the
+PCI INTA signal to an otherwise unused system IRQ line.
+
+Some boards have EEPROMs tables with default media entry.  The factory default
+is usually "autoselect".  This should only be overridden when using
+transceiver connections without link beat e.g. 10base2 or AUI, or (rarely!)
+for forcing full-duplex when used with old link partners that do not do
+autonegotiation. 
+
+Driver operation
+================
+
+Ring buffers
+------------
+
+The Tulip can use either ring buffers or lists of Tx and Rx descriptors.
+This driver uses statically allocated rings of Rx and Tx descriptors, set at
+compile time by RX/TX_RING_SIZE.  This version of the driver allocates skbuffs
+for the Rx ring buffers at open() time and passes the skb->data field to the
+Tulip as receive data buffers.  When an incoming frame is less than
+RX_COPYBREAK bytes long, a fresh skbuff is allocated and the frame is
+copied to the new skbuff.  When the incoming frame is larger, the skbuff is
+passed directly up the protocol stack and replaced by a newly allocated
+skbuff.
+
+The RX_COPYBREAK value is chosen to trade-off the memory wasted by
+using a full-sized skbuff for small frames vs. the copying costs of larger
+frames.  For small frames the copying cost is negligible (esp. considering
+that we are pre-loading the cache with immediately useful header
+information).  For large frames the copying cost is non-trivial, and the
+larger copy might flush the cache of useful data.  A subtle aspect of this
+choice is that the Tulip only receives into longword aligned buffers, thus
+the IP header at offset 14 isn't longword aligned for further processing.
+Copied frames are put into the new skbuff at an offset of "+2", thus copying
+has the beneficial effect of aligning the IP header and preloading the
+cache.
+
+Synchronization
+---------------
+The driver runs as two independent, single-threaded flows of control.  One
+is the send-packet routine, which enforces single-threaded use by the
+dev->tbusy flag.  The other thread is the interrupt handler, which is single
+threaded by the hardware and other software.
+
+The send packet thread has partial control over the Tx ring and 'dev->tbusy'
+flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
+queue slot is empty, it clears the tbusy flag when finished otherwise it sets
+the 'tp->tx_full' flag.
+
+The interrupt handler has exclusive control over the Rx ring and records stats
+from the Tx ring.  (The Tx-done interrupt can't be selectively turned off, so
+we can't avoid the interrupt overhead by having the Tx routine reap the Tx
+stats.)	 After reaping the stats, it marks the queue entry as empty by setting
+the 'base' to zero.	 Iff the 'tp->tx_full' flag is set, it clears both the
+tx_full and tbusy flags.
+
+Notes
+=====
+
+Thanks to Duke Kamstra of SMC for long ago providing an EtherPower board.
+Greg LaPolla at Linksys provided PNIC and other Linksys boards.
+Znyx provided a four-port card for testing.
+
+References
+==========
+
+http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
+http://www.digital.com  (search for current 21*4* datasheets and "21X4 SROM")
+http://www.national.com/pf/DP/DP83840A.html
+http://www.asix.com.tw/pmac.htm
+http://www.admtek.com.tw/
+
+Errata
 ======
 
-o becker@CESDIS.gsfc.nasa.gov (author of the tulip.c driver)
-o davies@wanton.lkg.dec.com (author of the de4x5.c driver)
+The old DEC databooks were light on details.
+The 21040 databook claims that CSR13, CSR14, and CSR15 should each be the last
+register of the set CSR12-15 written.  Hmmm, now how is that possible?
+
+The DEC SROM format is very badly designed not precisely defined, leading to
+part of the media selection junkheap below.  Some boards do not have EEPROM
+media tables and need to be patched up.  Worse, other boards use the DEC
+design kit media table when it isn't correct for their board.
+
+We cannot use MII interrupts because there is no defined GPIO pin to attach
+them.  The MII transceiver status is polled using an kernel timer.
+
+
+Source tree tour
+----------------
+The following is a list of files comprising the Tulip ethernet driver in
+drivers/net/tulip subdirectory.
+
+21142.c		- 21142-specific h/w interaction
+eeprom.c	- EEPROM reading and parsing
+interrupt.c	- Interrupt handler
+media.c		- Media selection and MII support
+pnic.c		- PNIC-specific h/w interaction
+timer.c		- Main driver timer, and misc h/w timers
+tulip.h		- Private driver header
+tulip_core.c	- Driver core (a.k.a. where "everything else" goes)
+
+
 
-o siekas@mailhost.tcs.tulane.edu
+[EOF]
 
-o jheiss@calvin.caltech.edu (providing information about smc8432 card)
-o goto@plathome.co.jp (lending me a DE450 card)
-o ted@physics.ucsb.edu
-o pmheuvel@xs4all.nl
-o hjl@lucon.org (EN-9400)
-o niles@axp745.gsfc.nasa.gov (ZNYX312)
-o pkc@scs.carleton.ca (EM110)
-o and testers...
-
------------------------------------------------------------------------
-*** ifconfig.c-dist	Wed Jan 17 07:25:36 1996
---- ifconfig.c	Tue Apr  9 15:24:25 1996
-***************
-*** 765,770 ****
---- 766,786 ----
-  			continue;
-  		}
-  		ifr.ifr_map.irq = atoi(*spp);
-+ 		if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
-+ 			fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));
-+ 			goterr = 1;
-+ 		}
-+ 		spp++;
-+ 		continue;
-+ 	}
-+ 
-+ 	if (!strcmp(*spp, "link")) {
-+ 		if (*++spp == NULL) usage();
-+ 		if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
-+ 			goterr = 1;
-+ 			continue;
-+ 		}
-+ 		ifr.ifr_map.port = atoi(*spp);
-  		if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
-  			fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));
-  			goterr = 1;
diff -u --recursive --new-file v2.3.47/linux/Documentation/networking/wavelan.txt linux/Documentation/networking/wavelan.txt
--- v2.3.47/linux/Documentation/networking/wavelan.txt	Thu Aug 26 13:05:34 1999
+++ linux/Documentation/networking/wavelan.txt	Mon Feb 21 20:51:51 2000
@@ -1,41 +1,73 @@
-Sun Jul  2 01:38:33 EST 1995
+	The Wavelan drivers saga
+	------------------------
 
-	As the date above certify, this ``readme'' is mostly
-obsolete. Please read release notes and change list in
-driver/net/wavelan.p.h, and consult my web page at :
-	http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html
-
-	Jean <jt@hpl.hp.com>
-
-1. At present the driver autoprobes for a WaveLAN card only at I/O address 
-   0x390. The version of the card that I use (NCR) supports four I/O addresses
-   (selectable via a pair of DIP switches).  If you want the driver to
-   autoprobe a different subset of the four valid addresses then you will need
-   to edit .../drivers/net/wavelan.c (near line 714) and change the 
-   initialisation of the `iobase[]' array.  Normally, I use a LILO 
-   configuration file directive to obviate the need for autoprobing entirely, 
-   a course of action I heartily recommend.
-
-2. By default, the driver uses the Network ID (NWID) stored in the card's 
-   Parameter Storage Area (PSA).  However, the PSA NWID can be overridden by a
-   value passed explicitly as the third numeric argument to LILO's "ether="
-   directive, either  at the LILO prompt at boot time or within LILO's 
-   configuration file.
-   For example, the following line from such a LILO configuration file would
-   auto-configure the IRQ value, set the I/O base to 0x390 and set the NWID to
-   0x4321, all on a WaveLAN card labelled "eth0":
-
-	..
-	append	="ether=0,0x390,0x4321,eth0"
-	..
-
-3. The driver uses the IRQ stored in the card's PSA.
-   To change this you will need to use the configuration/setup software that
-   accompanies each WaveLAN device.  Yes, the driver should use the value passed
-   in via LILO and it will, just as soon as I can work out why that part of the
-   code doesn't work :-(.
+	By Jean Tourrilhes <jt@hpl.hp.com>
 
-4. If you encounter any problems send me some email.
+	The Wavelan is a Radio network adapter designed by
+Lucent. Under this generic name is hidden quite a variety of hardware,
+and many Linux driver to support it.
+	The get the full story on Wireless LANs, please consult :
+		http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
+
+"wavelan" driver (old ISA Wavelan)
+----------------
+	o Config :	Network device -> Wireless LAN -> AT&T WaveLAN
+	o Location :	.../drivers/net/wavelan*
+	o in-line doc :	.../drivers/net/wavelan.p.h
+	o on-line doc :
+	    http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html
+
+	This is the driver for the ISA version of the first generation
+of the Wavelan, now discontinued. The device is 2 Mb/s, composed of a
+Intel 82586 controler and a Lucent Modem, and is NOT 802.11 compliant.
+	The driver has been tested with the following hardware :
+	o Wavelan ISA 915 MHz (full length ISA card) 
+	o Wavelan ISA 915 MHz 2.0 (half length ISA card) 
+	o Wavelan ISA 2.4 GHz (full length ISA card, fixed frequency) 
+	o Wavelan ISA 2.4 GHz 2.0 (half length ISA card, frequency selectable) 
+	o Above cards with the optional DES encryption feature 
+
+"wavelan_cs" driver (old Pcmcia Wavelan)
+-------------------
+	o Config :	Network device -> PCMCIA network ->
+				Pcmcia Wireless LAN -> AT&T/Lucent WaveLAN
+	o Location :	.../drivers/net/pcmcia/wavelan*
+	o in-line doc :	.../drivers/net/pcmcia/wavelan_cs.h
+	o on-line doc :
+	    http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html
+
+	This is the driver for the PCMCIA version of the first
+generation of the Wavelan, now discontinued. The device is 2 Mb/s,
+composed of a Intel 82593 controler (totally different from the 82586)
+and a Lucent Modem, and NOT 802.11 compatible.
+	The driver has been tested with the following hardware :
+	o Wavelan Pcmcia 915 MHz 2.0 (Pcmcia card + separate
+					modem/antenna block) 
+	o Wavelan Pcmcia 2.4 GHz 2.0 (Pcmcia card + separate
+					modem/antenna block) 
+
+"wvlan_cs" driver (Wavelan IEEE, GPL)
+-----------------
+	o Config :	Not yet in kernel
+	o Location :	Pcmcia package 3.1.10+
+	o on-line doc :	http://www.fasta.fh-dortmund.de/users/andy/wvlan/
+
+	This is the driver for the current generation of Wavelan IEEE,
+which is 802.11 compatible. Depending on version, it is 2 Mb/s or 11
+Mb/s, with or without encryption, all implemented in Lucent specific
+DSP (the Hermes).
+	This is a GPL full source PCMCIA driver (ISA is just a Pcmcia
+card with ISA-Pcmcia bridge).
+
+"wavelan2_cs" driver (Wavelan IEEE, binary)
+--------------------
+	o Config :	Not yet in kernel
+	o Location :	ftp://sourceforge.org/pcmcia/contrib/
+
+	This driver support exactly the same hardware as the previous
+driver, the main difference is that it is based on a binary library
+and supported by Lucent.
 
-Good luck,
-Bruce Janson (bruce@cs.usyd.edu.au)
+	I hope it clears the confusion ;-)
+
+	Jean
diff -u --recursive --new-file v2.3.47/linux/Documentation/parport-lowlevel.txt linux/Documentation/parport-lowlevel.txt
--- v2.3.47/linux/Documentation/parport-lowlevel.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/parport-lowlevel.txt	Thu Feb 24 10:30:25 2000
@@ -0,0 +1,1490 @@
+PARPORT interface documentation
+-------------------------------
+
+Time-stamp: <2000-02-24 13:30:20 twaugh>
+
+Described here are the following functions:
+
+Global functions:
+  parport_register_driver
+  parport_unregister_driver
+  parport_enumerate
+  parport_register_device
+  parport_unregister_device
+  parport_claim
+  parport_claim_or_block
+  parport_release
+  parport_yield
+  parport_yield_blocking
+  parport_wait_peripheral
+  parport_poll_peripheral
+  parport_wait_event
+  parport_negotiate
+  parport_read
+  parport_write
+  parport_open
+  parport_close
+  parport_device_id
+  parport_device_num
+  parport_device_coords
+  parport_find_class
+  parport_find_device
+  parport_set_timeout
+
+Port functions (can be overridden by low-level drivers):
+  SPP:
+    port->ops->read_data
+    port->ops->write_data
+    port->ops->read_status
+    port->ops->read_control
+    port->ops->write_control
+    port->ops->frob_control
+    port->ops->enable_irq
+    port->ops->disable_irq
+    port->ops->data_forward
+    port->ops->data_reverse
+
+  EPP:
+    port->ops->epp_write_data
+    port->ops->epp_read_data
+    port->ops->epp_write_addr
+    port->ops->epp_read_addr
+
+  ECP:
+    port->ops->ecp_write_data
+    port->ops->ecp_read_data
+    port->ops->ecp_write_addr
+
+  Other:
+    port->ops->nibble_read_data
+    port->ops->byte_read_data
+    port->ops->compat_write_data
+
+The parport subsystem comprises 'parport' (the core port-sharing
+code), and a variety of low-level drivers that actually do the port
+accesses.  Each low-level driver handles a particular style of port
+(PC, Amiga, and so on).
+
+The parport interface to the device driver author can be broken down
+into global functions and port functions.
+
+The global functions are mostly for communicating between the device
+driver and the parport subsystem: acquiring a list of available ports,
+claiming a port for exclusive use, and so on.  They also include
+'generic' functions for doing standard things that will work on any
+IEEE 1284-capable architecture.
+
+The port functions are provided by the low-level drivers, although the
+core parport module provides generic 'defaults' for some routines.
+The port functions can be split into three groups: SPP, EPP, and ECP.
+
+SPP (Standard Parallel Port) functions modify so-called 'SPP'
+registers: data, status, and control.  The hardware may not actually
+have registers exactly like that, but the PC does and this interface is
+modelled after common PC implementations.  Other low-level drivers may
+be able to emulate most of the functionality.
+
+EPP (Enhanced Parallel Port) functions are provided for reading and
+writing in IEEE 1284 EPP mode, and ECP (Extended Capabilities Port)
+functions are used for IEEE 1284 ECP mode. (What about BECP? Does
+anyone care?)
+
+Hardware assistance for EPP and/or ECP transfers may or may not be
+available, and if it is available it may or may not be used.  If
+hardware is not used, the transfer will be software-driven.  In order
+to cope with peripherals that only tenuously support IEEE 1284, a
+low-level driver specific function is provided, for altering 'fudge
+factors'.
+
+GLOBAL FUNCTIONS
+----------------
+
+parport_register_driver - register a device driver with parport
+-----------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_driver {
+	const char *name;
+	void (*attach) (struct parport *);
+	void (*detach) (struct parport *);
+	struct parport_driver *next;
+};
+int parport_register_driver (struct parport_driver *driver);
+
+DESCRIPTION
+
+In order to be notified about parallel ports when they are detected,
+parport_register_driver should be called.  Your driver will
+immediately be notified of all ports that have already been detected,
+and of each new port as low-level drivers are loaded.
+
+A 'struct parport_driver' contains the textual name of your driver,
+a pointer to a function to handle new ports, and a pointer to a
+function to handle ports going away due to a low-level driver
+unloading.  Ports will only be detached if they are not being used
+(i.e. there are no devices registered on them).
+
+The visible parts of the 'struct parport *' argument given to
+attach/detach are:
+
+struct parport
+{
+	struct parport *next; /* next parport in list */
+	const char *name;     /* port's name */
+	unsigned int modes;   /* bitfield of hardware modes */
+	struct parport_device_info probe_info;
+			      /* IEEE1284 info */
+	int number;           /* parport index */
+	struct parport_operations *ops;
+	...
+};
+
+There are other members of the structure, but they should not be
+touched.
+
+The 'modes' member summarises the capabilities of the underlying
+hardware.  It consists of flags which may be bitwise-ored together:
+
+  PARPORT_MODE_PCSPP		IBM PC registers are available,
+				i.e. functions that act on data,
+				control and status registers are
+				probably writing directly to the
+				hardware.
+  PARPORT_MODE_TRISTATE		The data drivers may be turned off.
+				This allows the data lines to be used
+				for reverse (peripheral to host)
+				transfers.
+  PARPORT_MODE_COMPAT		The hardware can assist with
+				compatibility-mode (printer)
+				transfers, i.e. compat_write_block.
+  PARPORT_MODE_EPP		The hardware can assist with EPP
+				transfers.
+  PARPORT_MODE_ECP		The hardware can assist with ECP
+				transfers.
+  PARPORT_MODE_DMA		The hardware can use DMA, so you might
+				want to pass ISA DMA-able memory
+				(i.e. memory allocated using the
+				GFP_DMA flag with kmalloc) to the
+				low-level driver in order to take
+				advantage of it.
+
+There may be other flags in 'modes' as well.
+
+The contents of 'modes' is advisory only.  For example, if the
+hardware is capable of DMA, and PARPORT_MODE_DMA is in 'modes', it
+doesn't necessarily mean that DMA will always be used when possible.
+Similarly, hardware that is capable of assisting ECP transfers won't
+necessarily be used.
+
+RETURN VALUE
+
+Zero on success, otherwise an error code.
+
+ERRORS
+
+None. (Can it fail? Why return int?)
+
+EXAMPLE
+
+static void lp_attach (struct parport *port)
+{
+	...
+	private = kmalloc (...);
+	dev[count++] = parport_register_device (...);
+	...
+}
+
+static void lp_detach (struct parport *port)
+{
+	...
+}
+
+static struct parport_driver lp_driver = {
+	"lp",
+	lp_attach,
+	lp_detach,
+	NULL /* always put NULL here */
+};
+
+int lp_init (void)
+{
+	...
+	if (parport_register_driver (&lp_driver)) {
+		/* Failed; nothing we can do. */
+		return -EIO;
+	}
+	...
+}
+
+SEE ALSO
+
+parport_unregister_driver, parport_register_device, parport_enumerate
+
+parport_unregister_driver - tell parport to forget about this driver
+-------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_driver {
+	const char *name;
+	void (*attach) (struct parport *);
+	void (*detach) (struct parport *);
+	struct parport_driver *next;
+};
+void parport_unregister_driver (struct parport_driver *driver);
+
+DESCRIPTION
+
+This tells parport not to notify the device driver of new ports or of
+ports going away.  Registered devices belonging to that driver are NOT
+unregistered: parport_unregister_device must be used for each one.
+
+EXAMPLE
+
+void cleanup_module (void)
+{
+	...
+	/* Stop notifications. */
+	parport_unregister_driver (&lp_driver);
+
+	/* Unregister devices. */
+	for (i = 0; i < NUM_DEVS; i++)
+		parport_unregister_device (dev[i]);
+	...
+}
+
+SEE ALSO
+
+parport_register_driver, parport_enumerate
+
+parport_enumerate - retrieve a list of parallel ports (DEPRECATED)
+-----------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport *parport_enumerate (void);
+
+DESCRIPTION
+
+Retrieve the first of a list of valid parallel ports for this machine.
+Successive parallel ports can be found using the 'struct parport
+*next' element of the 'struct parport *' that is returned.  If 'next'
+is NULL, there are no more parallel ports in the list.  The number of
+ports in the list will not exceed PARPORT_MAX.
+
+RETURN VALUE
+
+A 'struct parport *' describing a valid parallel port for the machine,
+or NULL if there are none.
+
+ERRORS
+
+This function can return NULL to indicate that there are no parallel
+ports to use.
+
+EXAMPLE
+
+int detect_device (void)
+{
+	struct parport *port;
+
+	for (port = parport_enumerate ();
+	     port != NULL;
+	     port = port->next) {
+		/* Try to detect a device on the port... */
+		...
+             }
+	}
+
+	...
+}
+
+NOTES
+
+parport_enumerate is deprecated; parport_register_driver should be
+used instead.
+
+SEE ALSO
+
+parport_register_driver, parport_unregister_driver
+
+parport_register_device - register to use a port
+-----------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+typedef int (*preempt_func) (void *handle);
+typedef void (*wakeup_func) (void *handle);
+typedef int (*irq_func) (int irq, void *handle, struct pt_regs *);
+
+struct pardevice *parport_register_device(struct parport *port,
+                                          const char *name,
+                                          preempt_func preempt,
+                                          wakeup_func wakeup,
+                                          irq_func irq,
+                                          int flags,
+                                          void *handle);
+
+DESCRIPTION
+
+Use this function to register your device driver on a parallel port
+('port').  Once you have done that, you will be able to use
+parport_claim and parport_release in order to use the port.
+
+This function will register three callbacks into your driver:
+'preempt', 'wakeup' and 'irq'.  Each of these may be NULL in order to
+indicate that you do not want a callback.
+
+When the 'preempt' function is called, it is because another driver
+wishes to use the parallel port.  The 'preempt' function should return
+non-zero if the parallel port cannot be released yet -- if zero is
+returned, the port is lost to another driver and the port must be
+re-claimed before use.
+
+The 'wakeup' function is called once another driver has released the
+port and no other driver has yet claimed it.  You can claim the
+parallel port from within the 'wakeup' function (in which case the
+claim is guaranteed to succeed), or choose not to if you don't need it
+now.
+
+If an interrupt occurs on the parallel port your driver has claimed,
+the 'irq' function will be called. (Write something about shared
+interrupts here.)
+
+The 'handle' is a pointer to driver-specific data, and is passed to
+the callback functions.
+
+'flags' may be a bitwise combination of the following flags:
+
+        Flag            Meaning
+  PARPORT_DEV_EXCL	The device cannot share the parallel port at all.
+			Use this only when absolutely necessary.
+
+The typedefs are not actually defined -- they are only shown in order
+to make the function prototype more readable.
+
+The visible parts of the returned 'struct pardevice' are:
+
+struct pardevice {
+	struct parport *port;	/* Associated port */
+	void *private;		/* Device driver's 'handle' */
+	...
+};
+
+RETURN VALUE
+
+A 'struct pardevice *': a handle to the registered parallel port
+device that can be used for parport_claim, parport_release, etc.
+
+ERRORS
+
+A return value of NULL indicates that there was a problem registering
+a device on that port.
+
+EXAMPLE
+
+static int preempt (void *handle)
+{
+	if (busy_right_now)
+		return 1;
+
+	must_reclaim_port = 1;
+	return 0;
+}
+
+static void wakeup (void *handle)
+{
+	struct toaster *private = handle;
+	struct pardevice *dev = private->dev;
+	if (!dev) return; /* avoid races */
+
+	if (want_port)
+		parport_claim (dev);
+}
+
+static int toaster_detect (struct toaster *private, struct parport *port)
+{
+	private->dev = parport_register_device (port, "toaster", preempt,
+					        wakeup, NULL, 0,
+						private);
+	if (!private->dev)
+		/* Couldn't register with parport. */
+		return -EIO;
+
+	must_reclaim_port = 0;
+	busy_right_now = 1;
+	parport_claim_or_block (private->dev);
+	...
+	/* Don't need the port while the toaster warms up. */
+	busy_right_now = 0;
+	...
+	busy_right_now = 1;
+	if (must_reclaim_port) {
+		parport_claim_or_block (private->dev);
+		must_reclaim_port = 0;
+	}
+	...
+}
+
+SEE ALSO
+
+parport_unregister_device, parport_claim
+
+parport_unregister_device - finish using a port
+-------------------------
+
+SYNPOPSIS
+
+#include <linux/parport.h>
+
+void parport_unregister_device (struct pardevice *dev);
+
+DESCRIPTION
+
+This function is the opposite of parport_register_device.  After using
+parport_unregister_device, 'dev' is no longer a valid device handle.
+
+You should not unregister a device that is currently claimed, although
+if you do it will be released automatically.
+
+EXAMPLE
+
+	...
+	kfree (dev->private); /* before we lose the pointer */
+	parport_unregister_device (dev);
+	...
+
+SEE ALSO
+
+parport_unregister_driver
+
+parport_claim, parport_claim_or_block - claim the parallel port for a device
+-------------------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+int parport_claim (struct pardevice *dev);
+int parport_claim_or_block (struct pardevice *dev);
+
+DESCRIPTION
+
+These functions attempt to gain control of the parallel port on which
+'dev' is registered.  'parport_claim' does not block, but
+'parport_claim_or_block' may do. (Put something here about blocking
+interruptibly or non-interruptibly.)
+
+You should not try to claim a port that you have already claimed.
+
+RETURN VALUE
+
+A return value of zero indicates that the port was successfully
+claimed, and the caller now has possession of the parallel port.
+
+If 'parport_claim_or_block' blocks before returning successfully, the
+return value is positive.
+
+ERRORS
+
+  -EAGAIN  The port is unavailable at the moment, but another attempt
+           to claim it may succeed.
+
+SEE ALSO
+
+parport_release
+
+parport_release - release the parallel port
+---------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+void parport_release (struct pardevice *dev);
+
+DESCRIPTION
+
+Once a parallel port device has been claimed, it can be released using
+'parport_release'.  It cannot fail, but you should not release a
+device that you do not have possession of.
+
+EXAMPLE
+
+static size_t write (struct pardevice *dev, const void *buf,
+		     size_t len)
+{
+	...
+	written = dev->port->ops->write_ecp_data (dev->port, buf,
+						  len);
+	parport_release (dev);
+	...
+}
+
+
+SEE ALSO
+
+change_mode, parport_claim, parport_claim_or_block, parport_yield
+
+parport_yield, parport_yield_blocking - temporarily release a parallel port
+-------------------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+int parport_yield (struct pardevice *dev)
+int parport_yield_blocking (struct pardevice *dev);
+
+DESCRIPTION
+
+When a driver has control of a parallel port, it may allow another
+driver to temporarily 'borrow' it.  'parport_yield' does not block;
+'parport_yield_blocking' may do.
+
+RETURN VALUE
+
+A return value of zero indicates that the caller still owns the port
+and the call did not block.
+
+A positive return value from 'parport_yield_blocking' indicates that
+the caller still owns the port and the call blocked.
+
+A return value of -EAGAIN indicates that the caller no longer owns the
+port, and it must be re-claimed before use.
+
+ERRORS
+
+  -EAGAIN  Ownership of the parallel port was given away.
+
+SEE ALSO
+
+parport_release
+
+parport_wait_peripheral - wait for status lines, up to 35ms
+-----------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+int parport_wait_peripheral (struct parport *port,
+			     unsigned char mask,
+			     unsigned char val);
+
+DESCRIPTION
+
+Wait for the status lines in mask to match the values in val.
+
+RETURN VALUE
+
+ -EINTR  a signal is pending
+      0  the status lines in mask have values in val
+      1  timed out while waiting (35ms elapsed)
+
+SEE ALSO
+
+parport_poll_peripheral
+
+parport_poll_peripheral - wait for status lines, in usec
+-----------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+int parport_poll_peripheral (struct parport *port,
+			     unsigned char mask,
+			     unsigned char val,
+			     int usec);
+
+DESCRIPTION
+
+Wait for the status lines in mask to match the values in val.
+
+RETURN VALUE
+
+ -EINTR  a signal is pending
+      0  the status lines in mask have values in val
+      1  timed out while waiting (usec microseconds have elapsed)
+
+SEE ALSO
+
+parport_wait_peripheral
+
+parport_wait_event - wait for an event on a port
+------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+int parport_wait_event (struct parport *port, signed long timeout)
+
+DESCRIPTION
+
+Wait for an event (e.g. interrupt) on a port.  The timeout is in
+jiffies.
+
+RETURN VALUE
+
+      0  success
+     <0  error (exit as soon as possible)
+     >0  timed out
+
+parport_negotiate - perform IEEE 1284 negotiation
+-----------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+int parport_negotiate (struct parport *, int mode);
+
+DESCRIPTION
+
+Perform IEEE 1284 negotiation.
+
+RETURN VALUE
+
+     0  handshake OK; IEEE 1284 peripheral and mode available
+    -1  handshake failed; peripheral not compliant (or none present)
+     1  handshake OK; IEEE 1284 peripheral present but mode not
+        available
+
+SEE ALSO
+
+parport_read, parport_write
+
+parport_read - read data from device
+------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+ssize_t parport_read (struct parport *, void *buf, size_t len);
+
+DESCRIPTION
+
+Read data from device in current IEEE 1284 transfer mode.  This only
+works for modes that support reverse data transfer.
+
+RETURN VALUE
+
+If negative, an error code; otherwise the number of bytes transferred.
+
+SEE ALSO
+
+parport_write, parport_negotiate
+
+parport_write - write data to device
+-------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+ssize_t parport_write (struct parport *, const void *buf, size_t len);
+
+DESCRIPTION
+
+Write data to device in current IEEE 1284 transfer mode.  This only
+works for modes that support forward data transfer.
+
+RETURN VALUE
+
+If negative, an error code; otherwise the number of bytes transferred.
+
+SEE ALSO
+
+parport_read, parport_negotiate
+
+parport_open - register device for particular device number
+------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct pardevice *parport_open (int devnum, const char *name,
+			        int (*pf) (void *),
+				void (*kf) (void *),
+				void (*irqf) (int, void *,
+					      struct pt_regs *),
+				int flags, void *handle);
+
+DESCRIPTION
+
+This is like parport_register_device but takes a device number instead
+of a pointer to a struct parport.
+
+RETURN VALUE
+
+See parport_register_device.  If no device is associated with devnum,
+NULL is returned.
+
+SEE ALSO
+
+parport_register_device, parport_device_num
+
+parport_close - unregister device for particular device number
+-------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+void parport_close (struct pardevice *dev);
+
+DESCRIPTION
+
+This is the equivalent of parport_unregister_device for parport_open.
+
+SEE ALSO
+
+parport_unregister_device, parport_open
+
+parport_device_id - obtain IEEE 1284 Device ID
+-----------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+ssize_t parport_device_id (int devnum, char *buffer, size_t len);
+
+DESCRIPTION
+
+Obtains the IEEE 1284 Device ID associated with a given device.
+
+RETURN VALUE
+
+If negative, an error code; otherwise, the number of bytes of buffer
+that contain the device ID.  The format of the device ID is as
+follows:
+
+[length][ID]
+
+The first two bytes indicate the inclusive length of the entire Device
+ID, and are in big-endian order.  The ID is a sequence of pairs of the
+form:
+
+key:value;
+
+NOTES
+
+Many devices have ill-formed IEEE 1284 Device IDs.
+
+SEE ALSO
+
+parport_find_class, parport_find_device, parport_device_num
+
+parport_device_num - convert device coordinates to device number
+------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+int parport_device_num (int parport, int mux, int daisy);
+
+DESCRIPTION
+
+Convert between device coordinates (port, multiplexor, daisy chain
+address) and device number (zero-based).
+
+RETURN VALUE
+
+Device number, or -1 if no device at given coordinates.
+
+SEE ALSO
+
+parport_device_coords, parport_open, parport_device_id
+
+parport_device_coords - convert device number to device coordinates
+------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+int parport_device_coords (int devnum, int *parport, int *mux,
+			   int *daisy);
+
+DESCRIPTION
+
+Convert between device number (zero-based) and device coordinates
+(port, multiplexor, daisy chain address).
+
+RETURN VALUE
+
+Zero on success, in which case the coordinates are (*parport, *mux,
+*daisy).
+
+SEE ALSO
+
+parport_device_num, parport_open, parport_device_id
+
+parport_find_class - find a device by its class
+------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+typedef enum {
+	PARPORT_CLASS_LEGACY = 0,       /* Non-IEEE1284 device */
+	PARPORT_CLASS_PRINTER,
+	PARPORT_CLASS_MODEM,
+	PARPORT_CLASS_NET,
+	PARPORT_CLASS_HDC,              /* Hard disk controller */
+	PARPORT_CLASS_PCMCIA,
+	PARPORT_CLASS_MEDIA,            /* Multimedia device */
+	PARPORT_CLASS_FDC,              /* Floppy disk controller */
+	PARPORT_CLASS_PORTS,
+	PARPORT_CLASS_SCANNER,
+	PARPORT_CLASS_DIGCAM,
+	PARPORT_CLASS_OTHER,            /* Anything else */
+	PARPORT_CLASS_UNSPEC,           /* No CLS field in ID */
+	PARPORT_CLASS_SCSIADAPTER
+} parport_device_class;
+
+int parport_find_class (parport_device_class cls, int from);
+
+DESCRIPTION
+
+Find a device by class.  The search starts from device number from+1.
+
+RETURN VALUE
+
+The device number of the next device in that class, or -1 if no such
+device exists.
+
+NOTES
+
+Example usage:
+
+int devnum = -1;
+while ((devnum = parport_find_class (PARPORT_CLASS_DIGCAM, devnum)) != -1) {
+    struct pardevice *dev = parport_open (devnum, ...);
+    ...
+}
+
+SEE ALSO
+
+parport_find_device, parport_open, parport_device_id
+
+parport_find_device - find a device by its class
+------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+int parport_find_device (const char *mfg, const char *mdl, int from);
+
+DESCRIPTION
+
+Find a device by vendor and model.  The search starts from device
+number from+1.
+
+RETURN VALUE
+
+The device number of the next device matching the specifications, or
+-1 if no such device exists.
+
+NOTES
+
+Example usage:
+
+int devnum = -1;
+while ((devnum = parport_find_device ("IOMEGA", "ZIP+", devnum)) != -1) {
+    struct pardevice *dev = parport_open (devnum, ...);
+    ...
+}
+
+SEE ALSO
+
+parport_find_class, parport_open, parport_device_id
+
+parport_set_timeout - set the inactivity timeout
+-------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+long parport_set_timeout (struct pardevice *dev, long inactivity);
+
+DESCRIPTION
+
+Set the inactivity timeout, in jiffies, for a registered device.  The
+previous timeout is returned.
+
+RETURN VALUE
+
+The previous timeout, in jiffies.
+
+NOTES
+
+Some of the port->ops functions for a parport may take time, owing to
+delays at the peripheral.  After the peripheral has not responded for
+'inactivity' jiffies, a timeout will occur and the blocking function
+will return.
+
+A timeout of 0 jiffies is a special case: the function must do as much
+as it can without blocking or leaving the hardware in an unknown
+state.  If port operations are performed from within an interrupt
+handler, for instance, a timeout of 0 jiffies should be used.
+
+Once set for a registered device, the timeout will remain at the set
+value until set again.
+
+SEE ALSO
+
+port->ops->xxx_read/write_yyy
+
+PORT FUNCTIONS
+--------------
+
+The functions in the port->ops structure (struct parport_operations)
+are provided by the low-level driver responsible for that port.
+
+port->ops->read_data - read the data register
+--------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	unsigned char (*read_data) (struct parport *port);
+	...
+};
+
+DESCRIPTION
+
+If port->modes contains the PARPORT_MODE_TRISTATE flag and the
+PARPORT_CONTROL_DIRECTION bit in the control register is set, this
+returns the value on the data pins.  If port->modes contains the
+PARPORT_MODE_TRISTATE flag and the PARPORT_CONTROL_DIRECTION bit is
+not set, the return value _may_ be the last value written to the data
+register.  Otherwise the return value is undefined.
+
+SEE ALSO
+
+write_data, read_status, write_control
+
+port->ops->write_data - write the data register
+---------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	void (*write_data) (struct parport *port, unsigned char d);
+	...
+};
+
+DESCRIPTION
+
+Writes to the data register.  May have side-effects (a STROBE pulse,
+for instance).
+
+SEE ALSO
+
+read_data, read_status, write_control
+
+port->ops->read_status - read the status register
+----------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	unsigned char (*read_status) (struct parport *port);
+	...
+};
+
+DESCRIPTION
+
+Reads from the status register.  This is a bitmask:
+
+- PARPORT_STATUS_ERROR (printer fault, "nFault")
+- PARPORT_STATUS_SELECT (on-line, "Select")
+- PARPORT_STATUS_PAPEROUT (no paper, "PError")
+- PARPORT_STATUS_ACK (handshake, "nAck")
+- PARPORT_STATUS_BUSY (busy, "Busy")
+
+There may be other bits set.
+
+SEE ALSO
+
+read_data, write_data, write_control
+
+port->ops->read_control - read the control register
+-----------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	unsigned char (*read_control) (struct parport *port);
+	...
+};
+
+DESCRIPTION
+
+Returns the last value written to the control register (either from
+write_control or frob_control).  No port access is performed.
+
+SEE ALSO
+
+read_data, write_data, read_status, write_control
+
+port->ops->write_control - write the control register
+------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	void (*write_status) (struct parport *port, unsigned char s);
+	...
+};
+
+DESCRIPTION
+
+Writes to the control register. This is a bitmask:
+                          _______
+- PARPORT_CONTROL_STROBE (nStrobe)
+                          _______
+- PARPORT_CONTROL_AUTOFD (nAutoFd)
+                        _____
+- PARPORT_CONTROL_INIT (nInit)
+                          _________
+- PARPORT_CONTROL_SELECT (nSelectIn)
+
+SEE ALSO
+
+read_data, write_data, read_status, frob_control
+
+port->ops->frob_control - write control register bits
+-----------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	void (*frob_control) (struct parport *port,
+	                      unsigned char mask,
+			      unsigned char val);
+	...
+};
+
+DESCRIPTION
+
+This is equivalent to reading from the control register, masking out
+the bits in mask, exclusive-or'ing with the bits in val, and writing
+the result to the control register.
+
+As some ports don't allow reads from the control port, a software copy
+of its contents is maintained, so frob_control is in fact only one
+port access.
+
+SEE ALSO
+
+read_data, write_data, read_status, write_control
+
+port->ops->enable_irq - enable interrupt generation
+---------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	void (*enable_irq) (struct parport *port);
+	...
+};
+
+DESCRIPTION
+
+The parallel port hardware is instructed to generate interrupts at
+appropriate moments, although those moments are
+architecture-specific.  For the PC architecture, interrupts are
+commonly generated on the rising edge of nAck.
+
+SEE ALSO
+
+disable_irq
+
+port->ops->disable_irq - disable interrupt generation
+----------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	void (*disable_irq) (struct parport *port);
+	...
+};
+
+DESCRIPTION
+
+The parallel port hardware is instructed not to generate interrupts.
+The interrupt itself is not masked.
+
+SEE ALSO
+
+enable_irq
+
+port->ops->data_forward - enable data drivers
+-----------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	void (*data_forward) (struct parport *port);
+	...
+};
+
+DESCRIPTION
+
+Enables the data line drivers, for 8-bit host-to-peripheral
+communications.
+
+SEE ALSO
+
+data_reverse
+
+port->ops->data_reverse - tristate the buffer
+-----------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	void (*data_reverse) (struct parport *port);
+	...
+};
+
+DESCRIPTION
+
+Places the data bus in a high impedance state, if port->modes has the
+PARPORT_MODE_TRISTATE bit set.
+
+SEE ALSO
+
+data_forward
+
+port->ops->epp_write_data - write EPP data
+-------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	size_t (*epp_write_data) (struct parport *port, const void *buf,
+				  size_t len, int flags);
+	...
+};
+
+DESCRIPTION
+
+Writes data in EPP mode, and returns the number of bytes written.
+
+The 'flags' parameter may be one or more of the following,
+bitwise-or'ed together:
+
+PARPORT_EPP_FAST	Use fast transfers. Some chips provide 16-bit and
+			32-bit registers.  However, if a transfer
+			times out, the return value may be unreliable.
+
+SEE ALSO
+
+epp_read_data, epp_write_addr, epp_read_addr
+
+port->ops->epp_read_data - read EPP data
+------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	size_t (*epp_read_data) (struct parport *port, void *buf,
+				 size_t len, int flags);
+	...
+};
+
+DESCRIPTION
+
+Reads data in EPP mode, and returns the number of bytes read.
+
+The 'flags' parameter may be one or more of the following,
+bitwise-or'ed together:
+
+PARPORT_EPP_FAST	Use fast transfers. Some chips provide 16-bit and
+			32-bit registers.  However, if a transfer
+			times out, the return value may be unreliable.
+
+SEE ALSO
+
+epp_write_data, epp_write_addr, epp_read_addr
+
+port->ops->epp_write_addr - write EPP address
+-------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	size_t (*epp_write_addr) (struct parport *port,
+				  const void *buf, size_t len, int flags);
+	...
+};
+
+DESCRIPTION
+
+Writes EPP addresses (8 bits each), and returns the number written.
+
+The 'flags' parameter may be one or more of the following,
+bitwise-or'ed together:
+
+PARPORT_EPP_FAST	Use fast transfers. Some chips provide 16-bit and
+			32-bit registers.  However, if a transfer
+			times out, the return value may be unreliable.
+
+(Does PARPORT_EPP_FAST make sense for this function?)
+
+SEE ALSO
+
+epp_write_data, epp_read_data, epp_read_addr
+
+port->ops->epp_read_addr - read EPP address
+------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	size_t (*epp_read_addr) (struct parport *port, void *buf,
+				 size_t len, int flags);
+	...
+};
+
+DESCRIPTION
+
+Reads EPP addresses (8 bits each), and returns the number read.
+
+The 'flags' parameter may be one or more of the following,
+bitwise-or'ed together:
+
+PARPORT_EPP_FAST	Use fast transfers. Some chips provide 16-bit and
+			32-bit registers.  However, if a transfer
+			times out, the return value may be unreliable.
+
+(Does PARPORT_EPP_FAST make sense for this function?)
+
+SEE ALSO
+
+epp_write_data, epp_read_data, epp_write_addr
+
+port->ops->ecp_write_data - write a block of ECP data
+-------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	size_t (*ecp_write_data) (struct parport *port,
+				  const void *buf, size_t len, int flags);
+	...
+};
+
+DESCRIPTION
+
+Writes a block of ECP data.  The 'flags' parameter is ignored.
+
+RETURN VALUE
+
+The number of bytes written.
+
+SEE ALSO
+
+ecp_read_data, ecp_write_addr
+
+port->ops->ecp_read_data - read a block of ECP data
+------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	size_t (*ecp_read_data) (struct parport *port,
+				 void *buf, size_t len, int flags);
+	...
+};
+
+DESCRIPTION
+
+Reads a block of ECP data.  The 'flags' parameter is ignored.
+
+RETURN VALUE
+
+The number of bytes read.  NB. There may be more unread data in a
+FIFO.  Is there a way of stunning the FIFO to prevent this?
+
+SEE ALSO
+
+ecp_write_block, ecp_write_addr
+
+port->ops->ecp_write_addr - write a block of ECP addresses
+-------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	size_t (*ecp_write_addr) (struct parport *port,
+				  const void *buf, size_t len, int flags);
+	...
+};
+
+DESCRIPTION
+
+Writes a block of ECP addresses.  The 'flags' parameter is ignored.
+
+RETURN VALUE
+
+The number of bytes written.
+
+NOTES
+
+This may use a FIFO, and if so shall not return until the FIFO is empty.
+
+SEE ALSO
+
+ecp_read_data, ecp_write_data
+
+port->ops->nibble_read_data - read a block of data in nibble mode
+---------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	size_t (*nibble_read_data) (struct parport *port,
+				    void *buf, size_t len, int flags);
+	...
+};
+
+DESCRIPTION
+
+Reads a block of data in nibble mode.  The 'flags' parameter is ignored.
+
+RETURN VALUE
+
+The number of whole bytes read.
+
+SEE ALSO
+
+byte_read_data, compat_write_data
+
+port->ops->byte_read_data - read a block of data in byte mode
+-------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	size_t (*byte_read_data) (struct parport *port,
+				  void *buf, size_t len, int flags);
+	...
+};
+
+DESCRIPTION
+
+Reads a block of data in byte mode.  The 'flags' parameter is ignored.
+
+RETURN VALUE
+
+The number of bytes read.
+
+SEE ALSO
+
+nibble_read_data, compat_write_data
+
+port->ops->compat_write_data - write a block of data in compatibility mode
+----------------------------
+
+SYNOPSIS
+
+#include <linux/parport.h>
+
+struct parport_operations {
+	...
+	size_t (*compat_write_data) (struct parport *port,
+				     const void *buf, size_t len, int flags);
+	...
+};
+
+DESCRIPTION
+
+Writes a block of data in compatibility mode.  The 'flags' parameter
+is ignored.
+
+RETURN VALUE
+
+The number of bytes written.
+
+SEE ALSO
+
+nibble_read_data, byte_read_data
diff -u --recursive --new-file v2.3.47/linux/Documentation/pci.txt linux/Documentation/pci.txt
--- v2.3.47/linux/Documentation/pci.txt	Thu Feb 10 17:11:02 2000
+++ linux/Documentation/pci.txt	Mon Feb 21 10:59:36 2000
@@ -174,6 +174,8 @@
 pci_set_power_state()		Set PCI Power Management state (0=D0 ... 3=D3)
 pci_find_capability()		Find specified capability in device's capability
 				list.
+pci_module_init()		Inline helper function for ensuring correct
+				pci_driver initialization and error handling.
 
 
 7. Miscellaneous hints
diff -u --recursive --new-file v2.3.47/linux/Documentation/pm.txt linux/Documentation/pm.txt
--- v2.3.47/linux/Documentation/pm.txt	Thu Feb 10 17:11:02 2000
+++ linux/Documentation/pm.txt	Wed Feb 23 20:05:12 2000
@@ -164,3 +164,154 @@
  *          access the device hardware until a call to "pm_access" is made.
  */
 typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data);
+
+Driver Details
+--------------
+This is just a quick Q&A as a stopgap until a real driver writers'
+power management guide is available.
+
+Q: When is a device suspended?
+
+Devices can be suspended based on direct user request (eg. laptop lid
+closes), system power policy (eg.  sleep after 30 minutes of console
+inactivity), or device power policy (eg. power down device after 5
+minutes of inactivity)
+
+Q: Must a driver honor a suspend request?
+
+No, a driver can return -EBUSY from a suspend request and this
+will stop the system from suspending.  When a suspend request
+fails, all suspended devices are resumed and the system continues
+to run.  Suspend can be retried at a later time.
+
+Q: Can the driver block suspend/resume requests?
+
+Yes, a driver can delay its return from a suspend or resume
+request until the device is ready to handle requests.  It
+is advantageous to return as quickly as possible from a
+request as suspend/resume are done serially.
+
+Q: What context is a suspend/resume initiated from?
+
+A suspend or resume is initiated from a kernel thread context.
+It is safe to block, allocate memory, initiate requests
+or anything else you can do within the kernel.
+
+Q: Will requests continue to arrive after a suspend?
+
+Possibly.  It is the driver's responsibility to queue(*),
+fail, or drop any requests that arrive after returning
+success to a suspend request.  It is important that the
+driver not access its device until after it receives
+a resume request as the device's bus may no longer
+be active.
+
+(*) If a driver queues requests for processing after
+    resume be aware that the device, network, etc.
+    might be in a different state than at suspend time.
+    It's probably better to drop requests unless
+    the driver is a storage device.
+
+Q: Do I have to manage bus-specific power management registers
+
+No.  It is the responsibility of the bus driver to manage
+PCI, USB, etc. power management registers.  The bus driver
+or the power management subsystem will also enable any
+wake-on functionality that the device has.
+
+Q: So, really, what do I need to do to support suspend/resume?
+
+You need to save any device context that would
+be lost if the device was powered off and then restore
+it at resume time.  When ACPI is active, there are
+three levels of device suspend states; D1, D2, and D3.
+(The suspend state is passed as the "data" argument
+to the device callback.)  With D3, the device is powered
+off and loses all context, D1 and D2 are shallower power
+states and require less device context to be saved.  To
+play it safe, just save everything at suspend and restore
+everything at resume.
+
+Q: Where do I store device context for suspend?
+
+Anywhere in memory, kmalloc a buffer or store it
+in the device descriptor.  You are guaranteed that the
+contents of memory will be restored and accessible
+before resume, even when the system suspends to disk.
+
+Q: What do I need to do for ACPI vs. APM vs. etc?
+
+Drivers need not be aware of the specific power management
+technology that is active.  They just need to be aware
+of when the overlying power management system requests
+that they suspend or resume.
+
+Q: What about device dependencies?
+
+When a driver registers a device, the power management
+subsystem uses the information provided to build a
+tree of device dependencies (eg. USB device X is on
+USB controller Y which is on PCI bus Z)  When power
+management wants to suspend a device, it first sends
+a suspend request to its driver, then the bus driver,
+and so on up to the system bus.  Device resumes
+proceed in the opposite direction.
+
+Q: Who do I contact for additional information about
+   enabling power management for my specific driver/device?
+
+ACPI4Linux mailing list: acpi@phobos.fs.tum.de
+Linux ACPI maintainer: andy_henroid@yahoo.com
+
+System Interface
+----------------
+If you are providing new power management support to Linux (ie.
+adding support for something like APM or ACPI), you should
+communicate with drivers through the existing generic power
+management interface.
+
+/*
+ * Send a request to a single device
+ *
+ * Parameters:
+ *   dev - PM device previously returned from pm_register or pm_find
+ *   rqst - request type
+ *   data - data, if any, associated with the request
+ *
+ * Returns: 0 if the request is successful
+ *          See "pm_callback" return for errors
+ *
+ * Details: Forward request to device callback and, if a suspend
+ *          or resume request, update the pm_dev "state" field
+ *          appropriately
+ */
+int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data);
+
+/*
+ * Send a request to all devices
+ *
+ * Parameters:
+ *   rqst - request type
+ *   data - data, if any, associated with the request
+ *
+ * Returns: 0 if the request is successful
+ *          See "pm_callback" return for errors
+ *
+ * Details: Walk list of registered devices and call pm_send
+ *          for each until complete or an error is encountered.
+ *          If an error is encountered for a suspend request,
+ *          return all devices to the state they were in before
+ *          the suspend request.
+ */
+int pm_send_all(pm_request_t rqst, void *data);
+
+/*
+ * Find a matching device
+ *
+ * Parameters:
+ *   type - device type (PCI device, system device, or 0 to match all devices)
+ *   from - previous match or NULL to start from the beginning
+ *
+ * Returns: Matching device or NULL if none found
+ */
+struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from);
diff -u --recursive --new-file v2.3.47/linux/Documentation/vm/balance linux/Documentation/vm/balance
--- v2.3.47/linux/Documentation/vm/balance	Fri Jan 28 15:09:06 2000
+++ linux/Documentation/vm/balance	Sat Feb 26 20:50:34 2000
@@ -68,11 +68,23 @@
 probably because all allocation requests are coming from intr context
 and all process contexts are sleeping. For 2.3, kswapd does not really
 need to balance the highmem zone, since intr context does not request
-highmem pages. A zone aware kswapd still needs to be implemented.
+highmem pages. kswapd looks at the zone_wake_kswapd field in the zone
+structure to decide whether a zone needs balancing.
 
 Page stealing from process memory and shm is done if stealing the page would
 alleviate memory pressure on any zone in the page's node that has fallen below
 its watermark.
+
+pages_min/pages_low/pages_high/low_on_memory/zone_wake_kswapd: These are 
+per-zone fields, used to determine when a zone needs to be balanced. When
+the number of pages falls below pages_min, the hysteric field low_on_memory
+gets set. This stays set till the number of free pages becomes pages_high.
+When low_on_memory is set, page allocation requests will try to free some
+pages in the zone (providing GFP_WAIT is set in the request). Orthogonal
+to this, is the decision to poke kswapd to free some zone pages. That
+decision is not hysteresis based, and is done when the number of free
+pages is below pages_low; in which case zone_wake_kswapd is also set.
+
 
 (Good) Ideas that I have heard:
 1. Dynamic experience should influence balancing: number of failed requests
diff -u --recursive --new-file v2.3.47/linux/MAINTAINERS linux/MAINTAINERS
--- v2.3.47/linux/MAINTAINERS	Sun Feb 20 21:12:38 2000
+++ linux/MAINTAINERS	Fri Feb 25 15:16:37 2000
@@ -726,6 +726,12 @@
 L:	linux-kernel@vger.rutgers.edu
 S:	Maintained
 
+NVIDIA (RIVA) FRAMEBUFFER DRIVER
+P:	Jeff Garzik
+M:	jgarzik@mandrakesoft.com
+L:	linux-nvidia@lists.surfsouth.com
+S:	Maintained
+
 OLYMPIC NETWORK DRIVER
 P:	Peter De Shrijver
 M:	p2@ace.ulyssis.sutdent.kuleuven.ac.be	
@@ -778,7 +784,7 @@
 P:	Martin Mares
 M:	mj@suse.cz
 L:	linux-kernel@vger.rutgers.edu
-S:	Maintained
+S:	Supported
 
 PCMCIA SUBSYSTEM
 P:	David Hinds
@@ -986,7 +992,7 @@
 
 SVGA HANDLING
 P:	Martin Mares
-M:	mj@atrey.karlin.mff.cuni.cz
+M:	mj@suse.cz
 L:	linux-video@atrey.karlin.mff.cuni.cz
 S:	Maintained
 
@@ -1021,6 +1027,12 @@
 W:	http://www.auk.cx/tms380tr/
 S:	Maintained
 
+TULIP NETWORK DRIVER
+P:	Jeff Garzik
+M:	jgarzik@mandrakesoft.com
+L:	linux-tulip@cesdis.gsfc.nasa.gov
+S:	Maintained
+
 U14-34F SCSI DRIVER
 P:	Dario Ballabio
 M:	dario@milano.europe.dg.com
@@ -1112,6 +1124,7 @@
 VIA 82Cxxx AUDIO DRIVER
 P:	Jeff Garzik
 M:	jgarzik@mandrakesoft.com
+L:	linux-via@gtf.org
 S:	Maintained
 
 VIDEO FOR LINUX
diff -u --recursive --new-file v2.3.47/linux/Makefile linux/Makefile
--- v2.3.47/linux/Makefile	Sun Feb 20 21:12:38 2000
+++ linux/Makefile	Fri Feb 25 10:26:42 2000
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 3
-SUBLEVEL = 47
+SUBLEVEL = 48
 EXTRAVERSION =
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
@@ -27,6 +27,7 @@
 AR	=$(CROSS_COMPILE)ar
 NM	=$(CROSS_COMPILE)nm
 STRIP	=$(CROSS_COMPILE)strip
+OBJCOPY	=$(CROSS_COMPILE)objcopy
 OBJDUMP	=$(CROSS_COMPILE)objdump
 MAKE	=make
 GENKSYMS=/sbin/genksyms
@@ -95,9 +96,6 @@
 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
 AFLAGS := $(CPPFLAGS)
 
-# use '-fno-strict-aliasing', but only if the compiler can take it
-CFLAGS += $(shell if $(CC) -fno-strict-aliasing -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strict-aliasing"; fi)
-
 #
 # if you want the RAM disk device, define this to be the
 # size in blocks.
@@ -214,7 +212,7 @@
 DRIVERS := $(DRIVERS) drivers/pnp/pnp.o
 endif
 
-ifdef CONFIG_SGI
+ifdef CONFIG_SGI_IP22
 DRIVERS := $(DRIVERS) drivers/sgi/sgi.a
 endif
 
@@ -256,6 +254,9 @@
 
 include arch/$(ARCH)/Makefile
 
+# use '-fno-strict-aliasing', but only if the compiler can take it
+CFLAGS += $(shell if $(CC) -fno-strict-aliasing -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strict-aliasing"; fi)
+
 .S.s:
 	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -E -o $*.s $<
 .S.o:
@@ -363,7 +364,7 @@
 	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print | xargs ctags $$CTAGSF -a && \
 	find $(SUBDIRS) init -name '*.c' | xargs ctags $$CTAGSF -a
 
-MODFLAGS = -DMODULE
+MODFLAGS += -DMODULE
 ifdef CONFIG_MODULES
 ifdef CONFIG_MODVERSIONS
 MODFLAGS += -DMODVERSIONS -include $(HPATH)/linux/modversions.h
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.3.47/linux/arch/alpha/config.in	Thu Feb 10 17:11:02 2000
+++ linux/arch/alpha/config.in	Mon Feb 21 17:38:03 2000
@@ -60,6 +60,7 @@
 unset CONFIG_ALPHA_T2 CONFIG_ALPHA_PYXIS CONFIG_ALPHA_POLARIS
 unset CONFIG_ALPHA_TSUNAMI CONFIG_ALPHA_MCPCIA
 unset CONFIG_ALPHA_IRONGATE
+unset CONFIG_ALPHA_BROKEN_IRQ_MASK
 
 # Most of these machines have ISA slots; not exactly sure which don't,
 # and this doesn't activate hordes of code, so do it always.
@@ -177,6 +178,10 @@
 if [ "$CONFIG_ALPHA_XL" = "y" ]
 then
 	define_bool CONFIG_ALPHA_AVANTI y
+fi
+if [ "$CONFIG_ALPHA_GENERIC" = "y" -o "$CONFIG_ALPHA_PC164" = "y" ]
+then
+	define_bool CONFIG_ALPHA_BROKEN_IRQ_MASK y
 fi
 
 if [ "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- v2.3.47/linux/arch/alpha/kernel/alpha_ksyms.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/alpha/kernel/alpha_ksyms.c	Mon Feb 21 17:38:03 2000
@@ -98,6 +98,8 @@
 EXPORT_SYMBOL(__memsetw);
 EXPORT_SYMBOL(__constant_c_memset);
 
+EXPORT_SYMBOL(__direct_map_base);
+EXPORT_SYMBOL(__direct_map_size);
 EXPORT_SYMBOL(pci_alloc_consistent);
 EXPORT_SYMBOL(pci_free_consistent);
 EXPORT_SYMBOL(pci_map_single);
@@ -142,6 +144,10 @@
 extern long (*alpha_fp_emul) (unsigned long pc);
 EXPORT_SYMBOL(alpha_fp_emul_imprecise);
 EXPORT_SYMBOL(alpha_fp_emul);
+#endif
+
+#ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK
+EXPORT_SYMBOL(__min_ipl);
 #endif
 
 /*
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/core_tsunami.c linux/arch/alpha/kernel/core_tsunami.c
--- v2.3.47/linux/arch/alpha/kernel/core_tsunami.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/alpha/kernel/core_tsunami.c	Thu Feb 24 22:44:17 2000
@@ -24,7 +24,6 @@
 #include "proto.h"
 #include "pci_impl.h"
 
-int TSUNAMI_bootcpu;
 
 static struct 
 {
@@ -210,17 +209,23 @@
 tsunami_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
 {
 	tsunami_pchip *pchip = hose->index ? TSUNAMI_pchip1 : TSUNAMI_pchip0;
-
-	wmb();
+	volatile unsigned long *csr;
+	unsigned long value;
 
 	/* We can invalidate up to 8 tlb entries in a go.  The flush
 	   matches against <31:16> in the pci address.  */
+	csr = &pchip->tlbia.csr;
 	if (((start ^ end) & 0xffff0000) == 0)
-		pchip->tlbiv.csr = (start & 0xffff0000) >> 12;
-	else
-		pchip->tlbia.csr = 0;
+		csr = &pchip->tlbiv.csr;
 
+	/* For TBIA, it doesn't matter what value we write.  For TBI, 
+	   it's the shifted tag bits.  */
+	value = (start & 0xffff0000) >> 12;
+
+	wmb();
+	*csr = value;
 	mb();
+	*csr;
 }
 
 #ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
@@ -229,7 +234,7 @@
 {
 	long dont_care, probe_result;
 	int cpu = smp_processor_id();
-	int s = swpipl(6);	/* Block everything but machine checks. */
+	int s = swpipl(IPL_MCHECK - 1);
 
 	mcheck_taken(cpu) = 0;
 	mcheck_expected(cpu) = 1;
@@ -338,9 +343,13 @@
 	 * because of an idiot-syncrasy of the CYPRESS chip.  It may
 	 * respond to a PCI bus address in the last 1MB of the 4GB
 	 * address range.
+	 *
+	 * Note that the TLB lookup logic uses bitwise concatenation,
+	 * not addition, so the required arena alignment is based on
+	 * the size of the window.
 	 */
-	hose->sg_isa = iommu_arena_new(0x00800000, 0x00800000, PAGE_SIZE);
-	hose->sg_pci = iommu_arena_new(0xc0000000, 0x08000000, PAGE_SIZE);
+	hose->sg_isa = iommu_arena_new(0x00800000, 0x00800000, 0x00800000>>10);
+	hose->sg_pci = iommu_arena_new(0xc0000000, 0x08000000, 0x08000000>>10);
 	__direct_map_base = 0x40000000;
 	__direct_map_size = 0x80000000;
 
@@ -399,8 +408,6 @@
 	printk("%s: CSR_STR 0x%lx\n", FN, TSUNAMI_dchip->str.csr);
 	printk("%s: CSR_DREV 0x%lx\n", FN, TSUNAMI_dchip->drev.csr);
 #endif
-	TSUNAMI_bootcpu = __hard_smp_processor_id();
-
 	/* With multiple PCI busses, we play with I/O as physical addrs.  */
 	ioport_resource.end = ~0UL;
 	iomem_resource.end = ~0UL;
@@ -444,12 +451,10 @@
 static inline void
 tsunami_pci_clr_err_1(tsunami_pchip *pchip)
 {
-	unsigned int jd;
-
-	jd = pchip->perror.csr;
+	pchip->perror.csr;
 	pchip->perror.csr = 0x040;
 	mb();
-	jd = pchip->perror.csr;
+	pchip->perror.csr;
 }
 
 static inline void
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
--- v2.3.47/linux/arch/alpha/kernel/irq.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/alpha/kernel/irq.c	Thu Feb 24 22:44:17 2000
@@ -48,6 +48,12 @@
 #define ACTUAL_NR_IRQS	NR_IRQS
 #endif
 
+/* Hack minimum IPL during interupt processing for broken hardware.  */
+
+#ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK
+int __min_ipl;
+#endif
+
 /*
  * Performance counter hook.  A module can override this to
  * do something useful.
@@ -283,30 +289,32 @@
 		 struct irqaction *action)
 {
 	int status, cpu = smp_processor_id();
-	unsigned long ipl;
+	int old_ipl, ipl;
 
 	kstat.irqs[cpu][irq]++;
 	irq_enter(cpu, irq);
 
 	status = 1;	/* Force the "do bottom halves" bit */
-	ipl = rdps() & 7;
 
+	old_ipl = ipl = getipl();
 	do {
-		unsigned long newipl = (action->flags & SA_INTERRUPT ? 7 : 0);
-		if (newipl != ipl) {
-			swpipl(newipl);
-			ipl = newipl;
+		int new_ipl = IPL_MIN;
+		if (action->flags & SA_INTERRUPT)
+			new_ipl = IPL_MAX;
+		if (new_ipl != ipl) {
+			setipl(new_ipl);
+			ipl = new_ipl;
 		}
 
 		status |= action->flags;
 		action->handler(irq, action->dev_id, regs);
 		action = action->next;
 	} while (action);
+	if (ipl != old_ipl)
+		setipl(old_ipl);
+
 	if (status & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	if (ipl == 0)
-		__cli();
-
 	irq_exit(cpu, irq);
 
 	return status;
@@ -325,7 +333,7 @@
 
 	spin_lock_irqsave(&irq_controller_lock, flags);
 	if (!irq_desc[irq].depth++) {
-		irq_desc[irq].status |= IRQ_DISABLED;
+		irq_desc[irq].status |= IRQ_DISABLED | IRQ_MASKED;
 		irq_desc[irq].handler->disable(irq);
 	}
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
@@ -356,14 +364,15 @@
 	switch (irq_desc[irq].depth) {
 	case 1:
 	  {
-		unsigned int status = irq_desc[irq].status & ~IRQ_DISABLED;
-		irq_desc[irq].status = status;
-		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
-			irq_desc[irq].status = status | IRQ_REPLAY;
+		unsigned int status = irq_desc[irq].status;
 
+		status &= ~(IRQ_DISABLED | IRQ_MASKED);
+		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+			status |= IRQ_REPLAY;
 			/* ??? We can't re-send on (most?) alpha hw.
 			   hw_resend_irq(irq_desc[irq].handler,irq); */
 		}
+		irq_desc[irq].status = status;
 		irq_desc[irq].handler->enable(irq);
 		/* fall-through */
 	  }
@@ -425,7 +434,7 @@
 
 	if (!shared) {
 		irq_desc[irq].depth = 0;
-		irq_desc[irq].status &= ~IRQ_DISABLED;
+		irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_MASKED);
 		irq_desc[irq].handler->startup(irq);
 	}
 	spin_unlock_irqrestore(&irq_controller_lock,flags);
@@ -500,7 +509,7 @@
 			/* Found - now remove it from the list of entries.  */
 			*pp = action->next;
 			if (!irq_desc[irq].action) {
-				irq_desc[irq].status |= IRQ_DISABLED;
+				irq_desc[irq].status |= IRQ_DISABLED|IRQ_MASKED;
 				irq_desc[irq].handler->shutdown(irq);
 			}
 			spin_unlock_irqrestore(&irq_controller_lock,flags);
@@ -669,7 +678,7 @@
 	 * Maximize ipl.  If ipl was previously 0 and if this thread
 	 * is not in an irq, then take global_irq_lock.
 	 */
-	if (swpipl(7) == 0 && !local_irq_count(cpu))
+	if (swpipl(IPL_MAX) == IPL_MIN && !local_irq_count(cpu))
 		get_irqlock(cpu, where);
 }
 
@@ -841,13 +850,25 @@
 	desc = irq_desc + irq;
 	spin_lock_irq(&irq_controller_lock); /* mask also the RTC */
 	desc->handler->ack(irq);
+	status = desc->status;
+
+#ifndef CONFIG_SMP
+	/* Look for broken irq masking.  */
+	if (status & IRQ_MASKED) {
+		static unsigned long last_printed;
+		if (time_after(jiffies, last_printed+HZ)) {
+			printk(KERN_CRIT "Mask didn't work for irq %d!\n", irq);
+			last_printed = jiffies;
+		}
+	}
+#endif
 
 	/*
 	 * REPLAY is when Linux resends an IRQ that was dropped earlier.
 	 * WAITING is used by probe to mark irqs that are being tested.
 	 */
-	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
-	status |= IRQ_PENDING; /* we _want_ to handle it */
+	status &= ~(IRQ_REPLAY | IRQ_WAITING);
+	status |= IRQ_PENDING | IRQ_MASKED; /* we _want_ to handle it */
 
 	/*
 	 * If the IRQ is disabled for whatever reason, we cannot
@@ -890,9 +911,12 @@
 		desc->status &= ~IRQ_PENDING;
 		spin_unlock(&irq_controller_lock);
 	}
-	desc->status &= ~IRQ_INPROGRESS;
-	if (!(desc->status & IRQ_DISABLED))
+	status = desc->status & ~IRQ_INPROGRESS;
+	if (!(status & IRQ_DISABLED)) {
+		status &= ~IRQ_MASKED;
 		desc->handler->end(irq);
+	}
+	desc->status = status;
 	spin_unlock(&irq_controller_lock);
 }
 
@@ -1056,7 +1080,7 @@
 #ifdef CONFIG_SMP
 		cpu_data[smp_processor_id()].smp_local_irq_count++;
 		smp_percpu_timer_interrupt(&regs);
-		if (smp_processor_id() == smp_boot_cpuid)
+		if (smp_processor_id() == boot_cpuid)
 #endif
 			handle_irq(RTC_IRQ, &regs);
 		return;
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/pci_iommu.c linux/arch/alpha/kernel/pci_iommu.c
--- v2.3.47/linux/arch/alpha/kernel/pci_iommu.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/alpha/kernel/pci_iommu.c	Thu Feb 24 22:45:28 2000
@@ -133,6 +133,9 @@
 	unsigned long paddr;
 	dma_addr_t ret;
 
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
 	paddr = virt_to_phys(cpu_addr);
 
 	/* First check to see if we can use the direct map window.  */
@@ -186,12 +189,15 @@
    wrote there.  */
 
 void
-pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, long size, int direction)
+pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, long size,
+		 int direction)
 {
 	struct pci_controler *hose = pdev ? pdev->sysdata : pci_isa_hose;
 	struct pci_iommu_arena *arena;
 	long dma_ofs, npages;
 
+	if (direction == PCI_DMA_NONE)
+		BUG();
 
 	if (dma_addr >= __direct_map_base
 	    && dma_addr < __direct_map_base + __direct_map_size) {
@@ -247,7 +253,8 @@
 	}
 	memset(cpu_addr, 0, size);
 
-	*dma_addrp = pci_map_single(pdev, cpu_addr, size, PCI_DMA_BIDIRECTIONAL);
+	*dma_addrp = pci_map_single(pdev, cpu_addr, size,
+				    PCI_DMA_BIDIRECTIONAL);
 	if (*dma_addrp == 0) {
 		free_pages((unsigned long)cpu_addr, order);
 		return NULL;
@@ -424,13 +431,17 @@
 }
 
 int
-pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, int direction)
+pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
+	   int direction)
 {
 	struct scatterlist *start, *end, *out;
 	struct pci_controler *hose;
 	struct pci_iommu_arena *arena;
 	dma_addr_t max_dma;
 
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
 	/* Fast path single entry scatterlists.  */
 	if (nents == 1) {
 		sg->dma_length = sg->length;
@@ -499,7 +510,8 @@
    above.  */
 
 void
-pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, int direction)
+pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
+	     int direction)
 {
 	struct pci_controler *hose;
 	struct pci_iommu_arena *arena;
@@ -507,6 +519,9 @@
 	dma_addr_t max_dma;
 	dma_addr_t fstart, fend;
 
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
 	if (! alpha_mv.mv_pci_tbi)
 		return;
 
@@ -554,4 +569,34 @@
 		alpha_mv.mv_pci_tbi(hose, fstart, fend);
 
 	DBGA("pci_unmap_sg: %d entries\n", nents - (end - sg));
+}
+
+/* Return whether the given PCI device DMA address mask can be
+   supported properly.  */
+
+int
+pci_dma_supported(struct pci_dev *pdev, dma_addr_t mask)
+{
+	struct pci_controler *hose;
+	struct pci_iommu_arena *arena;
+
+	/* If there exists a direct map, and the mask fits either
+	   MAX_DMA_ADDRESS defined such that GFP_DMA does something
+	   useful, or the total system memory as shifted by the
+	   map base.  */
+	if (__direct_map_size != 0
+	    && (__direct_map_base + MAX_DMA_ADDRESS-IDENT_ADDR-1 <= mask
+		|| __direct_map_base + (max_low_pfn<<PAGE_SHIFT)-1 <= mask))
+		return 1;
+
+	/* Check that we have a scatter-gather arena that fits.  */
+	hose = pdev ? pdev->sysdata : pci_isa_hose;
+	arena = hose->sg_isa;
+	if (arena && arena->dma_base + arena->size <= mask)
+		return 1;
+	arena = hose->sg_pci;
+	if (arena && arena->dma_base + arena->size <= mask)
+		return 1;
+
+	return 0;
 }
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c
--- v2.3.47/linux/arch/alpha/kernel/process.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/alpha/kernel/process.c	Thu Feb 24 22:43:39 2000
@@ -90,55 +90,82 @@
 	}
 }
 
+
+struct halt_info {
+	int mode;
+	char *restart_cmd;
+};
+
 static void
-common_shutdown(int mode, char *restart_cmd)
+common_shutdown_1(void *generic_ptr)
 {
-	/* The following currently only has any effect on SRM.  We should
-	   fix MILO to understand it.  Should be pretty easy.  Also we can
-	   support RESTART2 via the ipc_buffer machinations pictured below,
-	   which SRM ignores.  */
+	struct halt_info *how = (struct halt_info *)generic_ptr;
+	struct percpu_struct *cpup;
+	unsigned long *pflags, flags;
+	int cpuid = smp_processor_id();
+
+	/* No point in taking interrupts anymore. */
+	__cli();
+
+	cpup = (struct percpu_struct *)
+			((unsigned long)hwrpb + hwrpb->processor_offset
+			 + hwrpb->processor_size * cpuid);
+	pflags = &cpup->flags;
+	flags = *pflags;
+
+	/* Clear reason to "default"; clear "bootstrap in progress". */
+	flags &= ~0x00ff0001UL;
+
+#ifdef __SMP__
+	/* Secondaries halt here. */
+	if (cpuid != boot_cpuid) {
+		flags |= 0x00040000UL; /* "remain halted" */
+		*pflags = flags;
+		clear_bit(cpuid, &cpu_present_mask);
+		halt();
+	}
+#endif
 
-	if (alpha_using_srm) {
-		struct percpu_struct *cpup;
-		unsigned long flags;
-	
-		cpup = (struct percpu_struct *)
-		  ((unsigned long)hwrpb + hwrpb->processor_offset);
-
-		flags = cpup->flags;
-
-		/* Clear reason to "default"; clear "bootstrap in progress". */
-		flags &= ~0x00ff0001UL;
-
-		if (mode == LINUX_REBOOT_CMD_RESTART) {
-			if (!restart_cmd) {
-				flags |= 0x00020000UL; /* "cold bootstrap" */
-				cpup->ipc_buffer[0] = 0;
-			} else {
-				flags |=  0x00030000UL; /* "warm bootstrap" */
-				strncpy((char *)cpup->ipc_buffer, restart_cmd,
-					sizeof(cpup->ipc_buffer));
-			}
+	if (how->mode == LINUX_REBOOT_CMD_RESTART) {
+		if (!how->restart_cmd) {
+			flags |= 0x00020000UL; /* "cold bootstrap" */
 		} else {
-			flags |=  0x00040000UL; /* "remain halted" */
+			/* For SRM, we could probably set environment
+			   variables to get this to work.  We'd have to
+			   delay this until after srm_paging_stop unless
+			   we ever got srm_fixup working.
+
+			   At the moment, SRM will use the last boot device,
+			   but the file and flags will be the defaults, when
+			   doing a "warm" bootstrap.  */
+			flags |= 0x00030000UL; /* "warm bootstrap" */
 		}
-			
-		cpup->flags = flags;					       
-		mb();						
+	} else {
+		flags |= 0x00040000UL; /* "remain halted" */
+	}
+	*pflags = flags;
 
-		/* reset_for_srm(); */
-		set_hae(srm_hae);
+#ifdef __SMP__
+	/* Wait for the secondaries to halt. */
+	clear_bit(boot_cpuid, &cpu_present_mask);
+	while (cpu_present_mask)
+		barrier();
+#endif
 
+        /* If booted from SRM, reset some of the original environment. */
+	if (alpha_using_srm) {
 #ifdef CONFIG_DUMMY_CONSOLE
-		/* This has the effect of reseting the VGA video origin.  */
+		/* This has the effect of resetting the VGA video origin.  */
 		take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
 #endif
+		/* reset_for_srm(); */
+		set_hae(srm_hae);
 	}
 
 	if (alpha_mv.kill_arch)
-		alpha_mv.kill_arch(mode);
+		alpha_mv.kill_arch(how->mode);
 
-	if (!alpha_using_srm && mode != LINUX_REBOOT_CMD_RESTART) {
+	if (! alpha_using_srm && how->mode != LINUX_REBOOT_CMD_RESTART) {
 		/* Unfortunately, since MILO doesn't currently understand
 		   the hwrpb bits above, we can't reliably halt the 
 		   processor and keep it halted.  So just loop.  */
@@ -149,6 +176,18 @@
 		srm_paging_stop();
 
 	halt();
+}
+
+static void
+common_shutdown(int mode, char *restart_cmd)
+{
+	struct halt_info args;
+	args.mode = mode;
+	args.restart_cmd = restart_cmd;
+#ifdef __SMP__
+	smp_call_function(common_shutdown_1, &args, 1, 0);
+#endif
+	common_shutdown_1(&args);
 }
 
 void
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/proto.h linux/arch/alpha/kernel/proto.h
--- v2.3.47/linux/arch/alpha/kernel/proto.h	Sun Feb 20 21:12:38 2000
+++ linux/arch/alpha/kernel/proto.h	Thu Feb 24 22:43:39 2000
@@ -74,13 +74,14 @@
 
 /* setup.c */
 extern unsigned long srm_hae;
+extern int boot_cpuid;
 
 /* smp.c */
 extern void setup_smp(void);
 extern int smp_info(char *buffer);
 extern void handle_ipi(struct pt_regs *);
 extern void smp_percpu_timer_interrupt(struct pt_regs *);
-extern int smp_boot_cpuid;
+extern unsigned long cpu_present_mask;
 
 /* bios32.c */
 /* extern void reset_for_srm(void); */
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/semaphore.c linux/arch/alpha/kernel/semaphore.c
--- v2.3.47/linux/arch/alpha/kernel/semaphore.c	Thu Feb 10 17:11:02 2000
+++ linux/arch/alpha/kernel/semaphore.c	Thu Feb 24 22:36:04 2000
@@ -173,7 +173,7 @@
 			"	subl	%0,1,%0\n"
 			"	stl_c	%2,%1\n"
 			"	bne	%2,2f\n"
-			".section .text2,\"ax\"\n"
+			".subsection 2\n"
 			"2:	br	1b\n"
 			".previous"
 			: "=r"(count), "=m"(sem->count), "=r"(tmp)
@@ -226,7 +226,7 @@
 			"	ldah	%0,%3(%0)\n"
 			"	stl_c	%2,%1\n"
 			"	bne	%2,2f\n"
-			".section .text2,\"ax\"\n"
+			".subsection 2\n"
 			"2:	br	1b\n"
 			".previous"
 			: "=r"(count), "=m"(sem->count), "=r"(tmp)
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
--- v2.3.47/linux/arch/alpha/kernel/setup.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/alpha/kernel/setup.c	Thu Feb 24 22:43:39 2000
@@ -50,6 +50,9 @@
 struct hwrpb_struct *hwrpb;
 unsigned long srm_hae;
 
+/* Which processor we booted from.  */
+int boot_cpuid;
+
 #ifdef CONFIG_ALPHA_GENERIC
 struct alpha_machine_vector alpha_mv;
 int alpha_using_srm;
@@ -351,6 +354,7 @@
 	char *type_name, *var_name, *p;
 
 	hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr);
+	boot_cpuid = hard_smp_processor_id();
 
 	/* 
 	 * Locate the command line.
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c
--- v2.3.47/linux/arch/alpha/kernel/smp.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/alpha/kernel/smp.c	Thu Feb 24 22:43:39 2000
@@ -62,11 +62,13 @@
 /* Set to a secondary's cpuid when it comes online.  */
 static unsigned long smp_secondary_alive;
 
-unsigned long cpu_present_mask;	/* Which cpus ids came online.  */
-static unsigned long __cpu_present_mask __initdata = 0; /* cpu reported in the hwrpb */
+/* Which cpus ids came online.  */
+unsigned long cpu_present_mask;
+
+/* cpus reported in the hwrpb */
+static unsigned long hwrpb_cpu_present_mask __initdata = 0;
 
 static int max_cpus = -1;	/* Command-line limitation.  */
-int smp_boot_cpuid;		/* Which processor we booted from.  */
 int smp_num_probed;		/* Internal processor count */
 int smp_num_cpus = 1;		/* Number that came online.  */
 int smp_threads_ready;		/* True once the per process idle is forked. */
@@ -486,10 +488,9 @@
 	struct percpu_struct *cpubase, *cpu;
 	int i;
 
-	smp_boot_cpuid = hard_smp_processor_id();
-	if (smp_boot_cpuid != 0) {
+	if (boot_cpuid != 0) {
 		printk(KERN_WARNING "SMP: Booting off cpu %d instead of 0?\n",
-		       smp_boot_cpuid);
+		       boot_cpuid);
 	}
 
 	if (hwrpb->nr_processors > 1) {
@@ -508,7 +509,7 @@
 			if ((cpu->flags & 0x1cc) == 0x1cc) {
 				smp_num_probed++;
 				/* Assume here that "whami" == index */
-				__cpu_present_mask |= (1L << i);
+				hwrpb_cpu_present_mask |= (1L << i);
 				cpu->pal_revision = boot_cpu_palrev;
 			}
 
@@ -519,12 +520,12 @@
 		}
 	} else {
 		smp_num_probed = 1;
-		__cpu_present_mask = (1L << smp_boot_cpuid);
+		hwrpb_cpu_present_mask = (1L << boot_cpuid);
 	}
-	cpu_present_mask = 1L << smp_boot_cpuid;
+	cpu_present_mask = 1L << boot_cpuid;
 
 	printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n",
-	       smp_num_probed, __cpu_present_mask);
+	       smp_num_probed, hwrpb_cpu_present_mask);
 }
 
 /*
@@ -541,13 +542,13 @@
 	memset(__cpu_logical_map, -1, sizeof(__cpu_logical_map));
 	memset(ipi_data, 0, sizeof(ipi_data));
 
-	__cpu_number_map[smp_boot_cpuid] = 0;
-	__cpu_logical_map[0] = smp_boot_cpuid;
-	current->processor = smp_boot_cpuid;
+	__cpu_number_map[boot_cpuid] = 0;
+	__cpu_logical_map[0] = boot_cpuid;
+	current->processor = boot_cpuid;
 
-	smp_store_cpu_info(smp_boot_cpuid);
+	smp_store_cpu_info(boot_cpuid);
 	smp_tune_scheduling();
-	smp_setup_percpu_timer(smp_boot_cpuid);
+	smp_setup_percpu_timer(boot_cpuid);
 
 	init_idle();
 
@@ -565,10 +566,10 @@
 
 	cpu_count = 1;
 	for (i = 0; i < NR_CPUS; i++) {
-		if (i == smp_boot_cpuid)
+		if (i == boot_cpuid)
 			continue;
 
-		if (((__cpu_present_mask >> i) & 1) == 0)
+		if (((hwrpb_cpu_present_mask >> i) & 1) == 0)
 			continue;
 
 		if (smp_boot_one_cpu(i, cpu_count))
@@ -1023,7 +1024,7 @@
 	"	stl_c	%0,%1\n"
 	"	beq	%0,3f\n"
 	"4:	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"2:	ldl	%0,%1\n"
 	"	subq	%2,1,%2\n"
 	"3:	blt	%2,4b\n"
@@ -1097,7 +1098,7 @@
 	"	stl_c	%1,%0\n"
 	"	beq	%1,6f\n"
 	"4:	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"6:	blt	%3,4b	# debug\n"
 	"	subl	%3,1,%3	# debug\n"
 	"	ldl	%1,%0\n"
@@ -1140,7 +1141,7 @@
 	"	stl_c	%1,%0;"
 	"	beq	%1,6f;"
 	"4:	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"6:	ldl	%1,%0;"
 	"	blt	%2,4b	# debug\n"
 	"	subl	%2,1,%2	# debug\n"
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/sys_cabriolet.c linux/arch/alpha/kernel/sys_cabriolet.c
--- v2.3.47/linux/arch/alpha/kernel/sys_cabriolet.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/alpha/kernel/sys_cabriolet.c	Mon Feb 21 17:38:03 2000
@@ -126,6 +126,30 @@
 	setup_irq(16+4, &isa_cascade_irqaction);
 }
 
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PC164)
+static void
+pc164_device_interrupt(unsigned long v, struct pt_regs *r)
+{
+	/* In theory, the PC164 has the same interrupt hardware as
+	   the other Cabriolet based systems.  However, something 
+	   got screwed up late in the development cycle which broke
+	   the interrupt masking hardware.  Repeat, it is not 
+	   possible to mask and ack interrupts.  At all.
+
+	   In an attempt to work around this, while processing 
+	   interrupts, we do not allow the IPL to drop below what
+	   it is currently.  This prevents the possibility of
+	   recursion.  
+
+	   ??? Another option might be to force all PCI devices
+	   to use edge triggered rather than level triggered
+	   interrupts.  That might be too invasive though.  */
+
+	__min_ipl = getipl();
+	cabriolet_device_interrupt(v, r);
+	__min_ipl = 0;
+}
+#endif
 
 /*
  * The EB66+ is very similar to the EB66 except that it does not have
@@ -379,7 +403,7 @@
 	min_mem_address:	CIA_DEFAULT_MEM_BASE,
 
 	nr_irqs:		35,
-	device_interrupt:	cabriolet_device_interrupt,
+	device_interrupt:	pc164_device_interrupt,
 
 	init_arch:		cia_init_arch,
 	init_irq:		cabriolet_init_irq,
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/sys_dp264.c linux/arch/alpha/kernel/sys_dp264.c
--- v2.3.47/linux/arch/alpha/kernel/sys_dp264.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/alpha/kernel/sys_dp264.c	Thu Feb 24 22:44:17 2000
@@ -33,94 +33,80 @@
 #include "machvec_impl.h"
 
 
+/* Note mask bit is true for ENABLED irqs.  */
 static unsigned long cached_irq_mask;
 
-
-#define TSUNAMI_SET_IRQ_MASK(cpu, value)	\
-do {						\
-	volatile unsigned long *csr;		\
-	csr = &TSUNAMI_cchip->dim##cpu##.csr;	\
-	*csr = (value);				\
-	mb();					\
-	*csr;					\
-} while(0)
-
-static inline void
-do_flush_irq_mask(unsigned long value)
-{
-	switch (TSUNAMI_bootcpu) {
-	case 0:
-		TSUNAMI_SET_IRQ_MASK(0, value);
-		break;
-	case 1:
-		TSUNAMI_SET_IRQ_MASK(1, value);
-		break;
-	case 2:
-		TSUNAMI_SET_IRQ_MASK(2, value);
-		break;
-	case 3:
-		TSUNAMI_SET_IRQ_MASK(3, value);
-		break;
-	}
-}
-
-#ifdef CONFIG_SMP
-static inline void
-do_flush_smp_irq_mask(unsigned long value)
-{
-	extern unsigned long cpu_present_mask;
-	unsigned long other_cpus = cpu_present_mask & ~(1L << TSUNAMI_bootcpu);
-
-	if (other_cpus & 1)
-		TSUNAMI_SET_IRQ_MASK(0, value);
-	if (other_cpus & 2)
-		TSUNAMI_SET_IRQ_MASK(1, value);
-	if (other_cpus & 4)
-		TSUNAMI_SET_IRQ_MASK(2, value);
-	if (other_cpus & 8)
-		TSUNAMI_SET_IRQ_MASK(3, value);
-}
-#endif
-
 static void
-dp264_flush_irq_mask(unsigned long mask)
+tsunami_update_irq_hw(unsigned long mask, unsigned long isa_enable)
 {
-	unsigned long value;
+	register tsunami_cchip *cchip = TSUNAMI_cchip;
+	register int bcpu = boot_cpuid;
 
 #ifdef CONFIG_SMP
-	do_flush_smp_irq_mask(mask);
+	register unsigned long cpm = cpu_present_mask;
+	volatile unsigned long *dim0, *dim1, *dim2, *dim3;
+	unsigned long mask0, mask1, mask2, mask3, maskB, dummy;
+
+	mask0 = mask1 = mask2 = mask3 = mask;
+	maskB = mask | isa_enable;
+	if (bcpu == 0) mask0 = maskB;
+	if (bcpu == 1) mask1 = maskB;
+	if (bcpu == 2) mask2 = maskB;
+	if (bcpu == 3) mask3 = maskB;
+
+	dim0 = &cchip->dim0.csr;
+	dim1 = &cchip->dim1.csr;
+	dim2 = &cchip->dim2.csr;
+	dim3 = &cchip->dim3.csr;
+	if ((cpm & 1) == 0) dim0 = &dummy;
+	if ((cpm & 2) == 0) dim1 = &dummy;
+	if ((cpm & 4) == 0) dim2 = &dummy;
+	if ((cpm & 8) == 0) dim3 = &dummy;
+
+	*dim0 = mask0;
+	*dim1 = mask1;
+	*dim2 = mask2;
+	*dim3 = mask3;
+	mb();
+	*dim0;
+	*dim1;
+	*dim2;
+	*dim3;
+#else
+	volatile unsigned long *dimB = &cchip->dim1.csr;
+	if (bcpu == 0) dimB = &cchip->dim0.csr;
+	if (bcpu == 2) dimB = &cchip->dim2.csr;
+	if (bcpu == 3) dimB = &cchip->dim3.csr;
+	*dimB = mask | isa_enable;
+	mb();
+	*dimB;
 #endif
-
-	value = mask | (1UL << 55) | 0xffff; /* isa irqs always enabled */
-	do_flush_irq_mask(value);
 }
 
-static void
-clipper_flush_irq_mask(unsigned long mask)
+static inline void
+dp264_update_irq_hw(unsigned long mask)
 {
-	unsigned long value;
-
-	value = mask >> 16;
-#ifdef CONFIG_SMP
-	do_flush_smp_irq_mask(value);
-#endif
+	tsunami_update_irq_hw(mask, (1UL << 55) | 0xffff);
+}
 
-	value = value | (1UL << 55); /* master ISA enable */
-	do_flush_irq_mask(value);
+static inline void
+clipper_update_irq_hw(unsigned long mask)
+{
+	tsunami_update_irq_hw(mask, 1UL << 55);
 }
 
 static inline void
 dp264_enable_irq(unsigned int irq)
 {
 	cached_irq_mask |= 1UL << irq;
-	dp264_flush_irq_mask(cached_irq_mask);
+	dp264_update_irq_hw(cached_irq_mask);
 }
 
 static void
 dp264_disable_irq(unsigned int irq)
 {
 	cached_irq_mask &= ~(1UL << irq);
-	dp264_flush_irq_mask(cached_irq_mask);
+	dp264_update_irq_hw(cached_irq_mask);
 }
 
 static unsigned int
@@ -134,14 +120,14 @@
 clipper_enable_irq(unsigned int irq)
 {
 	cached_irq_mask |= 1UL << irq;
-	clipper_flush_irq_mask(cached_irq_mask);
+	clipper_update_irq_hw(cached_irq_mask);
 }
 
 static void
 clipper_disable_irq(unsigned int irq)
 {
 	cached_irq_mask &= ~(1UL << irq);
-	clipper_flush_irq_mask(cached_irq_mask);
+	clipper_update_irq_hw(cached_irq_mask);
 }
 
 static unsigned int
@@ -271,7 +257,7 @@
 	if (alpha_using_srm)
 		alpha_mv.device_interrupt = dp264_srm_device_interrupt;
 
-	dp264_flush_irq_mask(0UL);
+	dp264_update_irq_hw(0UL);
 
 	init_i8259a_irqs();
 	init_rtc_irq();
@@ -289,7 +275,7 @@
 	if (alpha_using_srm)
 		alpha_mv.device_interrupt = clipper_srm_device_interrupt;
 
-	clipper_flush_irq_mask(0UL);
+	clipper_update_irq_hw(0UL);
 
 	init_i8259a_irqs();
 	init_rtc_irq();
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/sys_sio.c linux/arch/alpha/kernel/sys_sio.c
--- v2.3.47/linux/arch/alpha/kernel/sys_sio.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/alpha/kernel/sys_sio.c	Thu Feb 24 22:45:57 2000
@@ -391,7 +391,7 @@
 	nr_irqs:		16,
 	device_interrupt:	isa_device_interrupt,
 
-	init_arch:		lca_init_arch,
+	init_arch:		apecs_init_arch,
 	init_irq:		sio_init_irq,
 	init_rtc:		common_init_rtc,
 	init_pci:		noname_init_pci,
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c
--- v2.3.47/linux/arch/alpha/kernel/time.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/alpha/kernel/time.c	Mon Feb 21 10:56:40 2000
@@ -22,7 +22,6 @@
  *	fixed algorithm in do_gettimeofday() for calculating the precise time
  *	from processor cycle counter (now taking lost_ticks into account)
  */
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v2.3.47/linux/arch/alpha/kernel/traps.c	Tue Dec  7 09:32:40 1999
+++ linux/arch/alpha/kernel/traps.c	Mon Feb 21 17:35:40 2000
@@ -215,8 +215,10 @@
 			/* EV4 does not implement anything except normal
 			   rounding.  Everything else will come here as
 			   an illegal instruction.  Emulate them.  */
-			if (alpha_fp_emul(regs.pc - 4))
+			if (alpha_fp_emul(regs.pc)) {
+				regs.pc += 4;
 				return;
+			}
 		}
 		send_sig(SIGILL, current, 1);
 		break;
diff -u --recursive --new-file v2.3.47/linux/arch/alpha/vmlinux.lds linux/arch/alpha/vmlinux.lds
--- v2.3.47/linux/arch/alpha/vmlinux.lds	Thu Feb 10 17:11:02 2000
+++ linux/arch/alpha/vmlinux.lds	Thu Feb 24 22:36:04 2000
@@ -5,7 +5,6 @@
   . = 0xfffffc0000310000;
   _text = .;
   .text : { *(.text) }
-  .text2 : { *(.text2) }
   _etext = .;
 
   /* Exception table */
diff -u --recursive --new-file v2.3.47/linux/arch/arm/kernel/armksyms.c linux/arch/arm/kernel/armksyms.c
--- v2.3.47/linux/arch/arm/kernel/armksyms.c	Sun Feb 13 19:29:03 2000
+++ linux/arch/arm/kernel/armksyms.c	Thu Feb 24 22:44:47 2000
@@ -165,7 +165,6 @@
 EXPORT_SYMBOL_NOVERS(strchr);
 EXPORT_SYMBOL_NOVERS(strlen);
 EXPORT_SYMBOL_NOVERS(strnlen);
-EXPORT_SYMBOL_NOVERS(strspn);
 EXPORT_SYMBOL_NOVERS(strpbrk);
 EXPORT_SYMBOL_NOVERS(strtok);
 EXPORT_SYMBOL_NOVERS(strrchr);
diff -u --recursive --new-file v2.3.47/linux/arch/arm/mm/consistent.c linux/arch/arm/mm/consistent.c
--- v2.3.47/linux/arch/arm/mm/consistent.c	Wed Feb 16 17:03:51 2000
+++ linux/arch/arm/mm/consistent.c	Thu Feb 24 22:44:47 2000
@@ -23,7 +23,6 @@
 {
 	int order;
 	unsigned long page;
-	struct vm_struct *area;
 	void *ret;
 
 	if (in_interrupt())
@@ -40,15 +39,10 @@
 
 	*dma_handle = virt_to_bus((void *)page);
 
-	area = get_vm_area(size, VM_IOREMAP); /* maybe new type? */
-	if (!area)
-		goto no_area;
-
 	ret = __ioremap(virt_to_phys((void *)page), PAGE_SIZE << order, 0);
 	if (ret)
 		return ret;
 
-no_area:
 	free_pages(page, order);
 no_page:
 	BUG();
diff -u --recursive --new-file v2.3.47/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.3.47/linux/arch/i386/defconfig	Sun Feb 20 21:12:38 2000
+++ linux/arch/i386/defconfig	Sat Feb 26 20:45:15 2000
@@ -109,10 +109,12 @@
 # CONFIG_BLK_DEV_ISAPNP is not set
 CONFIG_BLK_DEV_RZ1000=y
 CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
 # CONFIG_BLK_DEV_IDEDMA_PCI is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
 # CONFIG_BLK_DEV_AEC6210 is not set
 # CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_IDE_CHIPSETS is not set
 # CONFIG_BLK_CPQ_DA is not set
 
@@ -393,6 +395,7 @@
 # CONFIG_WATCHDOG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
+# CONFIG_EFI_RTC is not set
 
 #
 # Video For Linux
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/acpi.c linux/arch/i386/kernel/acpi.c
--- v2.3.47/linux/arch/i386/kernel/acpi.c	Wed Feb 16 17:03:51 2000
+++ linux/arch/i386/kernel/acpi.c	Thu Feb 24 10:11:24 2000
@@ -34,6 +34,7 @@
 #include <linux/spinlock.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
+#include <linux/mm.h>
 #include <linux/pci.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -379,13 +380,14 @@
 				ioremap((unsigned long) addr, table_size);
 		}
 
-		if (!table) {
-			/* ioremap is a pain, it returns NULL if the
-			 * table starts within mapped physical memory.
-			 * Hopefully, no table straddles a mapped/unmapped
-			 * physical memory boundary, ugh
+		if (!table && addr < virt_to_phys(high_memory)) {
+			/* sometimes we see ACPI tables in low memory
+			 * and not reserved by the memory map (E820) code,
+			 * who is at fault for this?  BIOS?
 			 */
-			table = (struct acpi_table*) phys_to_virt(addr);
+			printk(KERN_ERR
+			       "ACPI: unreserved table memory @ 0x%p!\n",
+			       (void*) addr);
 		}
 	}
 	return table;
@@ -933,9 +935,9 @@
 	int status = 0;
 	
 	if (state == ACPI_D0)
-		status = pm_send_request(PM_RESUME, (void*) state);
+		status = pm_send_all(PM_RESUME, (void*) state);
 	else
-		status = pm_send_request(PM_SUSPEND, (void*) state);
+		status = pm_send_all(PM_SUSPEND, (void*) state);
 
 	return status;
 }
@@ -1333,10 +1335,7 @@
 
 	if (acpi_claim_ioports(acpi_facp)) {
 		printk(KERN_ERR "ACPI: I/O port allocation failed\n");
-		if (pci_driver_registered)
-			pci_unregister_driver(&acpi_driver);
-		acpi_destroy_tables();
-		return -ENODEV;
+		goto err_out;
 	}
 
 	if (acpi_facp->sci_int
@@ -1347,12 +1346,7 @@
 			   acpi_facp)) {
 		printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n",
 		       acpi_facp->sci_int);
-
-		if (pci_driver_registered)
-			pci_unregister_driver(&acpi_driver);
-		acpi_destroy_tables();
-
-		return -ENODEV;
+		goto err_out;
 	}
 
 	acpi_sysctl = register_sysctl_table(acpi_dir_table, 1);
@@ -1379,6 +1373,13 @@
 		pm_idle = acpi_idle;
 
 	return 0;
+
+err_out:
+	if (pci_driver_registered)
+		pci_unregister_driver(&acpi_driver);
+	acpi_destroy_tables();
+
+	return -ENODEV;
 }
 
 /*
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c
--- v2.3.47/linux/arch/i386/kernel/apm.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/i386/kernel/apm.c	Thu Feb 24 22:41:16 2000
@@ -333,7 +333,7 @@
 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
 static struct apm_user *	user_list = NULL;
 
-static char			driver_version[] = "1.12";	/* no spaces */
+static char			driver_version[] = "1.13";	/* no spaces */
 
 static char *	apm_event_name[] = {
 	"system standby",
@@ -590,7 +590,11 @@
 					continue;
 				if (hlt_counter)
 					continue;
-				asm volatile("sti ; hlt" : : : "memory");
+				asm volatile("cli" : : : "memory");
+				if (!current->need_resched)
+					asm volatile("sti ; hlt" : : : "memory");
+				else
+					asm volatile("sti" : : : "memory");
 				continue;
 			}
 
@@ -635,7 +639,7 @@
 	 */
 #ifdef CONFIG_SMP
 	/* Some bioses don't like being called from CPU != 0 */
-	while (cpu_number_map[smp_processor_id()] != 0) {
+	while (cpu_number_map(smp_processor_id()) != 0) {
 		kernel_thread(apm_magic, NULL,
 			CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
 		schedule();
@@ -916,7 +920,7 @@
 	case APM_CRITICAL_SUSPEND:
 	case APM_USER_SUSPEND:
 		/* map all suspends to ACPI D3 */
-		if (pm_send_request(PM_SUSPEND, (void *)3)) {
+		if (pm_send_all(PM_SUSPEND, (void *)3)) {
 			if (apm_bios_info.version > 0x100)
 				apm_set_power_state(APM_STATE_REJECT);
 			return 0;
@@ -925,7 +929,7 @@
 	case APM_NORMAL_RESUME:
 	case APM_CRITICAL_RESUME:
 		/* map all resumes to ACPI D0 */
-		(void) pm_send_request(PM_RESUME, (void *)0);
+		(void) pm_send_all(PM_RESUME, (void *)0);
 		break;
 	}
 
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v2.3.47/linux/arch/i386/kernel/entry.S	Thu Feb 10 17:11:03 2000
+++ linux/arch/i386/kernel/entry.S	Mon Feb 21 10:59:36 2000
@@ -181,6 +181,8 @@
 	call SYMBOL_NAME(schedule_tail)
 	addl $4, %esp
 	GET_CURRENT(%ebx)
+	testb $0x20,flags(%ebx)		# PF_TRACESYS
+	jne tracesys_exit
 	jmp	ret_from_sys_call
 
 /*
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- v2.3.47/linux/arch/i386/kernel/i386_ksyms.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/i386/kernel/i386_ksyms.c	Thu Feb 24 22:41:16 2000
@@ -144,6 +144,4 @@
 
 EXPORT_SYMBOL(get_wchan);
 
-
-EXPORT_SYMBOL(local_bh_count); 
-EXPORT_SYMBOL(local_irq_count); 
+EXPORT_SYMBOL(irq_stat);
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/i8259.c linux/arch/i386/kernel/i8259.c
--- v2.3.47/linux/arch/i386/kernel/i8259.c	Sat Feb 12 11:22:10 2000
+++ linux/arch/i386/kernel/i8259.c	Thu Feb 24 22:41:16 2000
@@ -127,11 +127,14 @@
  * moves to arch independent land
  */
 
-void enable_8259A_irq(unsigned int irq);
-void disable_8259A_irq(unsigned int irq);
+static spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
+
+static void end_8259A_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & IRQ_DISABLED))
+		enable_8259A_irq(irq);
+}
 
-/* shutdown is same as "disable" */
-#define end_8259A_irq		enable_8259A_irq
 #define shutdown_8259A_irq	disable_8259A_irq
 
 void mask_and_ack_8259A(unsigned int);
@@ -149,7 +152,8 @@
 	enable_8259A_irq,
 	disable_8259A_irq,
 	mask_and_ack_8259A,
-	end_8259A_irq
+	end_8259A_irq,
+	NULL
 };
 
 /*
@@ -183,30 +187,45 @@
 void disable_8259A_irq(unsigned int irq)
 {
 	unsigned int mask = 1 << irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8259A_lock, flags);
 	cached_irq_mask |= mask;
 	if (irq & 8)
 		outb(cached_A1,0xA1);
 	else
 		outb(cached_21,0x21);
+	spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
 void enable_8259A_irq(unsigned int irq)
 {
 	unsigned int mask = ~(1 << irq);
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8259A_lock, flags);
 	cached_irq_mask &= mask;
 	if (irq & 8)
 		outb(cached_A1,0xA1);
 	else
 		outb(cached_21,0x21);
+	spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
 int i8259A_irq_pending(unsigned int irq)
 {
 	unsigned int mask = 1<<irq;
+	unsigned long flags;
+	int ret;
 
+	spin_lock_irqsave(&i8259A_lock, flags);
 	if (irq < 8)
-		return (inb(0x20) & mask);
-	return (inb(0xA0) & (mask >> 8));
+		ret = inb(0x20) & mask;
+	else
+		ret = inb(0xA0) & (mask >> 8);
+	spin_unlock_irqrestore(&i8259A_lock, flags);
+
+	return ret;
 }
 
 void make_8259A_irq(unsigned int irq)
@@ -247,7 +266,9 @@
 void mask_and_ack_8259A(unsigned int irq)
 {
 	unsigned int irqmask = 1 << irq;
+	unsigned long flags;
 
+	spin_lock_irqsave(&i8259A_lock, flags);
 	/*
 	 * Lightweight spurious IRQ detection. We do not want
 	 * to overdo spurious IRQ handling - it's usually a sign
@@ -278,6 +299,7 @@
 		outb(cached_21,0x21);
 		outb(0x20,0x20);	/* 'generic EOI' to master */
 	}
+	spin_unlock_irqrestore(&i8259A_lock, flags);
 	return;
 
 spurious_8259A_irq:
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
--- v2.3.47/linux/arch/i386/kernel/io_apic.c	Wed Feb 16 17:03:51 2000
+++ linux/arch/i386/kernel/io_apic.c	Thu Feb 24 22:41:16 2000
@@ -28,6 +28,8 @@
 #include <asm/smp.h>
 #include <asm/desc.h>
 
+static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
+
 /*
  * # of IO-APICs and # of IRQ routing registers
  */
@@ -87,9 +89,8 @@
 	entry->pin = pin;
 }
 
-#define DO_ACTION(name,R,ACTION, FINAL)					\
+#define __DO_ACTION(name,R,ACTION, FINAL)				\
 									\
-static void name##_IO_APIC_irq(unsigned int irq)			\
 {									\
 	int pin;							\
 	struct irq_pin_list *entry = irq_2_pin + irq;			\
@@ -109,8 +110,31 @@
 	FINAL;								\
 }
 
-DO_ACTION( mask,    0, |= 0x00010000, io_apic_sync(entry->apic))/* mask = 1 */
-DO_ACTION( unmask,  0, &= 0xfffeffff, )				/* mask = 0 */
+#define DO_ACTION(name,R,ACTION, FINAL)					\
+									\
+static void name##_IO_APIC_irq(unsigned int irq)			\
+__DO_ACTION(name,R,ACTION, FINAL)
+
+DO_ACTION( __mask,    0, |= 0x00010000, io_apic_sync(entry->apic))/* mask = 1 */
+DO_ACTION( __unmask,  0, &= 0xfffeffff, )				/* mask = 0 */
+
+static void mask_IO_APIC_irq (unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	__mask_IO_APIC_irq(irq);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
+static void unmask_IO_APIC_irq (unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	__unmask_IO_APIC_irq(irq);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+}
 
 void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
 {
@@ -537,7 +561,7 @@
 		entry.delivery_mode = dest_LowestPrio;
 		entry.dest_mode = 1;			/* logical delivery */
 		entry.mask = 0;				/* enable IRQ */
-		entry.dest.logical.logical_dest = APIC_ALL_CPUS; /* all CPUs */
+		entry.dest.logical.logical_dest = APIC_ALL_CPUS;
 
 		idx = find_irq_entry(apic,pin,mp_INT);
 		if (idx == -1) {
@@ -1026,16 +1050,16 @@
 
 static int __init nmi_irq_works(void)
 {
-	atomic_t tmp[NR_CPUS];
+	irq_cpustat_t tmp[NR_CPUS];
 	int j, cpu;
 
-	memcpy(tmp, nmi_counter, sizeof(tmp));
+	memcpy(tmp, irq_stat, sizeof(tmp));
 	sti();
 	mdelay(50);
 
 	for (j = 0; j < smp_num_cpus; j++) {
 		cpu = cpu_logical_map(j);
-		if (atomic_read(nmi_counter+cpu) - atomic_read(tmp+cpu) <= 3) {
+		if (atomic_read(&nmi_counter(cpu)) - atomic_read(&tmp[cpu].__nmi_counter) <= 3) {
 			printk("CPU#%d NMI appears to be stuck.\n", cpu);
 			return 0;
 		}
@@ -1055,14 +1079,9 @@
  * that was delayed but this is now handled in the device
  * independent code.
  */
-static void enable_edge_ioapic_irq(unsigned int irq)
-{
-	unmask_IO_APIC_irq(irq);
-}
+#define enable_edge_ioapic_irq unmask_IO_APIC_irq
 
-static void disable_edge_ioapic_irq(unsigned int irq)
-{
-}
+static void disable_edge_ioapic_irq (unsigned int irq) { /* nothing */ }
 
 /*
  * Starting up a edge-triggered IO-APIC interrupt is
@@ -1077,12 +1096,17 @@
 static unsigned int startup_edge_ioapic_irq(unsigned int irq)
 {
 	int was_pending = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
 	if (irq < 16) {
 		disable_8259A_irq(irq);
 		if (i8259A_irq_pending(irq))
 			was_pending = 1;
 	}
-	enable_edge_ioapic_irq(irq);
+	__unmask_IO_APIC_irq(irq);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
 	return was_pending;
 }
 
@@ -1093,14 +1117,15 @@
  * interrupt for real. This prevents IRQ storms from unhandled
  * devices.
  */
-void static ack_edge_ioapic_irq(unsigned int irq)
+static void ack_edge_ioapic_irq(unsigned int irq)
 {
 	if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
 					== (IRQ_PENDING | IRQ_DISABLED))
 		mask_IO_APIC_irq(irq);
 	ack_APIC_irq();
 }
-void static end_edge_ioapic_irq(unsigned int i){}
+
+static void end_edge_ioapic_irq (unsigned int i) { /* nothing */ }
 
 
 /*
@@ -1108,23 +1133,46 @@
  * and shutting down and starting up the interrupt
  * is the same as enabling and disabling them -- except
  * with a startup need to return a "was pending" value.
+ *
+ * Level triggered interrupts are special because we
+ * do not touch any IO-APIC register while handling
+ * them. We ack the APIC in the end-IRQ handler, not
+ * in the start-IRQ-handler. Protection against reentrance
+ * from the same interrupt is still provided, both by the
+ * generic IRQ layer and by the fact that an unacked local
+ * APIC does not accept IRQs.
  */
-static unsigned int startup_level_ioapic_irq(unsigned int irq)
+static unsigned int startup_level_ioapic_irq (unsigned int irq)
 {
 	unmask_IO_APIC_irq(irq);
+
 	return 0; /* don't check for pending */
 }
 
 #define shutdown_level_ioapic_irq	mask_IO_APIC_irq
 #define enable_level_ioapic_irq		unmask_IO_APIC_irq
 #define disable_level_ioapic_irq	mask_IO_APIC_irq
-#define end_level_ioapic_irq		unmask_IO_APIC_irq	
-void static mask_and_ack_level_ioapic_irq(unsigned int i)
+
+static void end_level_ioapic_irq (unsigned int i)
 {
-	mask_IO_APIC_irq(i);
 	ack_APIC_irq();
 }
 
+static void mask_and_ack_level_ioapic_irq (unsigned int i) { /* nothing */ }
+
+static void set_ioapic_affinity (unsigned int irq, unsigned int mask)
+{
+	unsigned long flags;
+	/*
+	 * Only the first 8 bits are valid.
+	 */
+	mask = mask << 24;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	__DO_ACTION( target,  1, = mask, )
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
 /*
  * Level and edge triggered IO-APIC interrupts need different handling,
  * so we use two separate IRQ descriptors. Edge triggered IRQs can be
@@ -1141,7 +1189,8 @@
 	enable_edge_ioapic_irq,
 	disable_edge_ioapic_irq,
 	ack_edge_ioapic_irq,
-	end_edge_ioapic_irq
+	end_edge_ioapic_irq,
+	set_ioapic_affinity,
 };
 
 static struct hw_interrupt_type ioapic_level_irq_type = {
@@ -1151,7 +1200,8 @@
 	enable_level_ioapic_irq,
 	disable_level_ioapic_irq,
 	mask_and_ack_level_ioapic_irq,
-	end_level_ioapic_irq
+	end_level_ioapic_irq,
+	set_ioapic_affinity,
 };
 
 static inline void init_IO_APIC_traps(void)
@@ -1185,12 +1235,12 @@
 	}
 }
 
-void static ack_lapic_irq (unsigned int irq)
+static void ack_lapic_irq (unsigned int irq)
 {
 	ack_APIC_irq();
 }
 
-void static end_lapic_irq (unsigned int i) { /* nothing */ }
+static void end_lapic_irq (unsigned int i) { /* nothing */ }
 
 static struct hw_interrupt_type lapic_irq_type = {
 	"local-APIC-edge",
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.3.47/linux/arch/i386/kernel/irq.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/i386/kernel/irq.c	Thu Feb 24 22:41:16 2000
@@ -31,21 +31,20 @@
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
 #include <linux/irq.h>
+#include <linux/proc_fs.h>
+#include <linux/irq.h>
 
 #include <asm/io.h>
 #include <asm/smp.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
+#include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 #include <asm/delay.h>
 #include <asm/desc.h>
 #include <asm/irq.h>
 
 
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
-
-extern atomic_t nmi_counter[NR_CPUS];
 
 /*
  * Linux has a controller-independent x86 interrupt architecture.
@@ -63,17 +62,15 @@
  * interrupt controllers, without having to do assembly magic.
  */
 
-/*
- * Micro-access to controllers is serialized over the whole
- * system. We never hold this lock when we call the actual
- * IRQ handler.
- */
-spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
+irq_cpustat_t irq_stat [NR_CPUS];
+
 /*
  * Controller mappings for all interrupt sources:
  */
 irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
-				{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, }};
+	{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
+
+static void register_irq_proc (unsigned int irq);
 
 /*
  * Special irq handlers.
@@ -164,7 +161,7 @@
 	p += sprintf(p, "NMI: ");
 	for (j = 0; j < smp_num_cpus; j++)
 		p += sprintf(p, "%10u ",
-			atomic_read(nmi_counter+cpu_logical_map(j)));
+			atomic_read(&nmi_counter(cpu_logical_map(j))));
 	p += sprintf(p, "\n");
 #if CONFIG_SMP
 	p += sprintf(p, "LOC: ");
@@ -186,7 +183,6 @@
 #ifdef CONFIG_SMP
 unsigned char global_irq_holder = NO_PROC_ID;
 unsigned volatile int global_irq_lock;
-atomic_t global_irq_count;
 
 static void show(char * str)
 {
@@ -196,9 +192,9 @@
 
 	printk("\n%s, CPU %d:\n", str, cpu);
 	printk("irq:  %d [%d %d]\n",
-		atomic_read(&global_irq_count), local_irq_count[0], local_irq_count[1]);
+		irqs_running(), local_irq_count(0), local_irq_count(1));
 	printk("bh:   %d [%d %d]\n",
-		spin_is_locked(&global_bh_lock) ? 1 : 0, local_bh_count[0], local_bh_count[1]);
+		spin_is_locked(&global_bh_lock) ? 1 : 0, local_bh_count(0), local_bh_count(1));
 	stack = (unsigned long *) &stack;
 	for (i = 40; i ; i--) {
 		unsigned long x = *++stack;
@@ -248,10 +244,9 @@
 		 * for bottom half handlers unless we're
 		 * already executing in one..
 		 */
-		if (!atomic_read(&global_irq_count)) {
-			if (local_bh_count[cpu] || !spin_is_locked(&global_bh_lock))
+		if (!irqs_running())
+			if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
 				break;
-		}
 
 		/* Duh, we have to loop. Release the lock to avoid deadlocks */
 		clear_bit(0,&global_irq_lock);
@@ -264,11 +259,11 @@
 			__sti();
 			SYNC_OTHER_CORES(cpu);
 			__cli();
-			if (atomic_read(&global_irq_count))
+			if (irqs_running())
 				continue;
 			if (global_irq_lock)
 				continue;
-			if (!local_bh_count[cpu] && spin_is_locked(&global_bh_lock))
+			if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
 				continue;
 			if (!test_and_set_bit(0,&global_irq_lock))
 				break;
@@ -285,7 +280,7 @@
  */
 void synchronize_irq(void)
 {
-	if (atomic_read(&global_irq_count)) {
+	if (irqs_running()) {
 		/* Stupid approach */
 		cli();
 		sti();
@@ -338,7 +333,7 @@
 	if (flags & (1 << EFLAGS_IF_SHIFT)) {
 		int cpu = smp_processor_id();
 		__cli();
-		if (!local_irq_count[cpu])
+		if (!local_irq_count(cpu))
 			get_irqlock(cpu);
 	}
 }
@@ -347,7 +342,7 @@
 {
 	int cpu = smp_processor_id();
 
-	if (!local_irq_count[cpu])
+	if (!local_irq_count(cpu))
 		release_irqlock(cpu);
 	__sti();
 }
@@ -364,6 +359,7 @@
 	int retval;
 	int local_enabled;
 	unsigned long flags;
+	int cpu = smp_processor_id();
 
 	__save_flags(flags);
 	local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1;
@@ -371,10 +367,10 @@
 	retval = 2 + local_enabled;
 
 	/* check for global flags if we're not in an interrupt */
-	if (!local_irq_count[smp_processor_id()]) {
+	if (!local_irq_count(cpu)) {
 		if (local_enabled)
 			retval = 1;
-		if (global_irq_holder == (unsigned char) smp_processor_id())
+		if (global_irq_holder == cpu)
 			retval = 0;
 	}
 	return retval;
@@ -442,16 +438,17 @@
  * hardware disable after having gotten the irq
  * controller lock. 
  */
-void disable_irq_nosync(unsigned int irq)
+void inline disable_irq_nosync(unsigned int irq)
 {
+	irq_desc_t *desc = irq_desc + irq;
 	unsigned long flags;
 
-	spin_lock_irqsave(&irq_controller_lock, flags);
-	if (!irq_desc[irq].depth++) {
-		irq_desc[irq].status |= IRQ_DISABLED;
-		irq_desc[irq].handler->disable(irq);
+	spin_lock_irqsave(&desc->lock, flags);
+	if (!desc->depth++) {
+		desc->status |= IRQ_DISABLED;
+		desc->handler->disable(irq);
 	}
-	spin_unlock_irqrestore(&irq_controller_lock, flags);
+	spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 /*
@@ -462,7 +459,7 @@
 {
 	disable_irq_nosync(irq);
 
-	if (!local_irq_count[smp_processor_id()]) {
+	if (!local_irq_count(smp_processor_id())) {
 		do {
 			barrier();
 		} while (irq_desc[irq].status & IRQ_INPROGRESS);
@@ -471,28 +468,29 @@
 
 void enable_irq(unsigned int irq)
 {
+	irq_desc_t *desc = irq_desc + irq;
 	unsigned long flags;
 
-	spin_lock_irqsave(&irq_controller_lock, flags);
-	switch (irq_desc[irq].depth) {
+	spin_lock_irqsave(&desc->lock, flags);
+	switch (desc->depth) {
 	case 1: {
-		unsigned int status = irq_desc[irq].status & ~IRQ_DISABLED;
-		irq_desc[irq].status = status;
+		unsigned int status = desc->status & ~IRQ_DISABLED;
+		desc->status = status;
 		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
-			irq_desc[irq].status = status | IRQ_REPLAY;
-			hw_resend_irq(irq_desc[irq].handler,irq);
+			desc->status = status | IRQ_REPLAY;
+			hw_resend_irq(desc->handler,irq);
 		}
-		irq_desc[irq].handler->enable(irq);
+		desc->handler->enable(irq);
 		/* fall-through */
 	}
 	default:
-		irq_desc[irq].depth--;
+		desc->depth--;
 		break;
 	case 0:
 		printk("enable_irq() unbalanced from %p\n",
 		       __builtin_return_address(0));
 	}
-	spin_unlock_irqrestore(&irq_controller_lock, flags);
+	spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 /*
@@ -514,13 +512,12 @@
 	 */
 	int irq = regs.orig_eax & 0xff; /* high bits used in ret_from_ code  */
 	int cpu = smp_processor_id();
-	irq_desc_t *desc;
+	irq_desc_t *desc = irq_desc + irq;
 	struct irqaction * action;
 	unsigned int status;
 
 	kstat.irqs[cpu][irq]++;
-	desc = irq_desc + irq;
-	spin_lock(&irq_controller_lock);
+	spin_lock(&desc->lock);
 	desc->handler->ack(irq);
 	/*
 	   REPLAY is when Linux resends an IRQ that was dropped earlier
@@ -540,7 +537,6 @@
 		status |= IRQ_INPROGRESS; /* we are handling it */
 	}
 	desc->status = status;
-	spin_unlock(&irq_controller_lock);
 
 	/*
 	 * If there is no IRQ handler or it was disabled, exit early.
@@ -549,7 +545,7 @@
 	   will take care of it.
 	 */
 	if (!action)
-		return 1;
+		goto out;
 
 	/*
 	 * Edge triggered interrupts need to remember
@@ -562,20 +558,24 @@
 	 * SMP environment.
 	 */
 	for (;;) {
+		spin_unlock(&desc->lock);
 		handle_IRQ_event(irq, &regs, action);
-		spin_lock(&irq_controller_lock);
+		spin_lock(&desc->lock);
 		
 		if (!(desc->status & IRQ_PENDING))
 			break;
 		desc->status &= ~IRQ_PENDING;
-		spin_unlock(&irq_controller_lock);
 	}
 	desc->status &= ~IRQ_INPROGRESS;
-	if (!(desc->status & IRQ_DISABLED))
-		desc->handler->end(irq);
-	spin_unlock(&irq_controller_lock);
+out:
+	/*
+	 * The ->end() handler has to deal with interrupts which got
+	 * disabled while the handler was running.
+	 */
+	desc->handler->end(irq);
+	spin_unlock(&desc->lock);
 
-	if (softirq_state[cpu].active&softirq_state[cpu].mask)
+	if (softirq_state[cpu].active & softirq_state[cpu].mask)
 		do_softirq();
 	return 1;
 }
@@ -627,14 +627,16 @@
 		
 void free_irq(unsigned int irq, void *dev_id)
 {
+	irq_desc_t *desc;
 	struct irqaction **p;
 	unsigned long flags;
 
 	if (irq >= NR_IRQS)
 		return;
 
-	spin_lock_irqsave(&irq_controller_lock,flags);
-	p = &irq_desc[irq].action;
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
 	for (;;) {
 		struct irqaction * action = *p;
 		if (action) {
@@ -645,22 +647,22 @@
 
 			/* Found it - now remove it from the list of entries */
 			*pp = action->next;
-			if (!irq_desc[irq].action) {
-				irq_desc[irq].status |= IRQ_DISABLED;
-				irq_desc[irq].handler->shutdown(irq);
+			if (!desc->action) {
+				desc->status |= IRQ_DISABLED;
+				desc->handler->shutdown(irq);
 			}
-			spin_unlock_irqrestore(&irq_controller_lock,flags);
+			spin_unlock_irqrestore(&desc->lock,flags);
 
 #ifdef CONFIG_SMP
 			/* Wait to make sure it's not being used on another CPU */
-			while (irq_desc[irq].status & IRQ_INPROGRESS)
+			while (desc->status & IRQ_INPROGRESS)
 				barrier();
 #endif
 			kfree(action);
 			return;
 		}
 		printk("Trying to free free IRQ%d\n",irq);
-		spin_unlock_irqrestore(&irq_controller_lock,flags);
+		spin_unlock_irqrestore(&desc->lock,flags);
 		return;
 	}
 }
@@ -676,21 +678,43 @@
 unsigned long probe_irq_on(void)
 {
 	unsigned int i;
-	unsigned long delay;
+	irq_desc_t *desc;
 	unsigned long val;
+	unsigned long delay;
+
+	/* 
+	 * something may have generated an irq long ago and we want to
+	 * flush such a longstanding irq before considering it as spurious. 
+	 */
+	for (i = NR_IRQS-1; i > 0; i--)  {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!irq_desc[i].action) 
+			irq_desc[i].handler->startup(i);
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/* Wait for longstanding interrupts to trigger. */
+	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
+		/* about 20ms delay */ synchronize_irq();
 
 	/*
-	 * first, enable any unassigned irqs
+	 * enable any unassigned irqs
+	 * (we must startup again here because if a longstanding irq
+	 * happened in the previous stage, it may have masked itself)
 	 */
-	spin_lock_irq(&irq_controller_lock);
 	for (i = NR_IRQS-1; i > 0; i--) {
-		if (!irq_desc[i].action) {
-			irq_desc[i].status |= IRQ_AUTODETECT | IRQ_WAITING;
-			if(irq_desc[i].handler->startup(i))
-				irq_desc[i].status |= IRQ_PENDING;
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!desc->action) {
+			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
+			if (desc->handler->startup(i))
+				desc->status |= IRQ_PENDING;
 		}
+		spin_unlock_irq(&desc->lock);
 	}
-	spin_unlock_irq(&irq_controller_lock);
 
 	/*
 	 * Wait for spurious interrupts to trigger
@@ -702,24 +726,24 @@
 	 * Now filter out any obviously spurious interrupts
 	 */
 	val = 0;
-	spin_lock_irq(&irq_controller_lock);
-	for (i=0; i<NR_IRQS; i++) {
-		unsigned int status = irq_desc[i].status;
-
-		if (!(status & IRQ_AUTODETECT))
-			continue;
-		
-		/* It triggered already - consider it spurious. */
-		if (!(status & IRQ_WAITING)) {
-			irq_desc[i].status = status & ~IRQ_AUTODETECT;
-			irq_desc[i].handler->shutdown(i);
-			continue;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			/* It triggered already - consider it spurious. */
+			if (!(status & IRQ_WAITING)) {
+				desc->status = status & ~IRQ_AUTODETECT;
+				desc->handler->shutdown(i);
+			} else
+				if (i < 32)
+					val |= 1 << i;
 		}
-
-		if (i < 32)
-			val |= 1 << i;
+		spin_unlock_irq(&desc->lock);
 	}
-	spin_unlock_irq(&irq_controller_lock);
 
 	return val;
 }
@@ -734,20 +758,22 @@
 	unsigned int mask;
 
 	mask = 0;
-	spin_lock_irq(&irq_controller_lock);
 	for (i = 0; i < 16; i++) {
-		unsigned int status = irq_desc[i].status;
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
 
-		if (!(status & IRQ_AUTODETECT))
-			continue;
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
 
-		if (!(status & IRQ_WAITING))
-			mask |= 1 << i;
+		if (status & IRQ_AUTODETECT) {
+			if (!(status & IRQ_WAITING))
+				mask |= 1 << i;
 
-		irq_desc[i].status = status & ~IRQ_AUTODETECT;
-		irq_desc[i].handler->shutdown(i);
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
+		}
+		spin_unlock_irq(&desc->lock);
 	}
-	spin_unlock_irq(&irq_controller_lock);
 
 	return mask & val;
 }
@@ -762,22 +788,24 @@
 
 	nr_irqs = 0;
 	irq_found = 0;
-	spin_lock_irq(&irq_controller_lock);
-	for (i=0; i<NR_IRQS; i++) {
-		unsigned int status = irq_desc[i].status;
-
-		if (!(status & IRQ_AUTODETECT))
-			continue;
-
-		if (!(status & IRQ_WAITING)) {
-			if (!nr_irqs)
-				irq_found = i;
-			nr_irqs++;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			if (!(status & IRQ_WAITING)) {
+				if (!nr_irqs)
+					irq_found = i;
+				nr_irqs++;
+			}
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
 		}
-		irq_desc[i].status = status & ~IRQ_AUTODETECT;
-		irq_desc[i].handler->shutdown(i);
+		spin_unlock_irq(&desc->lock);
 	}
-	spin_unlock_irq(&irq_controller_lock);
 
 	if (nr_irqs > 1)
 		irq_found = -irq_found;
@@ -788,8 +816,9 @@
 int setup_irq(unsigned int irq, struct irqaction * new)
 {
 	int shared = 0;
-	struct irqaction *old, **p;
 	unsigned long flags;
+	struct irqaction *old, **p;
+	irq_desc_t *desc = irq_desc + irq;
 
 	/*
 	 * Some drivers like serial.c use request_irq() heavily,
@@ -811,12 +840,12 @@
 	/*
 	 * The following block of code has to be executed atomically
 	 */
-	spin_lock_irqsave(&irq_controller_lock,flags);
-	p = &irq_desc[irq].action;
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
 	if ((old = *p) != NULL) {
 		/* Can't share interrupts unless both agree to */
 		if (!(old->flags & new->flags & SA_SHIRQ)) {
-			spin_unlock_irqrestore(&irq_controller_lock,flags);
+			spin_unlock_irqrestore(&desc->lock,flags);
 			return -EBUSY;
 		}
 
@@ -831,11 +860,171 @@
 	*p = new;
 
 	if (!shared) {
-		irq_desc[irq].depth = 0;
-		irq_desc[irq].status &= ~IRQ_DISABLED;
-		irq_desc[irq].handler->startup(irq);
+		desc->depth = 0;
+		desc->status &= ~IRQ_DISABLED;
+		desc->handler->startup(irq);
 	}
-	spin_unlock_irqrestore(&irq_controller_lock,flags);
+	spin_unlock_irqrestore(&desc->lock,flags);
+
+	register_irq_proc(irq);
 	return 0;
+}
+
+static struct proc_dir_entry * root_irq_dir;
+static struct proc_dir_entry * irq_dir [NR_IRQS];
+static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+
+unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0xffffffff};
+
+#define HEX_DIGITS 8
+
+static int irq_affinity_read_proc (char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	if (count < HEX_DIGITS+1)
+		return -EINVAL;
+	return sprintf (page, "%08x\n", irq_affinity[(int)data]);
+}
+
+static unsigned int parse_hex_value (const char *buffer,
+		unsigned long count, unsigned long *ret)
+{
+	unsigned char hexnum [HEX_DIGITS];
+	unsigned long value;
+	int i;
+
+	if (!count)
+		return -EINVAL;
+	if (count > HEX_DIGITS)
+		count = HEX_DIGITS;
+	if (copy_from_user(hexnum, buffer, count))
+		return -EFAULT;
+
+	/*
+	 * Parse the first 8 characters as a hex string, any non-hex char
+	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+	 */
+	value = 0;
+
+	for (i = 0; i < count; i++) {
+		unsigned int c = hexnum[i];
+
+		switch (c) {
+			case '0' ... '9': c -= '0'; break;
+			case 'a' ... 'f': c -= 'a'-10; break;
+			case 'A' ... 'F': c -= 'A'-10; break;
+		default:
+			goto out;
+		}
+		value = (value << 4) | c;
+	}
+out:
+	*ret = value;
+	return 0;
+}
+
+static int irq_affinity_write_proc (struct file *file, const char *buffer,
+					unsigned long count, void *data)
+{
+	int irq = (int) data, full_count = count, err;
+	unsigned long new_value;
+
+	if (!irq_desc[irq].handler->set_affinity)
+		return -EIO;
+
+	err = parse_hex_value(buffer, count, &new_value);
+
+#if CONFIG_SMP
+	/*
+	 * Do not allow disabling IRQs completely - it's a too easy
+	 * way to make the system unusable accidentally :-) At least
+	 * one online CPU still has to be targeted.
+	 */
+	if (!(new_value & cpu_online_map))
+		return -EINVAL;
+#endif
+
+	irq_affinity[irq] = new_value;
+	irq_desc[irq].handler->set_affinity(irq, new_value);
+
+	return full_count;
+}
+
+static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	unsigned long *mask = (unsigned long *) data;
+	if (count < HEX_DIGITS+1)
+		return -EINVAL;
+	return sprintf (page, "%08lx\n", *mask);
+}
+
+static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+					unsigned long count, void *data)
+{
+	unsigned long *mask = (unsigned long *) data, full_count = count, err;
+	unsigned long new_value;
+
+	err = parse_hex_value(buffer, count, &new_value);
+	if (err)
+		return err;
+
+	*mask = new_value;
+	return full_count;
+}
+
+#define MAX_NAMELEN 10
+
+static void register_irq_proc (unsigned int irq)
+{
+	struct proc_dir_entry *entry;
+	char name [MAX_NAMELEN];
+
+	if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type))
+		return;
+
+	memset(name, 0, MAX_NAMELEN);
+	sprintf(name, "%d", irq);
+
+	/* create /proc/irq/1234 */
+	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
+
+	/* create /proc/irq/1234/smp_affinity */
+	entry = create_proc_entry("smp_affinity", 0700, irq_dir[irq]);
+
+	entry->nlink = 1;
+	entry->data = (void *)irq;
+	entry->read_proc = irq_affinity_read_proc;
+	entry->write_proc = irq_affinity_write_proc;
+
+	smp_affinity_entry[irq] = entry;
+}
+
+unsigned long prof_cpu_mask = -1;
+
+void init_irq_proc (void)
+{
+	struct proc_dir_entry *entry;
+	int i;
+
+	/* create /proc/irq */
+	root_irq_dir = proc_mkdir("irq", 0);
+
+	/* create /proc/irq/prof_cpu_mask */
+	entry = create_proc_entry("prof_cpu_mask", 0700, root_irq_dir);
+
+	entry->nlink = 1;
+	entry->data = (void *)&prof_cpu_mask;
+	entry->read_proc = prof_cpu_mask_read_proc;
+	entry->write_proc = prof_cpu_mask_write_proc;
+
+	/*
+	 * Create entries for all existing IRQs.
+	 */
+	for (i = 0; i < NR_IRQS; i++) {
+		if (irq_desc[i].handler == &no_irq_type)
+			continue;
+		register_irq_proc(i);
+	}
 }
 
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/microcode.c linux/arch/i386/kernel/microcode.c
--- v2.3.47/linux/arch/i386/kernel/microcode.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/i386/kernel/microcode.c	Sat Feb 26 20:33:02 2000
@@ -20,6 +20,9 @@
  *		Initial release.
  *	1.01	18 February 2000, Tigran Aivazian <tigran@sco.com>
  *		Added read() support + cleanups.
+ *	1.02	21 February 2000, Tigran Aivazian <tigran@sco.com>
+ *		Added 'device trimming' support. open(O_WRONLY) zeroes
+ *		and frees the saved copy of applied microcode.
  */
 
 #include <linux/init.h>
@@ -33,7 +36,7 @@
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 
-#define MICROCODE_VERSION 	"1.01"
+#define MICROCODE_VERSION 	"1.02"
 
 MODULE_DESCRIPTION("CPU (P6) microcode update driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@ocston.org>");
@@ -53,7 +56,7 @@
 /*
  *  Bits in microcode_status. (31 bits of room for future expansion)
  */
-#define MICROCODE_IS_OPEN	0	/* set if /dev/microcode is in use */
+#define MICROCODE_IS_OPEN	0	/* set if device is in use */
 static unsigned long microcode_status = 0;
 
 /* the actual array of microcode blocks, each 2048 bytes */
@@ -68,31 +71,16 @@
 	release:	microcode_release,
 };
 
-static struct inode_operations microcode_inops = {
-	default_file_ops:	&microcode_fops,
-};
-
 static struct proc_dir_entry *proc_microcode;
 
 static int __init microcode_init(void)
 {
-	int size;
-
 	proc_microcode = create_proc_entry("microcode", S_IWUSR|S_IRUSR, proc_root_driver);
 	if (!proc_microcode) {
 		printk(KERN_ERR "microcode: can't create /proc/driver/microcode\n");
 		return -ENOMEM;
 	}
-	proc_microcode->ops = &microcode_inops;
-	size = smp_num_cpus * sizeof(struct microcode);
-	mc_applied = kmalloc(size, GFP_KERNEL);
-	if (!mc_applied) {
-		remove_proc_entry("microcode", proc_root_driver);
-		printk(KERN_ERR "microcode: can't allocate memory for saved microcode\n");
-		return -ENOMEM;
-	}
-	memset(mc_applied, 0, size); /* so that reading from offsets corresponding to failed
-	                                update makes this obvious */
+	proc_microcode->proc_fops = &microcode_fops;
 	printk(KERN_INFO "P6 Microcode Update Driver v%s registered\n", MICROCODE_VERSION);
 	return 0;
 }
@@ -100,7 +88,8 @@
 static void __exit microcode_exit(void)
 {
 	remove_proc_entry("microcode", proc_root_driver);
-	kfree(mc_applied);
+	if (mc_applied)
+		kfree(mc_applied);
 	printk(KERN_INFO "P6 Microcode Update Driver v%s unregistered\n", MICROCODE_VERSION);
 }
 
@@ -119,6 +108,15 @@
 	if (test_and_set_bit(MICROCODE_IS_OPEN, &microcode_status))
 		return -EBUSY;
 
+	if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
+		proc_microcode->size = 0;
+		if (mc_applied) {
+			memset(mc_applied, 0, smp_num_cpus * sizeof(struct microcode));
+			kfree(mc_applied);
+			mc_applied = NULL;
+		}
+	}
+
 	MOD_INC_USE_COUNT;
 
 	return 0;
@@ -243,6 +241,16 @@
 			sizeof(struct microcode));
 		return -EINVAL;
 	}
+	if (!mc_applied) {
+		int size = smp_num_cpus * sizeof(struct microcode);
+		mc_applied = kmalloc(size, GFP_KERNEL);
+		if (!mc_applied) {
+			printk(KERN_ERR "microcode: can't allocate memory for saved microcode\n");
+			return -ENOMEM;
+		}
+		memset(mc_applied, 0, size);
+	}
+	
 	lock_kernel();
 	microcode_num = len/sizeof(struct microcode);
 	microcode = vmalloc(len);
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/mpparse.c linux/arch/i386/kernel/mpparse.c
--- v2.3.47/linux/arch/i386/kernel/mpparse.c	Sat Feb 12 11:22:10 2000
+++ linux/arch/i386/kernel/mpparse.c	Sat Feb 26 08:13:45 2000
@@ -316,11 +316,14 @@
 	return num_processors;
 }
 
+static struct intel_mp_floating *mpf_found;
+
 /*
  * Scan the memory blocks for an SMP configuration block.
  */
-static int __init smp_get_mpf(struct intel_mp_floating *mpf)
+void __init get_smp_config (void)
 {
+	struct intel_mp_floating *mpf = mpf_found;
 	printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
 	if (mpf->mpf_feature2 & (1<<7)) {
 		printk("    IMCR and PIC compatibility mode.\n");
@@ -329,7 +332,6 @@
 		printk("    Virtual Wire compatibility mode.\n");
 		pic_mode = 0;
 	}
-	smp_found_config = 1;
 	/*
 	 * default CPU id - if it's different in the mptable
 	 * then we change it before first using it.
@@ -388,7 +390,7 @@
 		default:
 			printk("???\nUnknown standard configuration %d\n",
 				mpf->mpf_feature1);
-			return 1;
+			return;
 	}
 	if (mpf->mpf_feature1 > 4) {
 		printk("Bus #1 is PCI\n");
@@ -412,10 +414,9 @@
 	/*
 	 * Only use the first configuration found.
 	 */
-	return 1;
 }
 
-static int __init smp_scan_config(unsigned long base, unsigned long length)
+static int __init smp_scan_config (unsigned long base, unsigned long length)
 {
 	unsigned long *bp = phys_to_virt(base);
 	struct intel_mp_floating *mpf;
@@ -432,9 +433,13 @@
 			((mpf->mpf_specification == 1)
 				|| (mpf->mpf_specification == 4)) ) {
 
-			printk("found SMP MP-table at %08ld\n",
+			smp_found_config = 1;
+			printk("found SMP MP-table at %08lx\n",
 						virt_to_phys(mpf));
-			smp_get_mpf(mpf);
+			reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
+			if (mpf->mpf_physptr)
+				reserve_bootmem(mpf->mpf_physptr, PAGE_SIZE);
+			mpf_found = mpf;
 			return 1;
 		}
 		bp += 4;
@@ -443,7 +448,7 @@
 	return 0;
 }
 
-void __init init_intel_smp (void)
+void __init find_intel_smp (void)
 {
 	unsigned int address;
 
@@ -488,7 +493,7 @@
  * sense, but it doesnt have a BIOS(-configuration table).
  * No problem for Linux.
  */
-void __init init_visws_smp(void)
+void __init find_visws_smp(void)
 {
 	smp_found_config = 1;
 
@@ -505,13 +510,13 @@
  * - Intel MP Configuration Table
  * - or SGI Visual Workstation configuration
  */
-void __init init_smp_config (void)
+void __init find_smp_config (void)
 {
 #ifdef CONFIG_X86_IO_APIC
-	init_intel_smp();
+	find_intel_smp();
 #endif
 #ifdef CONFIG_VISWS
-	init_visws_smp();
+	find_visws_smp();
 #endif
 }
 
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c
--- v2.3.47/linux/arch/i386/kernel/mtrr.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/i386/kernel/mtrr.c	Sat Feb 26 20:33:02 2000
@@ -1507,11 +1507,6 @@
 
 #  ifdef CONFIG_PROC_FS
 
-static struct inode_operations proc_mtrr_inode_operations =
-{
-    &mtrr_fops,             /* default property file-ops */
-};
-
 static struct proc_dir_entry *proc_root_mtrr;
 
 #  endif  /*  CONFIG_PROC_FS  */
@@ -1836,9 +1831,9 @@
 
 #ifdef CONFIG_PROC_FS
     proc_root_mtrr = create_proc_entry ("mtrr", S_IWUSR | S_IRUGO, &proc_root);
-    proc_root_mtrr->ops = &proc_mtrr_inode_operations;
+    proc_root_mtrr->proc_fops = &mtrr_fops;
 #endif
-#ifdev CONFIG_DEVFS_FS
+#ifdef CONFIG_DEVFS_FS
     devfs_handle = devfs_register (NULL, "cpu/mtrr", 0, DEVFS_FL_DEFAULT, 0, 0,
 				   S_IFREG | S_IRUGO | S_IWUSR, 0, 0,
 				   &mtrr_fops, NULL);
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- v2.3.47/linux/arch/i386/kernel/process.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/i386/kernel/process.c	Thu Feb 24 22:41:15 2000
@@ -74,8 +74,13 @@
  */
 static void default_idle(void)
 {
-	if (current_cpu_data.hlt_works_ok && !hlt_counter)
-		asm volatile("sti ; hlt" : : : "memory");
+	if (current_cpu_data.hlt_works_ok && !hlt_counter) {
+		asm volatile("cli" : : : "memory");
+		if (!current->need_resched)
+			asm volatile("sti ; hlt" : : : "memory");
+		else
+			asm volatile("sti" : : : "memory");
+	}
 }
 
 /*
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/semaphore.c linux/arch/i386/kernel/semaphore.c
--- v2.3.47/linux/arch/i386/kernel/semaphore.c	Tue Dec  7 09:32:40 1999
+++ linux/arch/i386/kernel/semaphore.c	Fri Feb 25 16:35:28 2000
@@ -150,8 +150,9 @@
 int __down_trylock(struct semaphore * sem)
 {
 	int sleepers;
+	unsigned long flags;
 
-	spin_lock_irq(&semaphore_lock);
+	spin_lock_irqsave(&semaphore_lock, flags);
 	sleepers = sem->sleepers + 1;
 	sem->sleepers = 0;
 
@@ -162,7 +163,7 @@
 	if (!atomic_add_negative(sleepers, &sem->count))
 		wake_up(&sem->wait);
 
-	spin_unlock_irq(&semaphore_lock);
+	spin_unlock_irqrestore(&semaphore_lock, flags);
 	return 1;
 }
 
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.3.47/linux/arch/i386/kernel/setup.c	Sat Feb 12 11:22:10 2000
+++ linux/arch/i386/kernel/setup.c	Fri Feb 25 15:15:54 2000
@@ -119,7 +119,7 @@
 #endif
 
 extern int root_mountflags;
-extern int _text, _etext, _edata, _end;
+extern char _text, _etext, _edata, _end;
 extern unsigned long cpu_hz;
 
 /*
@@ -709,9 +709,20 @@
 
 #ifdef CONFIG_X86_IO_APIC
 	/*
-	 *	Save possible boot-time SMP configuration:
+	 * Find and reserve possible boot-time SMP configuration:
 	 */
-	init_smp_config();
+	find_smp_config();
+#endif
+	paging_init();
+#ifdef CONFIG_X86_IO_APIC
+	/*
+	 * get boot-time SMP configuration:
+	 */
+	if (smp_found_config)
+		get_smp_config();
+#endif
+#ifdef CONFIG_X86_LOCAL_APIC
+	init_apic_mappings();
 #endif
 
 #ifdef CONFIG_BLK_DEV_INITRD
diff -u --recursive --new-file v2.3.47/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- v2.3.47/linux/arch/i386/kernel/traps.c	Thu Feb 10 17:11:03 2000
+++ linux/arch/i386/kernel/traps.c	Thu Feb 24 22:41:16 2000
@@ -360,8 +360,6 @@
 	printk("Do you have a strange power saving mode enabled?\n");
 }
 
-atomic_t nmi_counter[NR_CPUS];
-
 #if CONFIG_X86_IO_APIC
 
 int nmi_watchdog = 1;
@@ -437,7 +435,8 @@
 {
 	unsigned char reason = inb(0x61);
 
-	atomic_inc(nmi_counter+smp_processor_id());
+
+	atomic_inc(&nmi_counter(smp_processor_id()));
 	if (!(reason & 0xc0)) {
 #if CONFIG_X86_IO_APIC
 		/*
diff -u --recursive --new-file v2.3.47/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c
--- v2.3.47/linux/arch/i386/mm/init.c	Wed Feb 16 17:03:51 2000
+++ linux/arch/i386/mm/init.c	Fri Feb 25 15:15:54 2000
@@ -438,10 +438,6 @@
 
 	__flush_tlb_all();
 
-#ifdef CONFIG_X86_LOCAL_APIC
-	init_apic_mappings();
-#endif
-
 #ifdef CONFIG_HIGHMEM
 	kmap_init();
 #endif
diff -u --recursive --new-file v2.3.47/linux/arch/ia64/ia32/binfmt_elf32.c linux/arch/ia64/ia32/binfmt_elf32.c
--- v2.3.47/linux/arch/ia64/ia32/binfmt_elf32.c	Thu Feb 10 17:11:03 2000
+++ linux/arch/ia64/ia32/binfmt_elf32.c	Thu Feb 24 10:14:29 2000
@@ -82,6 +82,8 @@
 	
 	/* Do all the IA-32 setup here */
 
+	current->thread.map_base = 0x40000000;
+
 	/* CS descriptor */
 	__asm__("mov ar.csd = %0" : /* no outputs */
 		: "r" IA64_SEG_DESCRIPTOR(0L, 0xFFFFFL, 0xBL, 1L,
diff -u --recursive --new-file v2.3.47/linux/arch/ia64/ia32/ia32_entry.S linux/arch/ia64/ia32/ia32_entry.S
--- v2.3.47/linux/arch/ia64/ia32/ia32_entry.S	Sun Feb 13 19:29:03 2000
+++ linux/arch/ia64/ia32/ia32_entry.S	Thu Feb 24 10:14:29 2000
@@ -75,7 +75,7 @@
 	data8 sys_unlink	  /* 10 */
 	data8 sys32_execve
 	data8 sys_chdir
-	data8 sys_ni_syscall /* sys_time is not supported on ia64 */
+	data8 sys32_time
 	data8 sys_mknod
 	data8 sys_chmod		  /* 15 */
 	data8 sys_lchown
diff -u --recursive --new-file v2.3.47/linux/arch/ia64/ia32/sys_ia32.c linux/arch/ia64/ia32/sys_ia32.c
--- v2.3.47/linux/arch/ia64/ia32/sys_ia32.c	Sun Feb 13 19:29:03 2000
+++ linux/arch/ia64/ia32/sys_ia32.c	Sat Feb 26 20:33:02 2000
@@ -278,7 +278,7 @@
 	if (!file)
 		return -EINVAL;
 	inode = file->f_dentry->d_inode;
-	if (!inode->i_op || !inode->i_op->default_file_ops)
+	if (!inode->i_fop)
 		return -EINVAL;
 	if (!file->f_op->read)
 		return -EINVAL;
@@ -1928,6 +1928,25 @@
 out:
 	unlock_kernel();
 	return err;
+}
+
+/*
+ * sys_time() can be implemented in user-level using
+ * sys_gettimeofday().  IA64 did this but i386 Linux did not
+ * so we have to implement this system call here.
+ */
+asmlinkage long sys32_time(int * tloc)
+{
+	int i;
+
+	/* SMP: This is fairly trivial. We grab CURRENT_TIME and 
+	   stuff it to user space. No side effects */
+	i = CURRENT_TIME;
+	if (tloc) {
+		if (put_user(i,tloc))
+			i = -EFAULT;
+	}
+	return i;
 }
 
 #ifdef	NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */
diff -u --recursive --new-file v2.3.47/linux/arch/ia64/kdb/kdbsupport.c linux/arch/ia64/kdb/kdbsupport.c
--- v2.3.47/linux/arch/ia64/kdb/kdbsupport.c	Thu Feb 10 17:11:03 2000
+++ linux/arch/ia64/kdb/kdbsupport.c	Thu Feb 24 10:14:29 2000
@@ -28,9 +28,10 @@
 #include <linux/stddef.h> 
 #include <linux/vmalloc.h>
 
-#include <asm/uaccess.h>
+#include <asm/delay.h>
 #include <asm/kdbsupport.h>
 #include <asm/rse.h>
+#include <asm/uaccess.h>
 
 extern kdb_state_t kdb_state ;
 k_machreg_t dbregs[KDB_DBREGS];
@@ -45,6 +46,21 @@
 __setup("kdb", kdb_setup);
 
 static int
+kdb_ia64_itm (int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+	int diag;
+	unsigned long val;
+
+	diag = kdbgetularg(argv[1], &val);
+	if (diag)
+		return diag;
+	kdb_printf("new itm=%0xlx\n", val);
+
+	ia64_set_itm(val);
+	return 0;
+}
+
+static int
 kdb_ia64_sir (int argc, const char **argv, const char **envp, struct pt_regs *regs)
 {
 	u64 lid, tpr, lrr0, lrr1, itv, pmv, cmcv;
@@ -53,15 +69,17 @@
 	asm ("mov %0=cr.tpr" : "=r"(tpr));
 	asm ("mov %0=cr.lrr0" : "=r"(lrr0));
 	asm ("mov %0=cr.lrr1" : "=r"(lrr1));
-	printk ("lid=0x%lx, tpr=0x%lx, lrr0=0x%lx, llr1=0x%lx\n", lid, tpr, lrr0, lrr1);
+	printk("lid=0x%lx, tpr=0x%lx, lrr0=0x%lx, llr1=0x%lx\n", lid, tpr, lrr0, lrr1);
 
 	asm ("mov %0=cr.itv" : "=r"(itv));
 	asm ("mov %0=cr.pmv" : "=r"(pmv));
 	asm ("mov %0=cr.cmcv" : "=r"(cmcv));
-	printk ("itv=0x%lx, pmv=0x%lx, cmcv=0x%lx\n", itv, pmv, cmcv);
+	printk("itv=0x%lx, pmv=0x%lx, cmcv=0x%lx\n", itv, pmv, cmcv);
 
-	printk ("irr=0x%016lx,0x%016lx,0x%016lx,0x%016lx\n",
+	printk("irr=0x%016lx,0x%016lx,0x%016lx,0x%016lx\n",
 		ia64_get_irr0(), ia64_get_irr1(), ia64_get_irr2(), ia64_get_irr3());
+
+	printk("itc=0x%016lx, itm=0x%016lx\n", ia64_get_itc(), ia64_get_itm());
 	return 0;
 }
 
@@ -90,6 +108,7 @@
 	kdb_state.bkpt_handling_state = BKPTSTATE_NOT_HANDLED ;
 
 	kdb_register("irr", kdb_ia64_sir, "", "Show interrupt registers", 0);
+	kdb_register("itm", kdb_ia64_itm, "", "Set new ITM value", 0);
 }
 
 /*
diff -u --recursive --new-file v2.3.47/linux/arch/ia64/kernel/irq.c linux/arch/ia64/kernel/irq.c
--- v2.3.47/linux/arch/ia64/kernel/irq.c	Sun Feb 13 19:29:03 2000
+++ linux/arch/ia64/kernel/irq.c	Thu Feb 24 10:14:29 2000
@@ -158,6 +158,9 @@
 	unsigned long eoi_ptr;
  
 # ifdef CONFIG_USB
+	extern void reenable_usb (void);
+	extern void disable_usb (void);
+
 	if (usbfix)
 		disable_usb();
 # endif
diff -u --recursive --new-file v2.3.47/linux/arch/ia64/kernel/irq_internal.c linux/arch/ia64/kernel/irq_internal.c
--- v2.3.47/linux/arch/ia64/kernel/irq_internal.c	Thu Feb 10 17:11:03 2000
+++ linux/arch/ia64/kernel/irq_internal.c	Thu Feb 24 10:14:29 2000
@@ -60,7 +60,7 @@
 }
 
 struct hw_interrupt_type irq_type_ia64_internal = {
-	"IA64 internal",
+	"IA64-internal",
 	(void (*)(unsigned long)) internal_noop,	/* init */
 	internal_noop,					/* startup */
 	internal_noop,					/* shutdown */
diff -u --recursive --new-file v2.3.47/linux/arch/ia64/kernel/ivt.S linux/arch/ia64/kernel/ivt.S
--- v2.3.47/linux/arch/ia64/kernel/ivt.S	Thu Feb 10 17:11:03 2000
+++ linux/arch/ia64/kernel/ivt.S	Thu Feb 24 10:14:29 2000
@@ -1026,7 +1026,7 @@
 // 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
 	mov r16=cr.ifa
 	rsm psr.dt
-#if 0
+#if 1
 	// If you disable this, you MUST re-enable to update_mmu_cache() code in pgtable.h
 	mov r17=_PAGE_SIZE_4K<<2
 	;;
diff -u --recursive --new-file v2.3.47/linux/arch/ia64/kernel/process.c linux/arch/ia64/kernel/process.c
--- v2.3.47/linux/arch/ia64/kernel/process.c	Thu Feb 10 17:11:03 2000
+++ linux/arch/ia64/kernel/process.c	Thu Feb 24 10:14:29 2000
@@ -97,6 +97,14 @@
 		check_pgt_cache();
 		if (pm_idle)
 			(*pm_idle)();
+#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
+		if (ia64_get_itm() < ia64_get_itc()) {
+			extern void ia64_reset_itm();
+
+			printk("cpu_idle: ITM in past, resetting it...\n");
+			ia64_reset_itm();
+		}
+#endif
 	}
 }
 
diff -u --recursive --new-file v2.3.47/linux/arch/ia64/kernel/time.c linux/arch/ia64/kernel/time.c
--- v2.3.47/linux/arch/ia64/kernel/time.c	Thu Feb 10 17:11:03 2000
+++ linux/arch/ia64/kernel/time.c	Thu Feb 24 10:14:29 2000
@@ -21,6 +21,10 @@
 #include <asm/ptrace.h>
 #include <asm/sal.h>
 #include <asm/system.h>
+#ifdef CONFIG_KDB
+# include <linux/kdb.h>
+#endif
+
 
 extern rwlock_t xtime_lock;
 extern volatile unsigned long lost_ticks;
@@ -61,7 +65,7 @@
  * update to jiffy.  The xtime_lock must be at least read-locked when
  * calling this routine.
  */
-static inline unsigned long
+static /*inline*/ unsigned long
 gettimeoffset (void)
 {
 	unsigned long now = ia64_get_itc();
@@ -185,6 +189,20 @@
 	}
 	write_unlock(&xtime_lock);
 }
+
+#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
+
+void 
+ia64_reset_itm (void)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	timer_interrupt(0, 0, current);
+	local_irq_restore(flags);
+}
+
+#endif /* CONFIG_ITANIUM_ASTEP_SPECIFIC */
 
 /*
  * Encapsulate access to the itm structure for SMP.
diff -u --recursive --new-file v2.3.47/linux/arch/ia64/kernel/traps.c linux/arch/ia64/kernel/traps.c
--- v2.3.47/linux/arch/ia64/kernel/traps.c	Thu Feb 10 17:11:03 2000
+++ linux/arch/ia64/kernel/traps.c	Thu Feb 24 10:14:29 2000
@@ -110,15 +110,75 @@
 ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
 {
 	siginfo_t siginfo;
+	int sig, code;
 
-	/* gdb uses a break number of 0xccccc for debug breakpoints: */
-	if (break_num != 0xccccc)
-		die_if_kernel("Bad break", regs, break_num);
-
-	siginfo.si_signo = SIGTRAP;
-	siginfo.si_errno = break_num;	/* XXX is it legal to abuse si_errno like this? */
-	siginfo.si_code = TRAP_BRKPT;
-	send_sig_info(SIGTRAP, &siginfo, current);
+	/* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
+	siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
+	siginfo.si_imm = break_num;
+
+	switch (break_num) {
+	      case 0: /* unknown error */
+		sig = SIGILL; code = ILL_ILLOPC;
+		break;
+
+	      case 1: /* integer divide by zero */
+		sig = SIGFPE; code = FPE_INTDIV;
+		break;
+
+	      case 2: /* integer overflow */
+		sig = SIGFPE; code = FPE_INTOVF;
+		break;
+
+	      case 3: /* range check/bounds check */
+		sig = SIGFPE; code = FPE_FLTSUB;
+		break;
+
+	      case 4: /* null pointer dereference */
+		sig = SIGSEGV; code = SEGV_MAPERR;
+		break;
+
+	      case 5: /* misaligned data */
+		sig = SIGSEGV; code = BUS_ADRALN;
+		break;
+
+	      case 6: /* decimal overflow */
+		sig = SIGFPE; code = __FPE_DECOVF;
+		break;
+
+	      case 7: /* decimal divide by zero */
+		sig = SIGFPE; code = __FPE_DECDIV;
+		break;
+
+	      case 8: /* packed decimal error */
+		sig = SIGFPE; code = __FPE_DECERR;
+		break;
+
+	      case 9: /* invalid ASCII digit */
+		sig = SIGFPE; code = __FPE_INVASC;
+		break;
+
+	      case 10: /* invalid decimal digit */
+		sig = SIGFPE; code = __FPE_INVDEC;
+		break;
+
+	      case 11: /* paragraph stack overflow */
+		sig = SIGSEGV; code = __SEGV_PSTKOVF;
+		break;
+
+	      default:
+		if (break_num < 0x40000 || break_num > 0x100000)
+			die_if_kernel("Bad break", regs, break_num);
+
+		if (break_num < 0x80000) {
+			sig = SIGILL; code = __ILL_BREAK;
+		} else {
+			sig = SIGTRAP; code = TRAP_BRKPT;
+		}
+	}
+	siginfo.si_signo = sig;
+	siginfo.si_errno = 0;
+	siginfo.si_code = code;
+	send_sig_info(sig, &siginfo, current);
 }
 
 /*
@@ -240,6 +300,7 @@
 {
 	long exception, bundle[2];
 	unsigned long fault_ip;
+	struct siginfo siginfo;
 	static int fpu_swa_count = 0;
 	static unsigned long last_time;
 
@@ -265,21 +326,41 @@
  			ia64_increment_ip(regs);
 		} else if (exception == -1) {
 			printk("handle_fpu_swa: fp_emulate() returned -1\n");
-			return -2;
+			return -1;
 		} else {
 			/* is next instruction a trap? */
 			if (exception & 2) {
 				ia64_increment_ip(regs);
 			}
-			return -1;
+			siginfo.si_signo = SIGFPE;
+			siginfo.si_errno = 0;
+			siginfo.si_code = 0;
+			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
+			if (isr & 0x11) {
+				siginfo.si_code = FPE_FLTINV;
+			} else if (isr & 0x44) {
+				siginfo.si_code = FPE_FLTDIV;
+			}
+			send_sig_info(SIGFPE, &siginfo, current);
 		}
 	} else {
 		if (exception == -1) {
 			printk("handle_fpu_swa: fp_emulate() returned -1\n");
-			return -2;
+			return -1;
 		} else if (exception != 0) {
 			/* raise exception */
-			return -1;
+			siginfo.si_signo = SIGFPE;
+			siginfo.si_errno = 0;
+			siginfo.si_code = 0;
+			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
+			if (isr & 0x880) {
+				siginfo.si_code = FPE_FLTOVF;
+			} else if (isr & 0x1100) {
+				siginfo.si_code = FPE_FLTUND;
+			} else if (isr & 0x2200) {
+				siginfo.si_code = FPE_FLTRES;
+			}
+			send_sig_info(SIGFPE, &siginfo, current);
 		}
 	}
 	return 0;
@@ -369,22 +450,19 @@
 		return;
 
 	      case 30: /* Unaligned fault */
-		sprintf(buf, "Unaligned access in kernel mode---don't do this!");
+		sprintf(buf, "Kernel unaligned trap accessing %016lx (ip=%016lx)!",
+			ifa, regs->cr_iip + ia64_psr(regs)->ri);
 		break;
 
 	      case 32: /* fp fault */
 	      case 33: /* fp trap */
-		result = handle_fpu_swa((vector == 32) ? 1 : 0, regs, isr);
+		result = handle_fpu_swa((vector == 32) ? 1 : 0, regs, &isr);
 		if (result < 0) {
 			siginfo.si_signo = SIGFPE;
 			siginfo.si_errno = 0;
-			siginfo.si_code = 0;	/* XXX fix me */
+			siginfo.si_code = FPE_FLTINV;
 			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
-			send_sig_info(SIGFPE, &siginfo, current);
-			if (result == -1)
-				send_sig_info(SIGFPE, &siginfo, current);
-			else
-				force_sig(SIGFPE, current);
+			force_sig(SIGFPE, current);
 		}
 		return;
 
diff -u --recursive --new-file v2.3.47/linux/arch/ia64/kernel/unaligned.c linux/arch/ia64/kernel/unaligned.c
--- v2.3.47/linux/arch/ia64/kernel/unaligned.c	Thu Feb 10 17:11:03 2000
+++ linux/arch/ia64/kernel/unaligned.c	Thu Feb 24 10:14:29 2000
@@ -1384,30 +1384,33 @@
 	load_store_t *insn;
 	int ret = -1;
 
-	/*
-	 * We flag unaligned references while in kernel as
-	 * errors: the kernel must be fixed. The switch code
-	 * is in ivt.S at entry 30.
-	 *
-	 * So here we keep a simple sanity check.
-	 */
-	if ( !user_mode(regs) ) {
-		die_if_kernel("Unaligned reference while in kernel\n", regs, 30);
-		/* NOT_REACHED */
+	if (current->thread.flags & IA64_THREAD_UAC_SIGBUS) {
+		struct siginfo si;
+
+		si.si_signo = SIGBUS;
+		si.si_errno = 0;
+		si.si_code = BUS_ADRALN;
+		si.si_addr = (void *) ifa;
+		send_sig_info (SIGBUS, &si, current);
+		return;
 	}
 
-	/*
-	 * Make sure we log the unaligned access, so that user/sysadmin can notice it
-	 * and eventually fix the program.
-	 *
-	 * We don't want to do that for every access so we pace it with jiffies.
-	 */
-	if ( unalign_count > 5 && jiffies - last_time > 5*HZ )  unalign_count = 0;
-	if ( ++unalign_count < 5 ) {
-		last_time = jiffies;
-		printk("%s(%d): unaligned trap accessing %016lx (ip=%016lx)\n",
-			current->comm, current->pid, ifa, regs->cr_iip + ipsr->ri);
-		
+	if (!(current->thread.flags & IA64_THREAD_UAC_NOPRINT)) {
+		/*
+		 * Make sure we log the unaligned access, so that
+		 * user/sysadmin can notice it and eventually fix the
+		 * program.
+		 *
+		 * We don't want to do that for every access so we
+		 * pace it with jiffies.
+		 */
+		if (unalign_count > 5 && jiffies - last_time > 5*HZ)
+			unalign_count = 0;
+		if (++unalign_count < 5) {
+			last_time = jiffies;
+			printk("%s(%d): unaligned trap accessing %016lx (ip=%016lx)\n",
+			       current->comm, current->pid, ifa, regs->cr_iip + ipsr->ri);
+		}
 	}
 
 	DPRINT(("iip=%lx ifa=%lx isr=%lx\n", regs->cr_iip, ifa, regs->cr_ipsr));
diff -u --recursive --new-file v2.3.47/linux/arch/ia64/lib/copy_user.S linux/arch/ia64/lib/copy_user.S
--- v2.3.47/linux/arch/ia64/lib/copy_user.S	Thu Feb 10 17:11:03 2000
+++ linux/arch/ia64/lib/copy_user.S	Thu Feb 24 10:14:29 2000
@@ -1,71 +1,375 @@
-/*
- * This routine copies a linear memory buffer across the user/kernel boundary.  When
- * reading a byte from the source causes a fault, the remainder of the destination
- * buffer is zeroed out.  Note that this can happen only when copying from user
- * to kernel memory and we do this to absolutely guarantee that the
- * kernel doesn't operate on random data.
- *
- * This file is derived from arch/alpha/lib/copy_user.S.
- *
- * Inputs:
- *	in0:	address of destination buffer
- *	in1:	address of source buffer
- *	in2:	length of buffer in bytes
- * Outputs:
- *	r8:	number of bytes that didn't get copied due to a fault
- * 
- * Copyright (C) 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#define EXI(x...)				\
-99:	x;					\
+// The label comes first because our store instruction contains a comma
+// and confuse the preprocessor otherwise
+//
+#undef DEBUG
+#ifdef DEBUG
+#define EX(y,x...)				\
+99:	x
+#else
+#define EX(y,x...)				\
 	.section __ex_table,"a";		\
-	data4 @gprel(99b);			\
-	data4 .Lexit_in-99b;			\
-	.previous
+	data4 @gprel(99f);			\
+	data4 y-99f;				\
+	.previous;				\
+99:	x
+#endif
 
-#define EXO(x...)				\
-99:	x;					\
-	.section __ex_table,"a";		\
-	data4 @gprel(99b);			\
-	data4 .Lexit_out-99b;			\
-	.previous
-
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
-
-	.align 32
-	.global __copy_user
-	.proc __copy_user
+//
+// Tuneable parameters
+//
+#define COPY_BREAK	16	// we do byte copy below (must be >=16)
+#define PIPE_DEPTH	4	// pipe depth
+
+#define EPI		p[PIPE_DEPTH-1] // PASTE(p,16+PIPE_DEPTH-1)
+
+//
+// arguments
+//
+#define dst		in0
+#define src		in1
+#define len		in2
+
+//
+// local registers
+//
+#define cnt		r18
+#define len2		r19
+#define saved_lc	r20
+#define saved_pr	r21
+#define tmp		r22
+#define val		r23
+#define src1		r24
+#define dst1		r25
+#define src2		r26
+#define dst2		r27
+#define len1		r28
+#define enddst		r29
+#define endsrc		r30
+#define saved_pfs	r31
+ 	.text
+ 	.psr	abi64
+ 	.psr	lsb
+
+ 	.align	16
+ 	.global	__copy_user
+ 	.proc	__copy_user
 __copy_user:
-	alloc r10=ar.pfs,3,0,0,0
-	mov r9=ar.lc		// save ar.lc
-	mov ar.lc=in2		// set ar.lc to length of buffer
-	br.sptk.few .Lentr
-
-	// XXX braindead copy loop---this needs to be optimized
-.Loop1:
-	EXI(ld1 r8=[in1],1)
-	;;
-	EXO(st1 [in0]=r8,1)
-.Lentr:	br.cloop.dptk.few .Loop1	// repeat unless ar.lc--==0
-	;;			// avoid RAW on ar.lc
-.Lexit_out:
-	mov r8=ar.lc		// return how many bytes we _didn't_ copy
-	mov ar.lc=r9
-	br.ret.sptk.few rp
-
-.Lexit_in:
-	// clear the remainder of the buffer:
-	mov r8=ar.lc	// return how many bytes we _didn't_ copy
-.Loop2:
-	st1 [in0]=r0,1	// this cannot fault because we get here only on user->kernel copies
-	br.cloop.dptk.few .Loop2
-	;;				// avoid RAW on ar.lc
-	mov ar.lc=r9
-	br.ret.sptk.few rp
+	alloc saved_pfs=ar.pfs,3,((2*PIPE_DEPTH+7)&~7),0,((2*PIPE_DEPTH+7)&~7)
+
+	.rotr val1[PIPE_DEPTH],val2[PIPE_DEPTH]
+	.rotp p[PIPE_DEPTH]
+
+	adds len2=-1,len	// br.ctop is repeat/until
+	mov ret0=r0
+
+	;;			// RAW of cfm when len=0
+	cmp.eq p8,p0=r0,len	// check for zero length
+	mov saved_lc=ar.lc	// preserve ar.lc (slow)
+(p8)	br.ret.spnt.few rp	// empty mempcy()
+	;;
+	add enddst=dst,len	// first byte after end of source
+	add endsrc=src,len	// first byte after end of destination
+	mov saved_pr=pr		// preserve predicates
+
+	mov dst1=dst		// copy because of rotation
+	mov ar.ec=PIPE_DEPTH
+	mov pr.rot=1<<16	// p16=true all others are false
+
+	mov src1=src		// copy because of rotation
+	mov ar.lc=len2		// initialize lc for small count
+	cmp.lt p10,p7=COPY_BREAK,len	// if len > COPY_BREAK then long copy 
+
+	xor tmp=src,dst		// same alignment test prepare
+(p10)	br.cond.dptk.few long_memcpy
+	;;			// RAW pr.rot/p16 ?
+	//
+	// Now we do the byte by byte loop with software pipeline
+	//
+	// p7 is necessarily false by now
+1:				
+	EX(failure_in_pipe1,(p16) ld1 val1[0]=[src1],1)
+
+	EX(failure_out,(EPI) st1 [dst1]=val1[PIPE_DEPTH-1],1)
+	br.ctop.dptk.few 1b
+	;;
+	mov ar.lc=saved_lc
+	mov pr=saved_pr,0xffffffffffff0000
+	mov ar.pfs=saved_pfs		// restore ar.ec
+	br.ret.sptk.few rp	// end of short memcpy
+
+	//
+	// Beginning of long mempcy (i.e. > 16 bytes)
+	//
+long_memcpy:
+	tbit.nz p6,p7=src1,0	// odd alignement
+	and tmp=7,tmp
+	;;
+	cmp.eq p10,p8=r0,tmp
+	mov len1=len		// copy because of rotation
+(p8)	br.cond.dpnt.few 1b	// XXX Fixme. memcpy_diff_align 
+	;;
+	// At this point we know we have more than 16 bytes to copy
+	// and also that both src and dest have the same alignment
+	// which may not be the one we want. So for now we must move
+	// forward slowly until we reach 16byte alignment: no need to
+	// worry about reaching the end of buffer.
+	//
+	EX(failure_in1,(p6) ld1 val1[0]=[src1],1)	// 1-byte aligned
+(p6)	adds len1=-1,len1;;
+	tbit.nz p7,p0=src1,1
+	;;
+	EX(failure_in1,(p7) ld2 val1[1]=[src1],2)	// 2-byte aligned
+(p7)	adds len1=-2,len1;;
+	tbit.nz p8,p0=src1,2
+	;;
+	//
+	// Stop bit not required after ld4 because if we fail on ld4
+	// we have never executed the ld1, therefore st1 is not executed.
+	//
+	EX(failure_in1,(p8) ld4 val2[0]=[src1],4)	// 4-byte aligned
+	EX(failure_out,(p6) st1 [dst1]=val1[0],1)
+	tbit.nz p9,p0=src1,3
+	;;
+	//
+	// Stop bit not required after ld8 because if we fail on ld8
+	// we have never executed the ld2, therefore st2 is not executed.
+	//
+	EX(failure_in1,(p9) ld8 val2[1]=[src1],8)	// 8-byte aligned
+	EX(failure_out,(p7) st2 [dst1]=val1[1],2)
+(p8)	adds len1=-4,len1
+	;;
+	EX(failure_out, (p8) st4 [dst1]=val2[0],4)
+(p9)	adds len1=-8,len1;;
+	shr.u cnt=len1,4		// number of 128-bit (2x64bit) words
+	;;
+	EX(failure_out, (p9) st8 [dst1]=val2[1],8)
+	tbit.nz p6,p0=len1,3	
+	cmp.eq p7,p0=r0,cnt
+	adds tmp=-1,cnt			// br.ctop is repeat/until
+(p7)	br.cond.dpnt.few .dotail	// we have less than 16 bytes left
+	;;
+	adds src2=8,src1	
+	adds dst2=8,dst1
+	mov ar.lc=tmp
+	;;
+	//
+	// 16bytes/iteration
+	//
+2:
+	EX(failure_in3,(p16) ld8 val1[0]=[src1],16)
+(p16)	ld8 val2[0]=[src2],16
+
+	EX(failure_out, (EPI)	st8 [dst1]=val1[PIPE_DEPTH-1],16)
+(EPI)	st8 [dst2]=val2[PIPE_DEPTH-1],16
+	br.ctop.dptk.few 2b
+	;;			// RAW on src1 when fall through from loop
+	//
+	// Tail correction based on len only
+	//
+	// No matter where we come from (loop or test) the src1 pointer
+	// is 16 byte aligned AND we have less than 16 bytes to copy.
+	//
+.dotail:			
+	EX(failure_in1,(p6) ld8 val1[0]=[src1],8)	// at least 8 bytes
+	tbit.nz p7,p0=len1,2
+	;;
+	EX(failure_in1,(p7) ld4 val1[1]=[src1],4)	// at least 4 bytes
+ 	tbit.nz p8,p0=len1,1
+	;;
+	EX(failure_in1,(p8) ld2 val2[0]=[src1],2)	// at least 2 bytes
+	tbit.nz p9,p0=len1,0
+	;;
+	EX(failure_out, (p6) st8 [dst1]=val1[0],8)
+	;;
+	EX(failure_in1,(p9) ld1 val2[1]=[src1])		// only 1 byte left
+	mov ar.lc=saved_lc
+	;;
+	EX(failure_out,(p7) st4 [dst1]=val1[1],4)
+	mov pr=saved_pr,0xffffffffffff0000
+	;;
+	EX(failure_out, (p8)	st2 [dst1]=val2[0],2)
+	mov ar.pfs=saved_pfs
+	;;
+	EX(failure_out, (p9)	st1 [dst1]=val2[1])
+	br.ret.dptk.few rp
+
+
+
+	//
+	// Here we handle the case where the byte by byte copy fails
+	// on the load.
+	// Several factors make the zeroing of the rest of the buffer kind of
+	// tricky:
+	//	- the pipeline: loads/stores are not in sync (pipeline)
+	//
+	//	  In the same loop iteration, the dst1 pointer does not directly
+	//	  reflect where the faulty load was.
+	//	  
+	//	- pipeline effect
+	//	  When you get a fault on load, you may have valid data from
+	//	  previous loads not yet store in transit. Such data must be
+	//	  store normally before moving onto zeroing the rest.
+	//
+	//	- single/multi dispersal independence.
+	//
+	// solution:
+	//	- we don't disrupt the pipeline, i.e. data in transit in
+	//	  the software pipeline will be eventually move to memory.
+	//	  We simply replace the load with a simple mov and keep the
+	//	  pipeline going. We can't really do this inline because 
+	//	  p16 is always reset to 1 when lc > 0.
+	//
+failure_in_pipe1:
+	sub ret0=endsrc,src1	// number of bytes to zero, i.e. not copied
+1:
+(p16)	mov val1[0]=r0
+(EPI)	st1 [dst1]=val1[PIPE_DEPTH-1],1
+	br.ctop.dptk.few 1b
+	;;
+	mov pr=saved_pr,0xffffffffffff0000
+	mov ar.lc=saved_lc
+	mov ar.pfs=saved_pfs
+	br.ret.dptk.few rp
+
+
+	//
+	// Here we handle the head & tail part when we check for alignment.
+	// The following code handles only the load failures. The
+	// main diffculty comes from the fact that loads/stores are
+	// scheduled. So when you fail on a load, the stores corresponding
+	// to previous successful loads must be executed.
+	//
+	// However some simplifications are possible given the way
+	// things work.
+	// 
+	// 1) HEAD
+	// Theory of operation:
+	//
+	//  Page A   | Page B
+	//  ---------|-----
+	//          1|8 x
+	//	  1 2|8 x
+	//	    4|8 x
+	//	  1 4|8 x
+	//        2 4|8 x
+	//      1 2 4|8 x
+	//	     |1
+	//	     |2 x
+	//	     |4 x
+	//
+	// page_size >= 4k (2^12).  (x means 4, 2, 1)
+	// Here we suppose Page A exists and Page B does not.
+	//
+	// As we move towards eight byte alignment we may encounter faults.
+	// The numbers on each page show the size of the load (current alignment).
+	//
+	// Key point:
+	//	- if you fail on 1, 2, 4 then you have never executed any smaller
+	//	  size loads, e.g. failing ld4 means no ld1 nor ld2 executed 
+	//	  before.
+	//
+	// This allows us to simplify the cleanup code, because basically you
+	// only have to worry about "pending" stores in the case of a failing
+	// ld8(). Given the way the code is written today, this means only 
+	// worry about st2, st4. There we can use the information encapsulated
+	// into the predicates.
+	// 
+	// Other key point:
+	// 	- if you fail on the ld8 in the head, it means you went straight
+	//	  to it, i.e. 8byte alignment within an unexisting page.
+	// Again this comes from the fact that if you crossed just for the the ld8 then
+	// you are 8byte aligned but also 16byte align, therefore you would
+	// either go for the 16byte copy loop OR the ld8 in the tail part.
+	// The combination ld1, ld2, ld4, ld8 where you fail on ld8 is impossible
+	// because it would mean you had 15bytes to copy in which case you 
+	// would have defaulted to the byte by byte copy.
+	//
+	//
+	// 2) TAIL
+	// Here we now we have less than 16 bytes AND we are either 8 or 16 byte
+	// aligned.
+	//
+	// Key point:
+	// This means that we either:
+	//		- are right on a page boundary
+	//	OR 
+	//		- are at more than 16 bytes from a page boundary with 
+	//		  at most 15 bytes to copy: no chance of crossing.
+	//
+	// This allows us to assume that if we fail on a load we haven't possibly
+	// executed any of the previous (tail) ones, so we don't need to do 
+	// any stores. For instance, if we fail on ld2, this means we had 
+	// 2 or 3 bytes left to copy and we did not execute the ld8 nor ld4.
+	//
+	// This means that we are in a situation similar the a fault in the 
+	// head part. That's nice! 
+	// 
+failure_in1:
+//	sub ret0=enddst,dst1	// number of bytes to zero, i.e. not copied
+//	sub len=enddst,dst1,1
+	sub ret0=endsrc,src1	// number of bytes to zero, i.e. not copied
+	sub len=endsrc,src1,1
+	//
+	// we know that ret0 can never be zero at this point
+	// because we failed why trying to do a load, i.e. there is still
+	// some work to do.
+	// The failure_in1bis and length problem is taken care of at the
+	// calling side.
+	//
+	;;
+failure_in1bis:			// from (failure_in3)
+	mov ar.lc=len		// Continue with a stupid byte store.
+	;;
+5:
+	st1 [dst1]=r0,1
+	br.cloop.dptk.few 5b	
+	;;
+skip_loop:
+	mov pr=saved_pr,0xffffffffffff0000
+	mov ar.lc=saved_lc
+	mov ar.pfs=saved_pfs
+	br.ret.dptk.few rp
+
+	//
+	// Here we simply restart the loop but instead
+	// of doing loads we fill the pipeline with zeroes
+	// We can't simply store r0 because we may have valid 
+	// data in transit in the pipeline.
+	// ar.lc and ar.ec are setup correctly at this point
+	//
+	// we MUST use src1/endsrc here and not dst1/enddst because
+	// of the pipeline effect.
+	//
+failure_in3:
+	sub ret0=endsrc,src1	// number of bytes to zero, i.e. not copied
+	;;
+2:
+(p16)	mov val1[0]=r0
+(p16)	mov val2[0]=r0
+(EPI)	st8 [dst1]=val1[PIPE_DEPTH-1],16
+(EPI)	st8 [dst2]=val2[PIPE_DEPTH-1],16
+	br.ctop.dptk.few 2b
+	;;
+	cmp.ne p6,p0=dst1,enddst	// Do we need to finish the tail ?
+	sub len=enddst,dst1,1		// precompute len
+(p6)	br.cond.dptk.few failure_in1bis	
+	;;
+	mov pr=saved_pr,0xffffffffffff0000
+	mov ar.lc=saved_lc
+	mov ar.pfs=saved_pfs
+	br.ret.dptk.few rp
+
+	//
+	// handling of failures on stores: that's the easy part
+	//
+failure_out:
+	sub ret0=enddst,dst1
+	mov pr=saved_pr,0xffffffffffff0000
+	mov ar.lc=saved_lc
+
+	mov ar.pfs=saved_pfs
+	br.ret.dptk.few rp
+
+
+ 	.endp __copy_user
 
-	.endp __copy_user
diff -u --recursive --new-file v2.3.47/linux/arch/mips/Makefile linux/arch/mips/Makefile
--- v2.3.47/linux/arch/mips/Makefile	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/Makefile	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.13 1998/08/17 10:16:23 ralf Exp $
+# $Id: Makefile,v 1.22 2000/01/26 00:07:44 ralf Exp $
 #
 # This file is subject to the terms and conditions of the GNU General Public
 # License.  See the file "COPYING" in the main directory of this archive
@@ -18,44 +18,27 @@
 #
 ifdef CONFIG_CPU_LITTLE_ENDIAN
 tool-prefix	= mipsel-linux-
-ifdef CONFIG_MIPS_ECOFF
-oformat		= ecoff-littlemips
-else
-oformat		= elf32-littlemips
-endif
 else
 tool-prefix	= mips-linux-
-ifdef CONFIG_MIPS_ECOFF
-oformat		= ecoff-bigmips
-else
-oformat		= elf32-bigmips
-endif
 endif
 
 ifdef CONFIG_CROSSCOMPILE
 CROSS_COMPILE  = $(tool-prefix)
 endif
 
-LINKFLAGS	= -static -N
-MODFLAGS	+= -mlong-calls
-
 #
-# The new ELF GCC uses -G0 -mabicalls -fpic as default.  We don't need PIC
+# The ELF GCC uses -G0 -mabicalls -fpic as default.  We don't need PIC
 # code in the kernel since it only slows down the whole thing.  For the
 # old GCC these options are just the defaults.  At some point we might
 # make use of global pointer optimizations.
 #
 # The DECStation requires an ECOFF kernel for remote booting, other MIPS
-# machines may also.
+# machines may also.  Since BFD is incredibly buggy with respect to
+# crossformat linking we rely on the elf2ecoff tool for format conversion.
 #
-ifdef CONFIG_ELF_KERNEL
-CFLAGS		+= -G 0 -mno-abicalls -fno-pic
-LINKFLAGS	+= -G 0
-endif
-ifdef CONFIG_ECOFF_KERNEL
 CFLAGS		+= -G 0 -mno-abicalls -fno-pic
-LINKFLAGS	+= -G 0 -oformat ecoff-littlemips
-endif
+LINKFLAGS	+= -static -G 0
+MODFLAGS	+= -mlong-calls
 
 ifdef CONFIG_REMOTE_DEBUG
 CFLAGS		:= $(CFLAGS) -g
@@ -125,7 +108,7 @@
 LOADADDR      += 0x80080000
 endif
 
-ifdef CONFIG_SGI
+ifdef CONFIG_SGI_IP22
 LIBS          += arch/mips/sgi/kernel/sgikern.a arch/mips/arc/arclib.a
 SUBDIRS       += arch/mips/sgi/kernel arch/mips/arc
 #
@@ -134,7 +117,6 @@
 # 8kb aligned or the handling of the current variable will break.
 #
 LOADADDR      += 0x88002000
-HOSTCC        = cc
 endif
 
 #
@@ -146,6 +128,15 @@
 endif
 
 #
+# NEC DDB Vrc-5074
+#
+ifdef CONFIG_DDB5074
+SUBDIRS       += arch/mips/ddb5074
+LIBS          += arch/mips/ddb5074/ddb5074.a
+LOADADDR      += 0x80080000
+endif
+
+#
 # Choosing incompatible machines durings configuration will result in
 # error messages during linking.  Select a default linkscript if
 # none has been choosen above.
@@ -171,7 +162,7 @@
 
 HEAD := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
 
-SUBDIRS := $(SUBDIRS) $(addprefix arch/mips/, kernel mm lib tools)
+SUBDIRS := $(addprefix arch/mips/, tools) $(SUBDIRS) $(addprefix arch/mips/, kernel mm lib)
 CORE_FILES := arch/mips/kernel/kernel.o arch/mips/mm/mm.o $(CORE_FILES)
 LIBS := arch/mips/lib/lib.a $(LIBS)
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/Makefile linux/arch/mips/arc/Makefile
--- v2.3.47/linux/arch/mips/arc/Makefile	Mon Dec 20 18:48:21 1999
+++ linux/arch/mips/arc/Makefile	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,5 @@
-# $Id: Makefile,v 1.1 1998/10/18 13:32:08 tsbogend Exp $
+# $Id: Makefile,v 1.2 2000/01/13 00:11:11 ralf Exp $
+#
 # Makefile for the SGI arcs prom monitor library routines
 # under Linux.
 #
@@ -8,16 +9,8 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-OBJS  = console.o init.o printf.o memory.o tree.o env.o \
-      cmdline.o misc.o time.o file.o identify.o
-
-all: arclib.a
-
-arclib.a: $(OBJS)
-	$(AR) rcs arclib.a $(OBJS)
-	sync
-
-dep:
-	$(CPP) $(CPPFLAGS) -M *.c > .depend
+L_TARGET = arclib.a
+L_OBJS  = console.o init.o printf.o memory.o tree.o env.o cmdline.o misc.o \
+	  time.o file.o identify.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/cmdline.c linux/arch/mips/arc/cmdline.c
--- v2.3.47/linux/arch/mips/arc/cmdline.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/arc/cmdline.c	Thu Feb 24 22:52:30 2000
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: cmdline.c,v 1.1 1998/10/18 13:32:08 tsbogend Exp $
+ * $Id: cmdline.c,v 1.2 1999/10/09 00:00:57 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/console.c linux/arch/mips/arc/console.c
--- v2.3.47/linux/arch/mips/arc/console.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/arc/console.c	Thu Feb 24 22:52:30 2000
@@ -4,9 +4,8 @@
  * Copyright (C) 1996 David S. Miller (dm@sgi.com)
  * Compability with board caches, Ulf Carlsson
  *
- * $Id: console.c,v 1.2 1999/06/12 18:42:38 ulfc Exp $
+ * $Id: console.c,v 1.3 1999/10/09 00:00:57 ralf Exp $
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <asm/sgialib.h>
 #include <asm/bcache.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/env.c linux/arch/mips/arc/env.c
--- v2.3.47/linux/arch/mips/arc/env.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/arc/env.c	Thu Feb 24 22:52:30 2000
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: env.c,v 1.1 1998/10/18 13:32:08 tsbogend Exp $
+ * $Id: env.c,v 1.2 1999/10/09 00:00:57 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/file.c linux/arch/mips/arc/file.c
--- v2.3.47/linux/arch/mips/arc/file.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/arc/file.c	Thu Feb 24 22:52:30 2000
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: file.c,v 1.1 1998/10/18 13:32:08 tsbogend Exp $
+ * $Id: file.c,v 1.2 1999/10/09 00:00:57 ralf Exp $
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/identify.c linux/arch/mips/arc/identify.c
--- v2.3.47/linux/arch/mips/arc/identify.c	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/arc/identify.c	Thu Feb 24 22:52:30 2000
@@ -7,14 +7,14 @@
  * 
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: identify.c,v 1.2 1999/02/25 21:04:13 tsbogend Exp $
+ * $Id: identify.c,v 1.3 1999/10/21 00:23:04 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
 
-#include <asm/sgi.h>
+#include <asm/sgi/sgi.h>
 #include <asm/sgialib.h>
 #include <asm/bootinfo.h>
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/init.c linux/arch/mips/arc/init.c
--- v2.3.47/linux/arch/mips/arc/init.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/arc/init.c	Thu Feb 24 22:52:30 2000
@@ -1,9 +1,11 @@
-/*
- * init.c: PROM library initialisation code.
+/* $Id: init.c,v 1.4 1999/10/09 00:00:57 ralf Exp $
+ * This file is subject to the terms and conditions of the GNU General Public+ 
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * PROM library initialisation code.
  *
- * $Id: init.c,v 1.2 1999/02/25 21:22:49 tsbogend Exp $
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -11,7 +13,7 @@
 
 #include <asm/sgialib.h>
 
-/* #define DEBUG_PROM_INIT */
+#undef DEBUG_PROM_INIT
 
 /* Master romvec interface. */
 struct linux_romvec *romvec;
@@ -43,18 +45,9 @@
 	prom_vers = pb->ver;
 	prom_rev = pb->rev;
 	prom_identify_arch();
-#ifdef CONFIG_SGI
-	printk("PROMLIB: SGI ARCS firmware Version %d Revision %d\n",
-		    prom_vers, prom_rev);
-#else
 	printk("PROMLIB: ARC firmware Version %d Revision %d\n",
 		    prom_vers, prom_rev);
-#endif
 	prom_meminit();
-
-#if 0
-	prom_testtree();
-#endif
 
 #ifdef DEBUG_PROM_INIT
 	{
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/memory.c linux/arch/mips/arc/memory.c
--- v2.3.47/linux/arch/mips/arc/memory.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/arc/memory.c	Thu Feb 24 22:52:30 2000
@@ -4,25 +4,30 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: memory.c,v 1.5 1999/04/14 21:25:02 tsbogend Exp $
+ * $Id: memory.c,v 1.10 2000/01/27 23:21:57 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/bootmem.h>
 #include <linux/swap.h>
+#include <linux/config.h>
 
 #include <asm/sgialib.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/bootinfo.h>
 
-/* #define DEBUG */
+#undef DEBUG
 
-struct linux_mdesc * __init prom_getmdesc(struct linux_mdesc *curr)
+extern char _end;
+
+struct linux_mdesc * __init
+ArcGetMemoryDescriptor(struct linux_mdesc *Current)
 {
-	return romvec->get_mdesc(curr);
+	return romvec->get_mdesc(Current);
 }
 
 #ifdef DEBUG /* convenient for debugging */
@@ -50,159 +55,185 @@
 #define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc]
 #endif
 
-static struct prom_pmemblock prom_pblocks[PROM_MAX_PMEMBLOCKS];
-
-struct prom_pmemblock * __init prom_getpblock_array(void)
-{
-	return &prom_pblocks[0];
-}
+static struct prom_pmemblock pblocks[PROM_MAX_PMEMBLOCKS];
 
 #define MEMTYPE_DONTUSE   0
 #define MEMTYPE_PROM      1
 #define MEMTYPE_FREE      2
 
-static int __init prom_memtype_classify (union linux_memtypes type)
+static inline int memtype_classify_arcs (union linux_memtypes type)
 {
-    if (prom_flags & PROM_FLAG_ARCS) {
 	switch (type.arcs) {
-	 case arcs_free:
-	 case arcs_fcontig:
-	    return MEMTYPE_FREE;
-	 case arcs_atmp:
-	 case arcs_aperm:
-	    return MEMTYPE_PROM;
-	 default:
-	    return MEMTYPE_DONTUSE;
+	case arcs_fcontig:
+	case arcs_free:
+		return MEMTYPE_FREE;
+	case arcs_atmp:
+		return MEMTYPE_PROM;
+	case arcs_eblock:
+	case arcs_rvpage:
+	case arcs_bmem:
+	case arcs_prog:
+	case arcs_aperm:
+		return MEMTYPE_DONTUSE;
+	default:
+		BUG();
 	}
-    } else {
+	while(1);				/* Nuke warning.  */
+}
+
+static inline int memtype_classify_arc (union linux_memtypes type)
+{
 	switch (type.arc) {
-	 case arc_free:
-	 case arc_fcontig:
-	    return MEMTYPE_FREE;
-	 case arc_rvpage:
-	 case arc_atmp:
-	 case arc_aperm:
-	    return MEMTYPE_PROM;
-	 default:
-	    return MEMTYPE_DONTUSE;
+	case arc_free:
+	case arc_fcontig:
+		return MEMTYPE_FREE;
+	case arc_atmp:
+		return MEMTYPE_PROM;
+	case arc_eblock:
+	case arc_rvpage:
+	case arc_bmem:
+	case arc_prog:
+	case arc_aperm:
+		return MEMTYPE_DONTUSE;
+	default:
+		BUG();
 	}
-    }
+	while(1);				/* Nuke warning.  */
 }
 
-static void __init prom_setup_memupper(void)
+static int __init prom_memtype_classify (union linux_memtypes type)
+{
+	if (prom_flags & PROM_FLAG_ARCS)	/* SGI is ``different'' ...  */
+		return memtype_classify_arcs(type);
+
+	return memtype_classify_arc(type);
+}
+
+static inline unsigned long find_max_low_pfn(void)
 {
 	struct prom_pmemblock *p, *highest;
+	unsigned long pfn;
 
-	for(p = prom_getpblock_array(), highest = 0; p->size != 0; p++) {
-		if(p->base == 0xdeadbeef)
-			prom_printf("WHEEE, bogus pmemblock\n");
-		if(!highest || p->base > highest->base)
+	p = pblocks;
+	highest = 0;
+	while (p->size != 0) {
+		if (!highest || p->base > highest->base)
 			highest = p;
+		p++;
 	}
-	mips_memory_upper = highest->base + highest->size;
+
+	pfn = (highest->base + highest->size) >> PAGE_SHIFT;
 #ifdef DEBUG
-	prom_printf("prom_setup_memupper: mips_memory_upper = %08lx\n",
-		    mips_memory_upper);
+	prom_printf("find_max_low_pfn: 0x%lx pfns.\n", pfn);
 #endif
+	return pfn;
+}
+
+static inline struct prom_pmemblock *find_largest_memblock(void)
+{
+	struct prom_pmemblock *p, *largest;
+
+	p = pblocks;
+	largest = 0;
+	while (p->size != 0) {
+		if (!largest || p->size > largest->size)
+			largest = p;
+		p++;
+	}
+
+	return largest;
 }
 
 void __init prom_meminit(void)
 {
+	struct prom_pmemblock *largest;
+	unsigned long bootmap_size;
 	struct linux_mdesc *p;
 	int totram;
 	int i = 0;
 
-	p = prom_getmdesc(PROM_NULL_MDESC);
 #ifdef DEBUG
 	prom_printf("ARCS MEMORY DESCRIPTOR dump:\n");
+	p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
 	while(p) {
 		prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
 			    i, p, p->base, p->pages, mtypes(p->type));
-		p = prom_getmdesc(p);
+		p = ArcGetMemoryDescriptor(p);
 		i++;
 	}
 #endif
-	p = prom_getmdesc(PROM_NULL_MDESC);
+
 	totram = 0;
 	i = 0;
-	while(p) {
-	    prom_pblocks[i].type = prom_memtype_classify (p->type);
-	    prom_pblocks[i].base = ((p->base<<PAGE_SHIFT) + 0x80000000);
-	    prom_pblocks[i].size = p->pages << PAGE_SHIFT;
-	    switch (prom_pblocks[i].type) {
-	     case MEMTYPE_FREE:
-		totram += prom_pblocks[i].size;
+	p = PROM_NULL_MDESC;
+	while ((p = ArcGetMemoryDescriptor(p))) {
+		pblocks[i].type = prom_memtype_classify(p->type);
+		pblocks[i].base = p->base << PAGE_SHIFT;
+		pblocks[i].size = p->pages << PAGE_SHIFT;
+
+		switch (pblocks[i].type) {
+		case MEMTYPE_FREE:
+			totram += pblocks[i].size;
 #ifdef DEBUG
-		prom_printf("free_chunk[%d]: base=%08lx size=%d\n",
-			    i, prom_pblocks[i].base,
-			    prom_pblocks[i].size);
+			prom_printf("free_chunk[%d]: base=%08lx size=%x\n",
+				    i, pblocks[i].base,
+				    pblocks[i].size);
 #endif
-		i++;
-		break;
-	     case MEMTYPE_PROM:
+			i++;
+			break;
+		case MEMTYPE_PROM:
 #ifdef DEBUG
-		prom_printf("prom_chunk[%d]: base=%08lx size=%d\n",
-			    i, prom_pblocks[i].base,
-			    prom_pblocks[i].size);
+			prom_printf("prom_chunk[%d]: base=%08lx size=%x\n",
+				    i, pblocks[i].base,
+				    pblocks[i].size);
 #endif
-		i++;
-		break;
-	     default:
-		break;
-	    }
-	    p = prom_getmdesc(p);
-	}
-	prom_pblocks[i].base = 0xdeadbeef;
-	prom_pblocks[i].size = 0; /* indicates last elem. of array */
-	printk("PROMLIB: Total free ram %d bytes (%dK,%dMB)\n",
-		    totram, (totram/1024), (totram/1024/1024));
+			i++;
+			break;
+		default:
+			break;
+		}
+	}
+	pblocks[i].size = 0;
 
-	/* Setup upper physical memory bound. */
-	prom_setup_memupper();
-}
+	max_low_pfn = find_max_low_pfn();
+	largest = find_largest_memblock();
+	bootmap_size = init_bootmem(largest->base >> PAGE_SHIFT, max_low_pfn);
 
-/* Called from mem_init() to fixup the mem_map page settings. */
-void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
-{
-	struct prom_pmemblock *p;
-	int i, nents;
+	for (i = 0; pblocks[i].size; i++)
+		if (pblocks[i].type == MEMTYPE_FREE)
+			free_bootmem(pblocks[i].base, pblocks[i].size);
 
-	/* Determine number of pblockarray entries. */
-	p = prom_getpblock_array();
-	for(i = 0; p[i].size; i++)
-		;
-	nents = i;
-restart:
-	while(start < end) {
-		for(i = 0; i < nents; i++) {
-			if((p[i].type == MEMTYPE_FREE) &&
-			   (start >= (p[i].base)) &&
-			   (start < (p[i].base + p[i].size))) {
-				start = p[i].base + p[i].size;
-				start &= PAGE_MASK;
-				goto restart;
-			}
-		}
-		set_bit(PG_reserved, &mem_map[MAP_NR(start)].flags);
-		start += PAGE_SIZE;
+	/* This test is simpleminded.  It will fail if the bootmem bitmap
+	   falls into multiple adjacent ARC memory areas.  */
+	if (bootmap_size > largest->size) {
+		prom_printf("CRITIAL: overwriting PROM data.\n");
+		BUG();
 	}
+	reserve_bootmem(largest->base, bootmap_size);
+
+	printk("PROMLIB: Total free ram %dK / %dMB.\n",
+	       totram >> 10, totram >> 20);
 }
 
-void prom_free_prom_memory (void)
+void __init
+prom_free_prom_memory (void)
 {
-    struct prom_pmemblock *p;
-    unsigned long addr;
-    unsigned long num_pages = 0;
+	struct prom_pmemblock *p;
+	unsigned long freed = 0;
+	unsigned long addr;
 
-    for(p = prom_getpblock_array(); p->size != 0; p++) {
-	if (p->type == MEMTYPE_PROM) {
-	    for (addr = p->base; addr < p->base + p->size; addr += PAGE_SIZE) {
-		mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
-		atomic_set(&mem_map[MAP_NR(addr)].count, 1);
-		free_page(addr);
-		num_pages++;
-	    }
+	for (p = pblocks; p->size != 0; p++) {
+		if (p->type != MEMTYPE_PROM)
+			continue;
+
+		addr = PAGE_OFFSET + p->base;
+		while (addr < p->base + p->size) {
+			ClearPageReserved(mem_map + MAP_NR(addr));
+			set_page_count(mem_map + MAP_NR(addr), 1);
+			free_page(addr);
+			addr += PAGE_SIZE;
+			freed += PAGE_SIZE;
+		}
 	}
-    }
-    printk ("Freeing prom memory: %dk freed\n",num_pages << (PAGE_SHIFT - 10));
+	printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/misc.c linux/arch/mips/arc/misc.c
--- v2.3.47/linux/arch/mips/arc/misc.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/arc/misc.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.1 1998/10/18 13:32:09 tsbogend Exp $
+/* $Id: misc.c,v 1.2 1999/10/09 00:00:57 ralf Exp $
  *
  * misc.c: Miscellaneous ARCS PROM routines.
  *
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/printf.c linux/arch/mips/arc/printf.c
--- v2.3.47/linux/arch/mips/arc/printf.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/arc/printf.c	Thu Feb 24 22:52:30 2000
@@ -4,9 +4,8 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@sgi.com)
  *
- * $Id: printf.c,v 1.2 1999/06/12 18:42:38 ulfc Exp $
+ * $Id: printf.c,v 1.3 1999/10/09 00:00:57 ralf Exp $
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/salone.c linux/arch/mips/arc/salone.c
--- v2.3.47/linux/arch/mips/arc/salone.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/arc/salone.c	Thu Feb 24 22:52:30 2000
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: salone.c,v 1.1 1998/10/18 13:32:09 tsbogend Exp $
+ * $Id: salone.c,v 1.2 1999/10/09 00:00:57 ralf Exp $
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/time.c linux/arch/mips/arc/time.c
--- v2.3.47/linux/arch/mips/arc/time.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/arc/time.c	Thu Feb 24 22:52:30 2000
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: time.c,v 1.1 1998/10/18 13:32:10 tsbogend Exp $
+ * $Id: time.c,v 1.2 1999/10/09 00:00:57 ralf Exp $
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/arc/tree.c linux/arch/mips/arc/tree.c
--- v2.3.47/linux/arch/mips/arc/tree.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/arc/tree.c	Thu Feb 24 22:52:30 2000
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: tree.c,v 1.1 1998/10/18 13:32:10 tsbogend Exp $
+ * $Id: tree.c,v 1.2 1999/10/09 00:00:57 ralf Exp $
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/Makefile linux/arch/mips/baget/Makefile
--- v2.3.47/linux/arch/mips/baget/Makefile	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/baget/Makefile	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-# $Id$
+# $Id: Makefile,v 1.3 1999/08/13 17:07:26 harald Exp $
 #
 # Makefile for the Baget specific kernel interface routines
 # under Linux.
@@ -15,7 +15,7 @@
 	cp -f $< $@
 
 O_TARGET := baget.a
-O_OBJS   := baget.o print.o setup.o time.o irq.o bagetIRQ.o reset.o wbflush.o
+O_OBJS   := baget.o print.o setup.o time.o irq.o bagetIRQ.o reset.o
 
 ifeq ($(CONFIG_SERIAL),y)
 	OX_OBJS += vacserial.o
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/baget.c linux/arch/mips/baget/baget.c
--- v2.3.47/linux/arch/mips/baget/baget.c	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/baget/baget.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: baget.c,v 1.1 1999/01/17 03:49:37 ralf Exp $
  *
  * baget.c: Baget low level stuff
  *
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/bagetIRQ.S linux/arch/mips/baget/bagetIRQ.S
--- v2.3.47/linux/arch/mips/baget/bagetIRQ.S	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/baget/bagetIRQ.S	Thu Feb 24 22:52:30 2000
@@ -1,11 +1,10 @@
-/* $Id$
+/* $Id: bagetIRQ.S,v 1.2 1999/08/18 23:37:42 ralf Exp $
  * bagetIRQ.S: Interrupt exception dispatch code for Baget/MIPS
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  */
 
 #include <asm/asm.h>
-#include <asm/mipsconfig.h>
 #include <asm/mipsregs.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/balo.c linux/arch/mips/baget/balo.c
--- v2.3.47/linux/arch/mips/baget/balo.c	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/baget/balo.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: balo.c,v 1.1 1999/01/17 03:49:37 ralf Exp $
  *
  * balo.c: BAget LOader
  *
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/balo_supp.S linux/arch/mips/baget/balo_supp.S
--- v2.3.47/linux/arch/mips/baget/balo_supp.S	Wed Jun 30 11:24:54 1999
+++ linux/arch/mips/baget/balo_supp.S	Thu Feb 24 22:52:30 2000
@@ -1,9 +1,10 @@
-/* $Id$
+/* $Id: balo_supp.S,v 1.1 1999/01/17 03:49:38 ralf Exp $
  * balo_supp.S: BAget Loader supplement
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  */
 
+#include <linux/config.h>
 #include <asm/asm.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/irq.c linux/arch/mips/baget/irq.c
--- v2.3.47/linux/arch/mips/baget/irq.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/baget/irq.c	Thu Feb 24 22:52:30 2000
@@ -5,7 +5,7 @@
  *      Code (mostly sleleton and comments) derived from DECstation IRQ
  *      handling.
  *
- * $Id$
+ * $Id: irq.c,v 1.6 2000/02/04 07:40:23 ralf Exp $
  */
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -33,8 +33,6 @@
 unsigned int local_irq_count[NR_CPUS];
 unsigned long spurious_count = 0;
 
-atomic_t __mips_bh_counter;
-
 /*
  * This table is a correspondence between IRQ numbers and CPU PILs
  */
@@ -142,15 +140,6 @@
 }
 
 /*
- * Data definition for static irqaction allocation.
- * It is used while SLAB module is not initialized.
- */
-
-#define MAX_STATIC_ALLOC 4 
-struct irqaction static_irqaction[MAX_STATIC_ALLOC];
-int static_irq_count = 0;
- 
-/*
  * Pointers to the low-level handlers: first the general ones, then the
  * fast ones, then the bad ones.
  */
@@ -193,7 +182,7 @@
 	int do_random, cpu;
 
 	cpu = smp_processor_id();
-	hardirq_enter(cpu);
+	irq_enter(cpu);
 	kstat.irqs[cpu][irq]++;
 
 	mask_irq(irq);  
@@ -215,7 +204,7 @@
 		printk("do_IRQ: Unregistered IRQ (0x%X) occured\n", irq);
 	}
 	unmask_irq(irq);
-	hardirq_exit(cpu);
+	irq_exit(cpu);
 
 	/* unmasking and bottom half handling is done magically for us. */
 }
@@ -319,7 +308,7 @@
 		void *dev_id)
 {
 	int retval;
-	struct irqaction * action = NULL;
+	struct irqaction * action;
 
 	if (irq >= BAGET_IRQ_NR)
 		return -EINVAL;
@@ -328,22 +317,8 @@
 	if (irq_to_pil_map[irq] < 0) 
 		return -EINVAL;
 
-        if (irqflags & SA_STATIC_ALLOC) {
-		unsigned long flags;
-
-		save_and_cli(flags);
-		if (static_irq_count < MAX_STATIC_ALLOC)
-			action = &static_irqaction[static_irq_count++];
-		else 
-			printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed "
-			       "using kmalloc\n", irq, devname);
-		restore_flags(flags);
-	}
-  
-	if (action == NULL)
-		action = (struct irqaction *)
+	action = (struct irqaction *)
 			kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-
 	if (!action) 
 		return -ENOMEM;
 
@@ -380,17 +355,6 @@
 		if (!irq[irq_action])
 			unmask_irq_count(irq);
 		restore_flags(flags);
-
-		if (action->flags & SA_STATIC_ALLOC)
-		{
-			/* This interrupt is marked as specially allocated
-			 * so it is a bad idea to free it.
-			 */
-			printk("Attempt to free statically allocated "
-			       "IRQ%d (%s)\n", irq, action->name);
-			return;
-		}
- 
 		kfree(action);
 		return;
 	}
@@ -422,6 +386,9 @@
 	*(volatile char*) BAGET_WRERR_ACK = 0;
 }
 
+static struct irqaction irq0  = 
+{ write_err_interrupt, SA_INTERRUPT, 0, "bus write error", NULL, NULL};
+
 void __init init_IRQ(void)
 {
 	irq_setup();
@@ -432,7 +399,6 @@
 	/* Enable interrupts for pils 2 and 3 (lines 0 and 1) */
 	modify_cp0_intmask(0, (1<<2)|(1<<3));
 
-	if (request_irq(0/*fixme*/, write_err_interrupt, 
-			SA_INTERRUPT|SA_STATIC_ALLOC, "write_err", NULL) < 0) 
+	if (setup_baget_irq(0, &irq0) < 0) 
 		printk("init_IRQ: unable to register write_err irq\n");
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/print.c linux/arch/mips/baget/print.c
--- v2.3.47/linux/arch/mips/baget/print.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/baget/print.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: print.c,v 1.2 1999/10/09 00:00:57 ralf Exp $
  *
  * print.c: Simple print fascility
  *
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/prom/Makefile linux/arch/mips/baget/prom/Makefile
--- v2.3.47/linux/arch/mips/baget/prom/Makefile	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/baget/prom/Makefile	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-# $Id$
+# $Id: Makefile,v 1.1 1999/01/17 03:49:40 ralf Exp $
 # Makefile for the Baget/MIPS prom emulator library routines.
 #
 # Note! Dependencies are done automagically by 'make dep', which also
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/prom/init.c linux/arch/mips/baget/prom/init.c
--- v2.3.47/linux/arch/mips/baget/prom/init.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/baget/prom/init.c	Thu Feb 24 22:52:30 2000
@@ -3,9 +3,10 @@
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov 
  *
- * $Id$
+ * $Id: init.c,v 1.3 1999/10/09 00:00:57 ralf Exp $
  */
 #include <linux/init.h>
+#include <linux/config.h>
 #include <asm/bootinfo.h>
 
 char arcs_cmdline[CL_SIZE];
@@ -17,4 +18,12 @@
 	mips_machtype   = MACH_UNKNOWN;
 	arcs_cmdline[0] = 0;
 	return 0;
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
+
+void prom_free_prom_memory (void)
+{
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/setup.c linux/arch/mips/baget/setup.c
--- v2.3.47/linux/arch/mips/baget/setup.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/baget/setup.c	Thu Feb 24 22:52:30 2000
@@ -1,10 +1,11 @@
-/* $Id$
+/* $Id: setup.c,v 1.4 1999/10/09 00:00:57 ralf Exp $
  *
  * setup.c: Baget/MIPS specific setup, including init of the feature struct.
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  *
  */
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -16,8 +17,6 @@
 
 extern long mips_memory_upper;
 
-extern void wbflush_setup(void);
-
 #define CACHEABLE_STR(val) ((val) ? "not cached" : "cached")
 #define MIN(a,b)           (((a)<(b)) ? (a):(b)) 
 		
@@ -480,8 +479,6 @@
 	printk("BT23/63-201n found.\n");
 	*BAGET_WRERR_ACK = 0;
 	irq_setup = baget_irq_setup;
-
-	wbflush_setup();
 
         _machine_restart   = baget_machine_restart;
         _machine_halt      = baget_machine_halt;
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/time.c linux/arch/mips/baget/time.c
--- v2.3.47/linux/arch/mips/baget/time.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/baget/time.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: time.c,v 1.4 1999/10/09 00:00:57 ralf Exp $
  * time.c: Baget/MIPS specific time handling details
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
@@ -63,14 +63,14 @@
 		 VIC_INT_LOW|VIC_INT_ENABLE, VIC_LINT2); 
 }
 
+static struct irqaction timer_irq  = 
+{ timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
+
 void __init time_init(void)
 {
-	if (request_irq(BAGET_VIC_TIMER_IRQ, timer_interrupt, 
-			SA_INTERRUPT|SA_STATIC_ALLOC, "timer", NULL) < 0) 
+	if (setup_baget_irq(BAGET_VIC_TIMER_IRQ, &timer_irq) < 0)
 		printk("time_init: unable request irq for system timer\n");
-
 	timer_enable();
-
 	/* We don't call sti() here, because it is too early for baget */
 }
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/vacserial.c linux/arch/mips/baget/vacserial.c
--- v2.3.47/linux/arch/mips/baget/vacserial.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/baget/vacserial.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: vacserial.c,v 1.4 1999/10/09 00:00:57 ralf Exp $
  * vacserial.c: VAC UART serial driver
  *              This code stealed and adopted from linux/drivers/char/serial.c
  *              See that for author info
@@ -22,7 +22,8 @@
 #define RS_STROBE_TIME (10*HZ)
 #define RS_ISR_PASS_LIMIT  2 /* Beget is not a super-computer (old=256) */
 
-#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
+#define IRQ_T(state) \
+ ((state->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
 
 #define SERIAL_INLINE
   
@@ -157,7 +158,7 @@
  * memory if large numbers of serial ports are open.
  */
 static unsigned char *tmp_buf;
-static struct semaphore tmp_buf_sem = MUTEX;
+static DECLARE_MUTEX(tmp_buf_sem);
 
 static inline int serial_paranoia_check(struct async_struct *info,
 					kdev_t device, const char *routine)
@@ -695,7 +696,7 @@
 			handler = rs_interrupt_single;
 
 
-		retval = request_irq(state->irq, handler, IRQ_T(info),
+		retval = request_irq(state->irq, handler, IRQ_T(state),
 				     "serial", NULL);
 		if (retval) {
 			if (capable(CAP_SYS_ADMIN)) {
@@ -813,7 +814,7 @@
 		if (IRQ_ports[state->irq]) {
 			free_irq(state->irq, NULL);
 			retval = request_irq(state->irq, rs_interrupt_single,
-					     IRQ_T(info), "serial", NULL);
+					     IRQ_T(state), "serial", NULL);
 			
 			if (retval)
 				printk("serial shutdown: request_irq: error %d"
@@ -912,6 +913,8 @@
 
 	/* Determine divisor based on baud rate */
 	baud = tty_get_baud_rate(info->tty);
+	if (!baud)
+		baud = 9600;    /* B0 transition handled in rs_set_termios */
 	baud_base = info->state->baud_base;
 	if (baud == 38400 &&
 	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
@@ -1357,7 +1360,7 @@
 check_and_exit:
 	if (!state->port || !state->type)
 		return 0;
-	if (state->flags & ASYNC_INITIALIZED) {
+	if (info->flags & ASYNC_INITIALIZED) {
 		if (((old_state.flags & ASYNC_SPD_MASK) !=
 		     (state->flags & ASYNC_SPD_MASK)) ||
 		    (old_state.custom_divisor != state->custom_divisor)) {
@@ -1603,8 +1606,9 @@
 static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
 {
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	
-	if (   (tty->termios->c_cflag == old_termios->c_cflag)
+	unsigned int cflag = tty->termios->c_cflag;
+
+	if (   (cflag == old_termios->c_cflag)
 	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
 		== RELEVANT_IFLAG(old_termios->c_iflag)))
 	  return;
@@ -1613,7 +1617,7 @@
 
 	/* Handle turning off CRTSCTS */
 	if ((old_termios->c_cflag & CRTSCTS) &&
-	    !(tty->termios->c_cflag & CRTSCTS)) {
+	    !(cflag & CRTSCTS)) {
 		tty->hw_stopped = 0;
 		rs_start(tty);
 	}
@@ -1820,7 +1824,7 @@
 static int block_til_ready(struct tty_struct *tty, struct file * filp,
 			   struct async_struct *info)
 {
-	struct wait_queue wait = { current, NULL };
+	DECLARE_WAITQUEUE(wait, current);
 	struct serial_state *state = info->state;
 	int		retval;
 	int		do_clocal = 0,  extra_count = 0;  
@@ -1960,6 +1964,9 @@
 		return -ENOMEM;
 	}
 	memset(info, 0, sizeof(struct async_struct));
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	init_waitqueue_head(&info->delta_msr_wait);
 	info->magic = SERIAL_MAGIC;
 	info->port = sstate->port;
 	info->flags = sstate->flags;
diff -u --recursive --new-file v2.3.47/linux/arch/mips/baget/wbflush.c linux/arch/mips/baget/wbflush.c
--- v2.3.47/linux/arch/mips/baget/wbflush.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/baget/wbflush.c	Thu Feb 24 22:52:30 2000
@@ -4,8 +4,8 @@
  * Copyright (C) 1999 Gleb Raiko & Vladimir Roganov
  */
 
+#include <linux/init.h>
 #include <asm/bootinfo.h>
-#include <asm/init.h>
 
 void (*__wbflush) (void);
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/boot/Makefile linux/arch/mips/boot/Makefile
--- v2.3.47/linux/arch/mips/boot/Makefile	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/boot/Makefile	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.9 1999/04/07 18:45:23 harald Exp $
+# $Id: Makefile,v 1.10 1999/10/17 19:55:22 harald Exp $
 #
 # This file is subject to the terms and conditions of the GNU General Public
 # License.  See the file "COPYING" in the main directory of this archive
@@ -46,6 +46,8 @@
 
 clean:
 	rm -f vmlinux.ecoff
+	rm -f addinitrd
+	rm -f elf2ecoff
 
 dummy:
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/config.in linux/arch/mips/config.in
--- v2.3.47/linux/arch/mips/config.in	Wed Dec  8 14:11:25 1999
+++ linux/arch/mips/config.in	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.27 1999/06/17 13:25:44 ralf Exp $
+# $Id: config.in,v 1.42 2000/02/24 00:12:40 ralf Exp $
 # For a description of the syntax of this configuration file,
 # see the Configure script.
 #
@@ -16,16 +16,18 @@
    bool 'Support for Algorithmics P4032 (EXPERIMENTAL)' CONFIG_ALGOR_P4032
    bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS
    bool 'Support for DECstations (EXPERIMENTAL)' CONFIG_DECSTATION
+   bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074
 fi
 bool 'Support for Mips Magnum 4000' CONFIG_MIPS_MAGNUM_4000
 bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700
-bool 'Support for SGI workstations' CONFIG_SGI
+bool 'Support for SGI IP22' CONFIG_SGI_IP22
 bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
 
 #
 # Select some configuration options automatically for certain systems.
 #
 unset CONFIG_PCI
+unset CONFIG_ISA
 unset CONFIG_MIPS_JAZZ
 unset CONFIG_VIDEO_G364
 
@@ -34,22 +36,44 @@
 fi
 if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
      "$CONFIG_OLIVETTI_M700" = "y" ]; then
+   define_bool CONFIG_ISA y
+   define_bool CONFIG_HAVE_IO_PORTS y
    define_bool CONFIG_MIPS_JAZZ y
    define_bool CONFIG_FB y
    define_bool CONFIG_FB_G364 y	
 fi
 if [ "$CONFIG_ACER_PICA_61" = "y" ]; then
+   define_bool CONFIG_ISA y
+   define_bool CONFIG_HAVE_IO_PORTS y
    define_bool CONFIG_MIPS_JAZZ y
 fi
 if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
+   define_bool CONFIG_ISA y
+   define_bool CONFIG_HAVE_IO_PORTS y
    define_bool CONFIG_PCI y
 fi
+if [ "$CONFIG_DDB5074" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_HAVE_IO_PORTS y
+fi
 endmenu
 
 mainmenu_option next_comment
 comment 'CPU selection'
 
-choice 'CPU type' \
+if [ "$CONFIG_CPU_ADVANCED" = "y" ]; then
+    choice 'CPU core' \
+	"R3000 CONFIG_CPU_R3000	\
+	 R4300 CONFIG_CPU_R4300	\
+	 R4x00 CONFIG_CPU_R4X00	\
+	 R5000 CONFIG_CPU_R5000	\
+	 R56x0 CONFIG_CPU_NEVADA \
+	 R10000 CONFIG_CPU_R10000" R4x00
+
+    bool '  ll/sc Instructions available' CONFIG_CPU_HAS_LLSC
+    bool '  Writeback Buffer available' CONFIG_CPU_HAS_WB
+else
+    choice 'CPU type' \
 	"R3000 CONFIG_CPU_R3000	\
 	 R6000 CONFIG_CPU_R6000	\
 	 R4300 CONFIG_CPU_R4300	\
@@ -57,13 +81,28 @@
 	 R5000 CONFIG_CPU_R5000	\
 	 R56x0 CONFIG_CPU_NEVADA \
 	 R8000 CONFIG_CPU_R8000	\
-	 R10000 CONFIG_CPU_R10000" R4x00
+	 R10000 CONFIG_CPU_R10000 \
+         Advanced CONFIG_CPU_ADVANCED" R4x00
+
+    if [ "$CONFIG_CPU_R3000" = "y" ]; then
+        if [ "$CONFIG_DECSTATION" = "y" ]; then
+            define_bool CONFIG_CPU_HAS_LLSC n
+            define_bool CONFIG_CPU_HAS_WB y
+        else
+            define_bool CONFIG_CPU_HAS_LLSC n
+            define_bool CONFIG_CPU_HAS_WB n
+        fi
+    else
+        define_bool CONFIG_CPU_HAS_LLSC y
+        define_bool CONFIG_CPU_HAS_WB n
+    fi
+fi
 endmenu
 
 mainmenu_option next_comment
 comment 'General setup'
 
-if [ "$CONFIG_DECSTATION" = "y" ]; then
+if [ "$CONFIG_DECSTATION" = "y" -o "$CONFIG_DDB5074" = "y" ]; then
    define_bool CONFIG_CPU_LITTLE_ENDIAN y
 else
    bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
@@ -83,11 +122,15 @@
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
 bool 'Networking support' CONFIG_NET
+
+source drivers/pci/Config.in
+source drivers/pcmcia/Config.in
+
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
 
-if [ "$CONFIG_SGI" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then
+if [ "$CONFIG_SGI_IP22" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then
    source drivers/parport/Config.in
 fi
 endmenu
@@ -114,8 +157,6 @@
    endmenu
 fi
 
-source drivers/i2o/Config.in
-
 source drivers/pnp/Config.in
 
 source drivers/block/Config.in
@@ -180,7 +221,8 @@
 	    comment '    CCP compressors for PPP are only built as modules.'
 	 fi
          if [ "$CONFIG_SGI" = "y" ]; then
-	 bool '  SGI Seeq ethernet controller support' CONFIG_SGISEEQ
+            bool '  SGI Seeq ethernet controller support' CONFIG_SGISEEQ
+         fi
       fi
       if [ "$CONFIG_DECSTATION" = "y" ]; then
          bool '  DEC LANCE ethernet controller support' CONFIG_DECLANCE
@@ -208,7 +250,6 @@
    fi
    endmenu
 
-
    mainmenu_option next_comment
    comment 'Old CD-ROM drivers (not SCSI, not IDE)'
 
@@ -227,18 +268,18 @@
 
    bool 'Virtual terminal' CONFIG_VT
    if [ "$CONFIG_VT" = "y" ]; then
-      bool '  Support for console on virtual terminal' CONFIG_VT_CONSOLE
+      bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE
    fi
-   if [ "$CONFIG_SGI" = "y" ]; then
+   tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL
+   if [ "$CONFIG_SGI_IP22" = "y" ]; then
       bool 'SGI PROM Console Support' CONFIG_SGI_PROM_CONSOLE
    fi
-   tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL
    if [ "$CONFIG_SERIAL" = "y" ]; then
-      bool '  DZ11 Serial Support' CONFIG_DZ
+      bool 'DZ11 Serial Support' CONFIG_DZ
       if [ "$CONFIG_TC" = "y" ]; then
-	 bool '  Z85C30 Serial Support' CONFIG_ZS
+	 bool 'Z85C30 Serial Support' CONFIG_ZS
       fi
-      bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE
+   bool '   Support for console on serial port' CONFIG_SERIAL_CONSOLE
    fi
    bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
    if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
@@ -246,29 +287,33 @@
    fi
    bool 'Keyboard Support' CONFIG_KEYBOARD
    bool 'Mouse Support' CONFIG_MOUSE
-#   bool 'Enhanced Real Time Clock Support' CONFIG_RTC
+#    bool 'Enhanced Real Time Clock Support' CONFIG_RTC
    endmenu
 fi
 
 source drivers/usb/Config.in
 
+source drivers/misc/Config.in
+
 source fs/Config.in
 
 if [ "$CONFIG_VT" = "y" ]; then
    mainmenu_option next_comment
    comment 'Console drivers'
-   if [ "$CONFIG_SGI" = "y" ]; then
+   if [ "$CONFIG_SGI_IP22" = "y" ]; then
       tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
       if [ "$CONFIG_SGI_NEWPORT_CONSOLE" != "y" ]; then
-         define_bool CONFIG_DUMMY_CONSOLE y
+	 define_bool CONFIG_DUMMY_CONSOLE y
+      else
+         define_bool CONFIG_FONT_8x16 y
       fi
    else
       if [ "$CONFIG_DECSTATION" != "y" ]; then
 	 bool 'VGA text console' CONFIG_VGA_CONSOLE
       fi
-      bool 'Support for frame buffer devices' CONFIG_FB
+	 bool 'Support for frame buffer devices' CONFIG_FB
 	 source drivers/video/Config.in
-      fi
+   fi
    endmenu
 fi
 
@@ -283,7 +328,7 @@
    endmenu
 fi
 
-if [ "$CONFIG_SGI" = "y" ]; then
+if [ "$CONFIG_SGI_IP22" = "y" ]; then
    source drivers/sgi/Config.in
 fi
 
@@ -296,7 +341,7 @@
    bool ' Build fp execption handler module' CONFIG_MIPS_FPE_MODULE
 fi
 if [ "$CONFIG_SERIAL" = "y" ]; then
-   bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
+  bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
 fi
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
diff -u --recursive --new-file v2.3.47/linux/arch/mips/ddb5074/Makefile linux/arch/mips/ddb5074/Makefile
--- v2.3.47/linux/arch/mips/ddb5074/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5074/Makefile	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,22 @@
+#
+# Makefile for the NEC DDB Vrc-5074 specific kernel interface routines
+# under Linux.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+#
+# $Id: Makefile,v 1.1 2000/01/26 00:07:44 ralf Exp $
+#
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET = ddb5074.a
+O_OBJS  = setup.o irq.o time.o prom.o pci.o int-handler.o nile4.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.47/linux/arch/mips/ddb5074/int-handler.S linux/arch/mips/ddb5074/int-handler.S
--- v2.3.47/linux/arch/mips/ddb5074/int-handler.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5074/int-handler.S	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,124 @@
+/*
+ *  arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler
+ *
+ *  Based on arch/mips/sgi/kernel/indyIRQ.S
+ *
+ *  Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Suprastructure Center Europe (SUPC-E), Brussels
+ *
+ *  $Id: int-handler.S,v 1.2 2000/01/27 02:06:56 ralf Exp $
+ */
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	/* A lot of complication here is taken away because:
+	 *
+	 * 1) We handle one interrupt and return, sitting in a loop
+	 *    and moving across all the pending IRQ bits in the cause
+	 *    register is _NOT_ the answer, the common case is one
+	 *    pending IRQ so optimize in that direction.
+	 *
+	 * 2) We need not check against bits in the status register
+	 *    IRQ mask, that would make this routine slow as hell.
+	 *
+	 * 3) Linux only thinks in terms of all IRQs on or all IRQs
+	 *    off, nothing in between like BSD spl() brain-damage.
+	 *
+	 * Furthermore, the IRQs on the INDY look basically (barring
+	 * software IRQs which we don't use at all) like:
+	 *
+	 *	MIPS IRQ	Source
+	 *      --------        ------
+	 *             0	Software (ignored)
+	 *             1        Software (ignored)
+	 *             2        Local IRQ level zero
+	 *             3        Local IRQ level one
+	 *             4        8254 Timer zero
+	 *             5        8254 Timer one
+	 *             6        Bus Error
+	 *             7        R4k timer (what we use)
+	 *
+	 * We handle the IRQ according to _our_ priority which is:
+	 *
+	 * Highest ----     R4k Timer
+	 *                  Local IRQ zero
+	 *                  Local IRQ one
+	 *                  Bus Error
+	 *                  8254 Timer zero
+	 * Lowest  ----     8254 Timer one
+	 *
+	 * then we just return, if multiple IRQs are pending then
+	 * we will just take another exception, big deal.
+	 */
+
+	.text
+	.set	noreorder
+	.set	noat
+	.align	5
+	NESTED(ddbIRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	mfc0	s0, CP0_CAUSE		# get irq mask
+
+#if 1
+	mfc0	t2,CP0_STATUS		# get enabled interrupts
+	and	s0,t2			# isolate allowed ones
+#endif
+	/* First we check for r4k counter/timer IRQ. */
+	andi	a0, s0, CAUSEF_IP2	# delay slot, check local level zero
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP3	# delay slot, check local level one
+
+	/* Wheee, local level zero interrupt. */
+	jal	ddb_local0_irqdispatch
+	 move	a0, sp			# delay slot
+
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP6	# delay slot, check bus error
+
+	/* Wheee, local level one interrupt. */
+	move	a0, sp
+	jal	ddb_local1_irqdispatch
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+	beq	a0, zero, 1f
+	 nop
+
+	/* Wheee, an asynchronous bus error... */
+	move	a0, sp
+	jal	ddb_buserror_irq
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+	/* Here by mistake?  This is possible, what can happen
+	 * is that by the time we take the exception the IRQ
+	 * pin goes low, so just leave if this is the case.
+	 */
+	andi	a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
+	beq	a0, zero, 1f
+
+	/* Must be one of the 8254 timers... */
+	move	a0, sp
+	jal	ddb_8254timer_irq
+	 nop
+1:
+	j	ret_from_irq
+	 nop
+	END(ddbIRQ)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/ddb5074/irq.c linux/arch/mips/ddb5074/irq.c
--- v2.3.47/linux/arch/mips/ddb5074/irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5074/irq.c	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,230 @@
+/*
+ *  arch/mips/ddb5074/irq.c -- NEC DDB Vrc-5074 interrupt routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Suprastructure Center Europe (SUPC-E), Brussels
+ *
+ *  $Id: irq.c,v 1.1 2000/01/26 00:07:44 ralf Exp $
+ */
+
+#include <linux/init.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/ptrace.h>
+#include <asm/nile4.h>
+#include <asm/ddb5074.h>
+
+
+extern void __init i8259_init(void);
+extern void i8259_disable_irq(unsigned int irq_nr);
+extern void i8259_enable_irq(unsigned int irq_nr);
+
+extern asmlinkage void ddbIRQ(void);
+extern asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs);
+extern asmlinkage void do_IRQ(int irq, struct pt_regs * regs);
+
+
+static void no_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+}
+
+
+#define M1543_PNP_CONFIG	0x03f0	/* PnP Config Port */
+#define M1543_PNP_INDEX		0x03f0	/* PnP Index Port */
+#define M1543_PNP_DATA		0x03f1	/* PnP Data Port */
+
+#define M1543_PNP_ALT_CONFIG	0x0370	/* Alternative PnP Config Port */
+#define M1543_PNP_ALT_INDEX	0x0370	/* Alternative PnP Index Port */
+#define M1543_PNP_ALT_DATA	0x0371	/* Alternative PnP Data Port */
+
+#define M1543_INT1_MASTER_CTRL	0x0020	/* INT_1 (master) Control Register */
+#define M1543_INT1_MASTER_MASK	0x0021	/* INT_1 (master) Mask Register */
+
+#define M1543_INT1_SLAVE_CTRL	0x00a0	/* INT_1 (slave) Control Register */
+#define M1543_INT1_SLAVE_MASK	0x00a1	/* INT_1 (slave) Mask Register */
+
+#define M1543_INT1_MASTER_ELCR	0x04d0	/* INT_1 (master) Edge/Level Control */
+#define M1543_INT1_SLAVE_ELCR	0x04d1	/* INT_1 (slave) Edge/Level Control */
+
+
+static void m1543_irq_setup(void)
+{
+    /*
+     *  The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13.  Not all
+     *  the possible IO sources in the M1543 are in use by us.  We will
+     *  use the following mapping:
+     *
+     *	    IRQ1  - keyboard (default set by M1543)
+     *	    IRQ3  - reserved for UART B (default set by M1543) (note that
+     *		    the schematics for the DDB Vrc-5074 board seem to 
+     *		    indicate that IRQ3 is connected to the DS1386 
+     *		    watchdog timer interrupt output so we might have 
+     *		    a conflict)
+     *	    IRQ4  - reserved for UART A (default set by M1543)
+     *	    IRQ5  - parallel (default set by M1543)
+     *	    IRQ8  - DS1386 time of day (RTC) interrupt
+     *	    IRQ12 - mouse
+     */
+ 
+    /*
+     *  Assing mouse interrupt to IRQ12 
+     */
+
+    /* Enter configuration mode */
+    outb(0x51, M1543_PNP_CONFIG);
+    outb(0x23, M1543_PNP_CONFIG);
+
+    /* Select logical device 7 (Keyboard) */
+    outb(0x07, M1543_PNP_INDEX);
+    outb(0x07, M1543_PNP_DATA);
+
+    /* Select IRQ12 */
+    outb(0x72, M1543_PNP_INDEX);
+    outb(0x0c, M1543_PNP_DATA);
+
+    /* Leave configration mode */
+    outb(0xbb, M1543_PNP_CONFIG);
+
+
+    /* Initialize the 8259 PIC in the M1543 */
+    i8259_init();
+
+    /* Enable the interrupt cascade */
+    nile4_enable_irq(NILE4_INT_INTE);
+
+    request_region(M1543_PNP_CONFIG, 2, "M1543 config");
+    request_region(M1543_INT1_MASTER_ELCR, 2, "pic ELCR");
+}
+
+static void nile4_irq_setup(void)
+{
+    int i;
+
+    /* Map all interrupts to CPU int #0 */
+    nile4_map_irq_all(0);
+
+    /* PCI INTA#-E# must be level triggered */
+    nile4_set_pci_irq_level_or_edge(0, 1);
+    nile4_set_pci_irq_level_or_edge(1, 1);
+    nile4_set_pci_irq_level_or_edge(2, 1);
+    nile4_set_pci_irq_level_or_edge(3, 1);
+    nile4_set_pci_irq_level_or_edge(4, 1);
+
+    /* PCI INTA#-D# must be active low, INTE# must be active high */
+    nile4_set_pci_irq_polarity(0, 0);
+    nile4_set_pci_irq_polarity(1, 0);
+    nile4_set_pci_irq_polarity(2, 0);
+    nile4_set_pci_irq_polarity(3, 0);
+    nile4_set_pci_irq_polarity(4, 1);
+
+    for (i = 0; i < 16; i++)
+	nile4_clear_irq(i);
+
+    /* Enable CPU int #0 */
+    nile4_enable_irq_output(0);
+
+    request_mem_region(NILE4_BASE, NILE4_SIZE, "Nile 4");
+}
+
+
+/*
+ * IRQ2 is cascade interrupt to second interrupt controller
+ */
+
+static struct irqaction irq2  = { no_action, 0, 0, "cascade", NULL, NULL };
+
+
+void disable_irq(unsigned int irq_nr)
+{
+    if (is_i8259_irq(irq_nr))
+	i8259_disable_irq(irq_nr);
+    else
+	nile4_disable_irq(irq_to_nile4(irq_nr));
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+    if (is_i8259_irq(irq_nr))
+	i8259_enable_irq(irq_nr);
+    else
+	nile4_enable_irq(irq_to_nile4(irq_nr));
+}
+
+int table[16] = { 0, };
+
+void ddb_local0_irqdispatch(struct pt_regs *regs)
+{
+    u32 mask;
+    int nile4_irq;
+#if 1
+    volatile static int nesting = 0;
+    if (nesting++ == 0)
+	ddb5074_led_d3(1);
+    ddb5074_led_hex(nesting < 16 ? nesting : 15);
+#endif
+
+    mask = nile4_get_irq_stat(0);
+    nile4_clear_irq_mask(mask);
+
+    /* Handle the timer interrupt first */
+    if (mask & (1<<NILE4_INT_GPT)) {
+	nile4_disable_irq(NILE4_INT_GPT);
+	do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs);
+	nile4_enable_irq(NILE4_INT_GPT);
+	mask &= ~(1<<NILE4_INT_GPT);
+    }
+    for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1)
+	if (mask & 1) {
+	    nile4_disable_irq(nile4_irq);
+	    if (nile4_irq == NILE4_INT_INTE) {
+		int i8259_irq = nile4_i8259_iack();
+		i8259_do_irq(i8259_irq, regs);
+	    } else
+		do_IRQ(nile4_to_irq(nile4_irq), regs);
+	    nile4_enable_irq(nile4_irq);
+	}
+
+#if 1
+    if (--nesting == 0)
+	ddb5074_led_d3(0);
+    ddb5074_led_hex(nesting < 16 ? nesting : 15);
+#endif
+}
+
+void ddb_local1_irqdispatch(void)
+{
+    printk("ddb_local1_irqdispatch called\n");
+}
+
+void ddb_buserror_irq(void)
+{
+    printk("ddb_buserror_irq called\n");
+}
+
+void ddb_8254timer_irq(void)
+{
+    printk("ddb_8254timer_irq called\n");
+}
+
+void __init ddb_irq_setup(void)
+{
+#ifdef CONFIG_REMOTE_DEBUG
+    if (remote_debug)
+	set_debug_traps();
+    breakpoint(); /* you may move this line to whereever you want :-) */
+#endif
+    request_region(0x20, 0x20, "pic1");
+    request_region(0xa0, 0x20, "pic2");
+    i8259_setup_irq(2, &irq2);
+
+    nile4_irq_setup();
+    m1543_irq_setup();
+
+    set_except_vector(0, ddbIRQ);
+}
+
diff -u --recursive --new-file v2.3.47/linux/arch/mips/ddb5074/nile4.c linux/arch/mips/ddb5074/nile4.c
--- v2.3.47/linux/arch/mips/ddb5074/nile4.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5074/nile4.c	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,294 @@
+/*
+ *  arch/mips/ddb5074/nile4.c -- NEC Vrc-5074 Nile 4 support routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Suprastructure Center Europe (SUPC-E), Brussels
+ *
+ *  $Id: nile4.c,v 1.1 2000/01/26 00:07:44 ralf Exp $
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/nile4.h>
+
+
+    /*
+     *  Physical Device Address Registers
+     *
+     *  Note: 32 bit addressing only!
+     */
+
+void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width, int on_memory_bus,
+		    int visible)
+{
+    u32 maskbits;
+    u32 widthbits;
+
+    if (pdar > NILE4_BOOTCS || (pdar & 7)) {
+	printk("nile4_set_pdar: invalid pdar %d\n", pdar);
+	return;
+    }
+    if (pdar == NILE4_INTCS && size != 0x00200000) {
+	printk("nile4_set_pdar: INTCS size must be 2 MB\n");
+	return;
+    }
+    switch (size) {
+#if 0	/* We don't support 4 GB yet */
+	case 0x100000000:	/* 4 GB */
+	    maskbits = 4;
+	    break;
+#endif
+	case 0x80000000:	/* 2 GB */
+	    maskbits = 5;
+	    break;
+	case 0x40000000:	/* 1 GB */
+	    maskbits = 6;
+	    break;
+	case 0x20000000:	/* 512 MB */
+	    maskbits = 7;
+	    break;
+	case 0x10000000:	/* 256 MB */
+	    maskbits = 8;
+	    break;
+	case 0x08000000:	/* 128 MB */
+	    maskbits = 9;
+	    break;
+	case 0x04000000:	/* 64 MB */
+	    maskbits = 10;
+	    break;
+	case 0x02000000:	/* 32 MB */
+	    maskbits = 11;
+	    break;
+	case 0x01000000:	/* 16 MB */
+	    maskbits = 12;
+	    break;
+	case 0x00800000:	/* 8 MB */
+	    maskbits = 13;
+	    break;
+	case 0x00400000:	/* 4 MB */
+	    maskbits = 14;
+	    break;
+	case 0x00200000:	/* 2 MB */
+	    maskbits = 15;
+	    break;
+	case 0:			/* OFF */
+	    maskbits = 0;
+	    break;
+	default:
+	    printk("nile4_set_pdar: unsupported size %p\n", (void *)size);
+	    return;
+    }
+    switch (width) {
+	case 8:
+	    widthbits = 0;
+	    break;
+	case 16:
+	    widthbits = 1;
+	    break;
+	case 32:
+	    widthbits = 2;
+	    break;
+	case 64:
+	    widthbits = 3;
+	    break;
+	default:
+	    printk("nile4_set_pdar: unsupported width %d\n", width);
+	    return;
+    }
+    nile4_out32(pdar, maskbits | (on_memory_bus ? 0x10 : 0) |
+    		      (visible ? 0x20 : 0) | (widthbits << 6) |
+		      (phys & 0xffe00000));
+    nile4_out32(pdar+4, 0);
+    /*
+     *  When programming a PDAR, the register should be read immediately after
+     *  writing it. This ensures that address decoders are properly configured.
+     */
+    (void)nile4_in32(pdar);
+    (void)nile4_in32(pdar+4);
+}
+
+
+    /*
+     *  PCI Master Registers
+     *
+     *  Note: 32 bit addressing only!
+     */
+
+void nile4_set_pmr(u32 pmr, u32 type, u32 addr)
+{
+    if (pmr != NILE4_PCIINIT0 && pmr != NILE4_PCIINIT1) {
+	printk("nile4_set_pmr: invalid pmr %d\n", pmr);
+	return;
+    }
+    switch (type) {
+	case NILE4_PCICMD_IACK:	/* PCI Interrupt Acknowledge */
+	case NILE4_PCICMD_IO:	/* PCI I/O Space */
+	case NILE4_PCICMD_MEM:	/* PCI Memory Space */
+	case NILE4_PCICMD_CFG:	/* PCI Configuration Space */
+	    break;
+	default:
+	    printk("nile4_set_pmr: invalid type %d\n", type);
+	    return;
+    }
+    nile4_out32(pmr, (type << 1) | 0x10 | (addr & 0xffe00000));
+    nile4_out32(pmr+4, 0);
+}
+
+
+    /*
+     *  Interrupt Programming
+     */
+
+void nile4_map_irq(int nile4_irq, int cpu_irq)
+{
+    u32 offset, t;
+
+    offset = NILE4_INTCTRL;
+    if (nile4_irq >= 8) {
+	offset += 4;
+	nile4_irq -= 8;
+    }
+    t = nile4_in32(offset);
+    t &= ~(7 << (nile4_irq*4));
+    t |= cpu_irq << (nile4_irq*4);
+    nile4_out32(offset, t);
+}
+
+void nile4_map_irq_all(int cpu_irq)
+{
+    u32 all, t;
+    
+    all = cpu_irq;
+    all |= all << 4;
+    all |= all << 8;
+    all |= all << 16;
+    t = nile4_in32(NILE4_INTCTRL);
+    t &= 0x88888888;
+    t |= all;
+    nile4_out32(NILE4_INTCTRL, t);
+    t = nile4_in32(NILE4_INTCTRL+4);
+    t &= 0x88888888;
+    t |= all;
+    nile4_out32(NILE4_INTCTRL+4, t);
+}
+
+void nile4_enable_irq(int nile4_irq)
+{
+    u32 offset, t;
+
+    offset = NILE4_INTCTRL;
+    if (nile4_irq >= 8) {
+	offset += 4;
+	nile4_irq -= 8;
+    }
+    t = nile4_in32(offset);
+    t |= 8 << (nile4_irq*4);
+    nile4_out32(offset, t);
+}
+
+void nile4_disable_irq(int nile4_irq)
+{
+    u32 offset, t;
+
+    offset = NILE4_INTCTRL;
+    if (nile4_irq >= 8) {
+	offset += 4;
+	nile4_irq -= 8;
+    }
+    t = nile4_in32(offset);
+    t &= ~(8 << (nile4_irq*4));
+    nile4_out32(offset, t);
+}
+
+void nile4_disable_irq_all(void)
+{
+    nile4_out32(NILE4_INTCTRL, 0);
+    nile4_out32(NILE4_INTCTRL+4, 0);
+}
+
+u16 nile4_get_irq_stat(int cpu_irq)
+{
+    return nile4_in16(NILE4_INTSTAT0+cpu_irq*2);
+}
+
+void nile4_enable_irq_output(int cpu_irq)
+{
+    u32 t;
+
+    t = nile4_in32(NILE4_INTSTAT1+4);
+    t |= 1 << (16+cpu_irq);
+    nile4_out32(NILE4_INTSTAT1, t);
+}
+
+void nile4_disable_irq_output(int cpu_irq)
+{
+    u32 t;
+
+    t = nile4_in32(NILE4_INTSTAT1+4);
+    t &= ~(1 << (16+cpu_irq));
+    nile4_out32(NILE4_INTSTAT1, t);
+}
+
+void nile4_set_pci_irq_polarity(int pci_irq, int high)
+{
+    u32 t;
+
+    t = nile4_in32(NILE4_INTPPES);
+    if (high)
+	t &= ~(1 << (pci_irq*2));
+    else
+	t |= 1 << (pci_irq*2);
+    nile4_out32(NILE4_INTPPES, t);
+}
+
+void nile4_set_pci_irq_level_or_edge(int pci_irq, int level)
+{
+    u32 t;
+
+    t = nile4_in32(NILE4_INTPPES);
+    if (level)
+	t |= 2 << (pci_irq*2);
+    else
+	t &= ~(2 << (pci_irq*2));
+    nile4_out32(NILE4_INTPPES, t);
+}
+
+void nile4_clear_irq(int nile4_irq)
+{
+    nile4_out32(NILE4_INTCLR, 1 << nile4_irq);
+}
+
+void nile4_clear_irq_mask(u32 mask)
+{
+    nile4_out32(NILE4_INTCLR, mask);
+}
+
+u8 nile4_i8259_iack(void)
+{
+    u8 irq;
+
+    /* Set window 0 for interrupt acknowledge */
+    nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IACK, 0);
+    irq = *(volatile u8 *)NILE4_PCI_IACK_BASE;
+    /* Set window 0 for PCI I/O space */
+    nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0);
+    return irq;
+}
+
+#if 0
+void nile4_dump_irq_status(void)
+{
+    printk("CPUSTAT = %p:%p\n", (void *)nile4_in32(NILE4_CPUSTAT+4),
+    				(void *)nile4_in32(NILE4_CPUSTAT));
+    printk("INTCTRL = %p:%p\n", (void *)nile4_in32(NILE4_INTCTRL+4),
+    				(void *)nile4_in32(NILE4_INTCTRL));
+    printk("INTSTAT0 = %p:%p\n", (void *)nile4_in32(NILE4_INTSTAT0+4),
+    				(void *)nile4_in32(NILE4_INTSTAT0));
+    printk("INTSTAT1 = %p:%p\n", (void *)nile4_in32(NILE4_INTSTAT1+4),
+    				(void *)nile4_in32(NILE4_INTSTAT1));
+    printk("INTCLR = %p:%p\n", (void *)nile4_in32(NILE4_INTCLR+4),
+    				(void *)nile4_in32(NILE4_INTCLR));
+    printk("INTPPES = %p:%p\n", (void *)nile4_in32(NILE4_INTPPES+4),
+    				(void *)nile4_in32(NILE4_INTPPES));
+}
+#endif
diff -u --recursive --new-file v2.3.47/linux/arch/mips/ddb5074/pci.c linux/arch/mips/ddb5074/pci.c
--- v2.3.47/linux/arch/mips/ddb5074/pci.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5074/pci.c	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,357 @@
+/*
+ *  arch/mips/ddb5074/pci.c -- NEC DDB Vrc-5074 PCI access routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Albert Dorofeev <albert@sonycom.com>
+ *                     Sony Suprastructure Center Europe (SUPC-E), Brussels
+ *
+ *  $Id: pci.c,v 1.4 2000/02/18 00:02:17 ralf Exp $
+ */
+
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <asm-mips/nile4.h>
+
+
+static u32 nile4_pre_pci_access0(int slot_num)
+{
+    u32 pci_addr = 0;
+    u32 virt_addr = NILE4_PCI_CFG_BASE;
+
+    /* Set window 1 address 8000000 - 64 bit - 2 MB (PCI config space) */
+    nile4_set_pdar(NILE4_PCIW1, PHYSADDR(virt_addr), 0x00200000, 64, 0, 0);
+    if (slot_num > 2)
+	pci_addr = 0x00040000 << slot_num;
+    else
+	virt_addr += 0x00040000 << slot_num;
+    nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, pci_addr);
+    return virt_addr;
+}
+
+static void nile4_post_pci_access0(void)
+{
+    /* Set window 1 back to address 8000000 - 64 bit - 128 MB (PCI IO space) */
+    nile4_set_pdar(NILE4_PCIW1, PHYSADDR(NILE4_PCI_MEM_BASE), 0x08000000, 64,
+    		   1, 1);
+    nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0);
+}
+
+
+static int nile4_pci_read_config_dword( struct pci_dev *dev,
+				int where, u32 *val)
+{
+    int slot_num, func_num;
+    u32 base;
+
+    /*
+     *  For starters let's do configuration cycle 0 only (one bus only)
+     */
+    if (dev->bus->number)
+	return PCIBIOS_FUNC_NOT_SUPPORTED;
+
+    slot_num = PCI_SLOT(dev->devfn);
+    func_num = PCI_FUNC(dev->devfn);
+    if (slot_num == 5) {
+	/*
+	 *  This is Nile 4 and it will crash if we access it like other
+	 *   devices
+	 */
+	*val = nile4_in32(NILE4_PCI_BASE + where);
+	return PCIBIOS_SUCCESSFUL;
+    }
+    base = nile4_pre_pci_access0(slot_num);
+    *val = *((volatile u32 *)(base + (func_num << 8) + (where & 0xfc)));
+    nile4_post_pci_access0();
+    return PCIBIOS_SUCCESSFUL;
+}
+
+static int nile4_pci_write_config_dword(struct pci_dev *dev, int where,
+					u32 val)
+{
+    int slot_num, func_num;
+    u32 base;
+
+    /*
+     *  For starters let's do configuration cycle 0 only (one bus only)
+     */
+    if (dev->bus->number)
+	return PCIBIOS_FUNC_NOT_SUPPORTED;
+
+    slot_num = PCI_SLOT(dev->devfn);
+    func_num = PCI_FUNC(dev->devfn);
+    if (slot_num == 5) {
+	/*
+	 *  This is Nile 4 and it will crash if we access it like other
+	 *   devices
+	 */
+	nile4_out32(NILE4_PCI_BASE + where, val);
+	return PCIBIOS_SUCCESSFUL;
+    }
+    base = nile4_pre_pci_access0(slot_num);
+    *((volatile u32 *)(base + (func_num << 8) + (where & 0xfc))) = val;
+    nile4_post_pci_access0();
+    return PCIBIOS_SUCCESSFUL;
+}
+
+static int nile4_pci_read_config_word(struct pci_dev *dev, int where, u16 *val)
+{
+    int status;
+    u32 result;
+
+    status = nile4_pci_read_config_dword(dev, where, &result);
+    if (status != PCIBIOS_SUCCESSFUL)
+	return status;
+    if (where & 2)
+	result >>= 16;
+    *val = result & 0xffff;
+    return PCIBIOS_SUCCESSFUL;
+}
+
+static int nile4_pci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
+{
+    int status;
+    u32 result;
+
+    status = nile4_pci_read_config_dword(dev, where, &result);
+    if (status != PCIBIOS_SUCCESSFUL)
+	return status;
+    if (where & 1)
+	result >>= 8;
+    if (where & 2)
+	result >>= 16;
+    *val = result & 0xff;
+    return PCIBIOS_SUCCESSFUL;
+}
+
+static int nile4_pci_write_config_word(struct pci_dev *dev, int where, u16 val)
+{
+    int status, shift = 0;
+    u32 result;
+
+    status = nile4_pci_read_config_dword(dev, where, &result);
+    if (status != PCIBIOS_SUCCESSFUL)
+	return status;
+    if (where & 2)
+	shift += 16;
+    result &= ~(0xffff << shift);
+    result |= val << shift;
+    return nile4_pci_write_config_dword(dev, where, result);
+}
+
+static int nile4_pci_write_config_byte( struct pci_dev *dev, int where, u8 val)
+{
+    int status, shift = 0;
+    u32 result;
+
+    status = nile4_pci_read_config_dword(dev, where, &result);
+    if (status != PCIBIOS_SUCCESSFUL)
+	return status;
+    if (where & 2)
+	shift += 16;
+    if (where & 1)
+	shift += 8;
+    result &= ~(0xff << shift);
+    result |= val << shift;
+    return nile4_pci_write_config_dword(dev, where, result);
+}
+
+struct pci_ops nile4_pci_ops = {
+    nile4_pci_read_config_byte,
+    nile4_pci_read_config_word,
+    nile4_pci_read_config_dword,
+    nile4_pci_write_config_byte,
+    nile4_pci_write_config_word,
+    nile4_pci_write_config_dword
+};
+
+
+static void __init pcibios_claim_resources(struct list_head *bus_list)
+{
+    struct list_head *ln, *dn;
+    struct pci_bus *bus;
+    struct pci_dev *dev;
+    int idx;
+
+    for (ln = bus_list->next; ln != bus_list; ln = ln->next) {
+	bus = pci_bus_b(ln);
+	for (dn = bus->devices.next; dn != &bus->devices; dn = dn->next) {
+	    dev = pci_dev_b(dn);
+	    for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
+		struct resource *r = &dev->resource[idx];
+		struct resource *pr;
+		if (!r->start)
+		    continue;
+		pr = pci_find_parent_resource(dev, r);
+		if (!pr || request_resource(pr, r) < 0) {
+		    printk(KERN_ERR "PCI: Address space collision on region %d of device %s\n", idx, dev->name);
+		    /* We probably should disable the region, shouldn't we? */
+		}
+	    }
+	}
+	pcibios_claim_resources(&bus->children);
+    }
+}
+
+
+void pcibios_init(void)
+{
+    printk("PCI: Probing PCI hardware\n");
+    ioport_resource.end = 0x1ffffff;
+    pci_scan_bus(0, &nile4_pci_ops, NULL);
+    pcibios_claim_resources(&pci_root_buses);
+}
+
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+    struct list_head *dn;
+    struct pci_dev *dev;
+    extern struct pci_dev *pci_pmu;	/* for LEDs D2 and D3 */
+    int slot_num, func_num;
+    u8 t8;
+
+    /*
+     *  FIXME: PMON doesn't autoconfigure the PCI devices
+     *         For now we just hardcode them for our configuration
+     */
+    printk("PCI: Configuring PCI devices (hardcoded)\n");
+    for (dn = bus->devices.next; dn != &bus->devices; dn = dn->next) {
+	dev = pci_dev_b(dn);
+
+	slot_num = PCI_SLOT(dev->devfn);
+	func_num = PCI_FUNC(dev->devfn);
+	printk("  Device %2d: ", slot_num);
+	switch (slot_num) {
+	    case 0:
+		printk("[onboard] Acer Labs M1533 Aladdin IV\n");
+		dev->irq = nile4_to_irq(NILE4_INT_INTE);
+		break;
+	    case 1:
+		printk("[onboard] DEC DC21140\n");
+		dev->irq = nile4_to_irq(NILE4_INT_INTA);
+		dev->resource[0].start = 0x100000;
+		dev->resource[0].end = dev->resource[0].start+0x7f;
+		nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
+					     dev->resource[0].start);
+		dev->resource[1].start = 0x1000000;
+		dev->resource[1].end = dev->resource[1].start+0x7f;
+		nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
+					     dev->resource[1].start);
+		break;
+	    case 2:
+		printk("[slot 1]  Realtek 8029\n");
+		dev->irq = nile4_to_irq(NILE4_INT_INTA);
+		dev->resource[0].start = 0x800000;
+		dev->resource[0].end = dev->resource[0].start+0x1f;
+		nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
+					     dev->resource[0].start);
+		break;
+	    case 3:
+		printk("[slot 2]  DEC DC21140 (#2)\n");
+		dev->irq = nile4_to_irq(NILE4_INT_INTB);
+		dev->resource[0].start = 0x1000000;
+		dev->resource[0].end = dev->resource[0].start+0x7f;
+		nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
+					     dev->resource[0].start);
+		dev->resource[1].start = 0x4000000;
+		dev->resource[1].end = dev->resource[1].start+0x7f;
+		nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
+					     dev->resource[1].start);
+		break;
+	    case 4:
+		printk("[slot 3]  Promise Technology IDE UltraDMA/33");
+		printk(" or 3Com 3c905 :-)\n");
+		dev->irq = nile4_to_irq(NILE4_INT_INTC);
+		dev->resource[0].start = 0x1800000;
+		dev->resource[0].end = dev->resource[0].start+0x7fffff;
+		nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
+					     dev->resource[0].start);
+		break;
+	    case 5:
+		printk("[onboard] NEC Vrc-5074 Nile 4 Host Bridge\n");
+		/*
+		 * Fixup so the serial driver can use the UART
+		 */
+		dev->irq = nile4_to_irq(NILE4_INT_UART);
+		dev->resource[0].start = PHYSADDR(NILE4_BASE);
+		dev->resource[0].end = dev->resource[0].start+NILE4_SIZE-1;
+		dev->resource[0].flags = IORESOURCE_MEM |
+					 PCI_BASE_ADDRESS_MEM_TYPE_64;
+		
+		break;
+	    case 10:
+		printk("[onboard] Acer Labs M7101 PMU\n");
+		pci_pmu = dev;
+		/* Program the lines for LEDs D2 and D3 to output */
+		nile4_pci_read_config_byte(dev, 0x7d, &t8);
+		t8 |= 0xc0;
+		nile4_pci_write_config_byte(dev, 0x7d, t8);
+		/* Turn LEDs D2 and D3 off */
+		nile4_pci_read_config_byte(dev, 0x7e, &t8);
+		t8 |= 0xc0;
+		nile4_pci_write_config_byte(dev, 0x7e, t8);
+		break;
+	    case 13:
+		printk("[onboard] Acer Labs M5237 USB\n");
+		dev->irq = nile4_to_irq(NILE4_INT_INTE);
+		dev->resource[0].start = 0x1001000;
+		dev->resource[0].end = dev->resource[0].start+0xfff;
+		nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
+					     dev->resource[0].start);
+		break;
+	    default:
+		printk("\n");
+		break;
+	}
+    }
+}
+
+char *pcibios_setup (char *str)
+{
+    return str;
+}
+
+void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+				    struct resource *res, int resource)
+{
+    unsigned long where, size;
+    u32 reg;
+
+    where = PCI_BASE_ADDRESS_0 + (resource * 4);
+    size = res->end - res->start;
+    pci_read_config_dword(dev, where, &reg);
+    reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
+    pci_write_config_dword(dev, where, reg);
+}
+
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+    pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus,
+				      struct pbus_set_ranges_data *ranges)
+{
+    ranges->io_start -= bus->resource[0]->start;
+    ranges->io_end -= bus->resource[0]->start;
+    ranges->mem_start -= bus->resource[1]->start;
+    ranges->mem_end -= bus->resource[1]->start;
+}
+
+int __init pcibios_enable_device(struct pci_dev *dev)
+{
+    printk("pcibios_enable_device for %04x:%04x\n", dev->vendor, dev->device);
+    panic("pcibios_enable_device: not yet implemented\n");
+}
+
+void __init pcibios_align_resource(void *data, struct resource *res,
+				   unsigned long size)
+{}
+
+struct pci_fixup pcibios_fixups[] = {};
+
diff -u --recursive --new-file v2.3.47/linux/arch/mips/ddb5074/prom.c linux/arch/mips/ddb5074/prom.c
--- v2.3.47/linux/arch/mips/ddb5074/prom.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5074/prom.c	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,62 @@
+/*
+ *  arch/mips/ddb5074/prom.c -- NEC DDB Vrc-5074 PROM routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Suprastructure Center Europe (SUPC-E), Brussels
+ *
+ *  $Id: prom.c,v 1.2 2000/02/14 17:07:36 ralf Exp $
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+
+char arcs_cmdline[CL_SIZE];
+
+extern char _end;
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_ALIGN(x)	(((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+
+void __init prom_init(const char *s)
+{
+    int i = 0;
+    unsigned long mem_size, free_start, free_end, start_pfn, bootmap_size;
+
+//  _serinit();
+
+    if (s != (void *)-1)
+	while (*s && i < sizeof(arcs_cmdline)-1)
+	    arcs_cmdline[i++] = *s++;
+    arcs_cmdline[i] = '\0';
+
+    mips_machgroup = MACH_GROUP_NEC_DDB;
+    mips_machtype = MACH_NEC_DDB5074;
+    /* 64 MB non-upgradable */
+    mem_size = 64 << 20;
+
+    free_start = PHYSADDR(PFN_ALIGN(&_end));
+    free_end = mem_size;
+    start_pfn = PFN_UP((unsigned long)&_end);
+
+    /* Register all the contiguous memory with the bootmem allocator
+       and free it.  Be careful about the bootmem freemap.  */
+    bootmap_size = init_bootmem(start_pfn, mem_size >> PAGE_SHIFT);
+
+    /* Free the entire available memory after the _end symbol.  */
+    free_start += bootmap_size;
+    free_bootmem(free_start, free_end-free_start);
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips/ddb5074/setup.c linux/arch/mips/ddb5074/setup.c
--- v2.3.47/linux/arch/mips/ddb5074/setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5074/setup.c	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,244 @@
+/*
+ *  arch/mips/ddb5074/setup.c -- NEC DDB Vrc-5074 setup routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Suprastructure Center Europe (SUPC-E), Brussels
+ *
+ *  $Id: setup.c,v 1.2 2000/02/14 17:07:36 ralf Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/console.h>
+#include <linux/sched.h>
+#include <linux/mc146818rtc.h>
+#include <linux/pc_keyb.h>
+#include <linux/pci.h>
+
+#include <asm/addrspace.h>
+#include <asm/bcache.h>
+#include <asm/keyboard.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/gdb-stub.h>
+#include <asm/nile4.h>
+#include <asm/ddb5074.h>
+
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void rs_kgdb_hook(int);
+extern void breakpoint(void);
+#endif
+
+#if defined(CONFIG_SERIAL_CONSOLE)
+extern void console_setup(char *);
+#endif
+
+extern struct rtc_ops ddb_rtc_ops;
+
+static void ddb_machine_restart(char *command)
+{
+    u32 t;
+
+    // FIXME: This doesn't seem to work...
+    printk("Restarting DDB Vrc-5074...");
+    /* PCI cold reset */
+    t = nile4_in32(NILE4_PCICTRL+4);
+    t |= 0x40000000;
+    nile4_out32(NILE4_PCICTRL+4, t);
+    /* CPU cold reset */
+    t = nile4_in32(NILE4_CPUSTAT);
+    t |= 1;
+    nile4_out32(NILE4_CPUSTAT, t);
+    printk("Restart failed!\n");
+    do {} while (1);
+}
+
+static void ddb_machine_halt(void)
+{
+    printk("DDB Vrc-5074 halted.\n");
+    do {} while (1);
+}
+
+static void ddb_machine_power_off(void)
+{
+    printk("DDB Vrc-5074 halted. Please turn off the power.\n");
+    do {} while (1);
+}
+
+extern void ddb_irq_setup(void);
+
+void (*board_time_init)(struct irqaction *irq);
+
+
+static void __init ddb_time_init(struct irqaction *irq)
+{
+    /* set the clock to 1 Hz */
+    nile4_out32(NILE4_T2CTRL, 1000000);
+    /* enable the General-Purpose Timer */
+    nile4_out32(NILE4_T2CTRL+4, 0x00000001);
+    /* reset timer */
+    nile4_out32(NILE4_T2CNTR, 0);
+    /* enable interrupt */
+    nile4_enable_irq(NILE4_INT_GPT);
+    i8259_setup_irq(nile4_to_irq(NILE4_INT_GPT), irq);
+    set_cp0_status(ST0_IM, IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
+}
+
+void __init ddb_setup(void)
+{
+    irq_setup = ddb_irq_setup;
+    mips_io_port_base = NILE4_PCI_IO_BASE;
+    isa_slot_offset = NILE4_PCI_MEM_BASE;
+    request_region(0x00, 0x20, "dma1");
+    request_region(0x40, 0x20, "timer");
+    request_region(0x70, 0x10, "rtc");
+    request_region(0x80, 0x10, "dma page reg");
+    request_region(0xc0, 0x20, "dma2");
+    board_time_init = ddb_time_init;
+
+    _machine_restart = ddb_machine_restart;
+    _machine_halt = ddb_machine_halt;
+    _machine_power_off = ddb_machine_power_off;
+
+    rtc_ops = &ddb_rtc_ops;
+}
+
+int __init page_is_ram(unsigned long pagenr)
+{
+    return 1;
+}
+
+
+#define USE_NILE4_SERIAL	0
+
+#if USE_NILE4_SERIAL
+#define ns16550_in(reg)		nile4_in8((reg)*8)
+#define ns16550_out(reg, val)	nile4_out8((reg)*8, (val))
+#else
+#define NS16550_BASE		(NILE4_PCI_IO_BASE+0x03f8)
+static inline u8 ns16550_in(u32 reg)
+{
+    return *(volatile u8 *)(NS16550_BASE+reg);
+}
+
+static inline void ns16550_out(u32 reg, u8 val)
+{
+    *(volatile u8 *)(NS16550_BASE+reg) = val;
+}
+#endif
+
+#define NS16550_RBR		0
+#define NS16550_THR		0
+#define NS16550_DLL		0
+#define NS16550_IER		1
+#define NS16550_DLM		1
+#define NS16550_FCR		2
+#define NS16550_IIR		2
+#define NS16550_LCR		3
+#define NS16550_MCR		4
+#define NS16550_LSR		5
+#define NS16550_MSR		6
+#define NS16550_SCR		7
+
+#define NS16550_LSR_DR		0x01	/* Data ready */
+#define NS16550_LSR_OE		0x02	/* Overrun */
+#define NS16550_LSR_PE		0x04	/* Parity error */
+#define NS16550_LSR_FE		0x08	/* Framing error */
+#define NS16550_LSR_BI		0x10	/* Break */
+#define NS16550_LSR_THRE	0x20	/* Xmit holding register empty */
+#define NS16550_LSR_TEMT	0x40	/* Xmitter empty */
+#define NS16550_LSR_ERR		0x80	/* Error */
+
+
+void _serinit(void)
+{
+#if USE_NILE4_SERIAL
+    ns16550_out(NS16550_LCR, 0x80);
+    ns16550_out(NS16550_DLM, 0x00);
+    ns16550_out(NS16550_DLL, 0x36);	/* 9600 baud */
+    ns16550_out(NS16550_LCR, 0x00);
+    ns16550_out(NS16550_LCR, 0x03);
+    ns16550_out(NS16550_FCR, 0x47);
+#else
+    /* done by PMON */
+#endif
+}
+
+void _putc(char c)
+{
+    while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
+    ns16550_out(NS16550_THR, c);
+    if (c == '\n') {
+	while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
+	ns16550_out(NS16550_THR, '\r');
+    }
+}
+
+void _puts(const char *s)
+{
+    char c;
+    while ((c = *s++))
+	_putc(c);
+}
+
+char _getc(void)
+{
+    while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR));
+    return ns16550_in(NS16550_RBR);
+}
+
+int _testc(void)
+{
+    return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0;
+}
+
+
+    /*
+     *  Hexadecimal 7-segment LED
+     */
+
+void ddb5074_led_hex(int hex)
+{
+    outb(hex, 0x80);
+}
+
+
+    /*
+     *  LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543
+     */
+
+struct pci_dev *pci_pmu = NULL;
+
+void ddb5074_led_d2(int on)
+{
+    u8 t;
+
+    if (pci_pmu) {
+	pci_read_config_byte(pci_pmu, 0x7e, &t);
+	if (on)
+	    t &= 0x7f;
+	else
+	    t |= 0x80;
+	pci_write_config_byte(pci_pmu, 0x7e, t);
+    }
+}
+
+void ddb5074_led_d3(int on)
+{
+    u8 t;
+
+    if (pci_pmu) {
+	pci_read_config_byte(pci_pmu, 0x7e, &t);
+	if (on)
+	    t &= 0xbf;
+	else
+	    t |= 0x40;
+	pci_write_config_byte(pci_pmu, 0x7e, t);
+    }
+}
+
diff -u --recursive --new-file v2.3.47/linux/arch/mips/ddb5074/time.c linux/arch/mips/ddb5074/time.c
--- v2.3.47/linux/arch/mips/ddb5074/time.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5074/time.c	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,35 @@
+/*
+ *  arch.mips/ddb5074/time.c -- Timer routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Suprastructure Center Europe (SUPC-E), Brussels
+ *
+ *  $Id*
+ */
+
+#include <linux/init.h>
+#include <asm/mc146818rtc.h>
+
+static unsigned char ddb_rtc_read_data(unsigned long addr)
+{
+    outb_p(addr, RTC_PORT(0));
+    return inb_p(RTC_PORT(1));
+}
+
+static void ddb_rtc_write_data(unsigned char data, unsigned long addr)
+{
+    outb_p(addr, RTC_PORT(0));
+    outb_p(data, RTC_PORT(1));
+}
+
+static int ddb_rtc_bcd_mode(void)
+{
+    return 1;
+}
+
+struct rtc_ops ddb_rtc_ops = {
+    ddb_rtc_read_data,
+    ddb_rtc_write_data,
+    ddb_rtc_bcd_mode
+};
+
diff -u --recursive --new-file v2.3.47/linux/arch/mips/dec/Makefile linux/arch/mips/dec/Makefile
--- v2.3.47/linux/arch/mips/dec/Makefile	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/dec/Makefile	Thu Feb 24 22:52:30 2000
@@ -13,7 +13,7 @@
 
 all: dec.o
 O_TARGET := dec.o
-O_OBJS	 := int-handler.o setup.o irq.o time.o reset.o rtc-dec.o wbflush.o
+O_OBJS	 := int-handler.o setup.o irq.o time.o reset.o rtc-dec.o
 
 ifdef CONFIG_PROM_CONSOLE
 O_OBJS   += promcon.o
@@ -21,6 +21,12 @@
 
 ifdef CONFIG_SERIAL
 O_OBJS   += serial.o
+endif
+
+ifeq ($(CONFIG_MODULES),y)
+ OX_OBJS  = wbflush.o
+else
+ O_OBJS   += wbflush.o
 endif
 
 int-handler.o:	int-handler.S
diff -u --recursive --new-file v2.3.47/linux/arch/mips/dec/irq.c linux/arch/mips/dec/irq.c
--- v2.3.47/linux/arch/mips/dec/irq.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/dec/irq.c	Thu Feb 24 22:52:30 2000
@@ -4,7 +4,7 @@
  * Copyright (C) 1992 Linus Torvalds
  * Copyright (C) 1994, 1995, 1996, 1997 Ralf Baechle
  *
- * $Id: irq.c,v 1.3 1999/04/11 17:06:16 harald Exp $
+ * $Id: irq.c,v 1.6 2000/02/04 07:40:23 ralf Exp $
  */
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -114,8 +114,6 @@
     return len;
 }
 
-atomic_t __mips_bh_counter;
-
 /*
  * do_IRQ handles IRQ's that have been installed without the
  * SA_INTERRUPT flag: it uses the full signal-handling return
@@ -129,7 +127,7 @@
     int do_random, cpu;
 
     cpu = smp_processor_id();
-    hardirq_enter(cpu);
+    irq_enter(cpu);
     kstat.irqs[cpu][irq]++;
 
     mask_irq(irq);
@@ -149,7 +147,7 @@
 	unmask_irq(irq);
 	__cli();
     }
-    hardirq_exit(cpu);
+    irq_exit(cpu);
 
     /* unmasking and bottom half handling is done magically for us. */
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/dec/prom/Makefile linux/arch/mips/dec/prom/Makefile
--- v2.3.47/linux/arch/mips/dec/prom/Makefile	Mon Dec 20 18:48:21 1999
+++ linux/arch/mips/dec/prom/Makefile	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-# $Id: $
+# $Id: Makefile,v 1.2 2000/02/05 06:47:08 ralf Exp $
 # Makefile for the DECstation prom monitor library routines
 # under Linux.
 #
diff -u --recursive --new-file v2.3.47/linux/arch/mips/dec/prom/cmdline.c linux/arch/mips/dec/prom/cmdline.c
--- v2.3.47/linux/arch/mips/dec/prom/cmdline.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/dec/prom/cmdline.c	Thu Feb 24 22:52:30 2000
@@ -3,10 +3,11 @@
  *
  * Copyright (C) 1998 Harald Koerfgen
  *
- * $Id: $
+ * $Id: cmdline.c,v 1.2 1999/10/09 00:00:57 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/config.h>
 #include <linux/string.h>
 
 #include <asm/bootinfo.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/dec/prom/identify.c linux/arch/mips/dec/prom/identify.c
--- v2.3.47/linux/arch/mips/dec/prom/identify.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/dec/prom/identify.c	Thu Feb 24 22:52:30 2000
@@ -3,9 +3,10 @@
  *
  * Copyright (C) 1998 Harald Koerfgen and Paul M. Antoine
  *
- * $Id: $
+ * $Id: identify.c,v 1.2 1999/10/09 00:00:58 ralf Exp $
  */
 #include <linux/init.h>
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/dec/prom/init.c linux/arch/mips/dec/prom/init.c
--- v2.3.47/linux/arch/mips/dec/prom/init.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/dec/prom/init.c	Thu Feb 24 22:52:30 2000
@@ -3,9 +3,11 @@
  *
  * Copyright (C) 1998 Harald Koerfgen
  *
- * $Id: $
+ * $Id: init.c,v 1.4 1999/10/09 00:00:58 ralf Exp $
  */
 #include <linux/init.h>
+#include <linux/config.h>
+#include <asm/bootinfo.h>
 #include "prom.h"
 
 /*
@@ -81,11 +83,30 @@
 int __init prom_init(int argc, char **argv,
 	       unsigned long magic, int *prom_vec)
 {
+	extern void dec_machine_halt(void);
+
 	/* Determine which PROM's we have (and therefore which machine we're on!) */
 	which_prom(magic, prom_vec);
 
 	if (magic == REX_PROM_MAGIC)
 		rex_clear_cache();
+
+	/* Were we compiled with the right CPU option? */
+#if defined(CONFIG_CPU_R3000)
+	if ((mips_cputype == CPU_R4000SC) || (mips_cputype == CPU_R4400SC)) {
+		prom_printf("Sorry, this kernel is compiled for the wrong CPU type!\n");
+		prom_printf("Please recompile with \"CONFIG_CPU_R4x00 = y\"\n");
+		dec_machine_halt();
+	}
+#endif
+
+#if defined(CONFIG_CPU_R4x00)
+	if ((mips_cputype == CPU_R3000) || (mips_cputype == CPU_R3000A)) {
+		prom_printf("Sorry, this kernel is compiled for the wrong CPU type!\n");
+		prom_printf("Please recompile with \"CONFIG_CPU_R3000 = y\"\n");
+		dec_machine_halt();
+	}
+#endif
 
 	prom_meminit(magic);
 	prom_identify_arch(magic);
diff -u --recursive --new-file v2.3.47/linux/arch/mips/dec/prom/memory.c linux/arch/mips/dec/prom/memory.c
--- v2.3.47/linux/arch/mips/dec/prom/memory.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/dec/prom/memory.c	Thu Feb 24 22:52:30 2000
@@ -3,11 +3,19 @@
  *
  * Copyright (C) 1998 Harald Koerfgen, Frieder Streffer and Paul M. Antoine
  *
- * $Id: $
+ * $Id: memory.c,v 1.4 2000/02/13 20:52:05 harald Exp $
  */
-#include <asm/addrspace.h>
 #include <linux/init.h>
-#include <linux/string.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/page.h>
+
+#include <asm/dec/machtype.h>
+
 #include "prom.h"
 
 typedef struct {
@@ -23,10 +31,13 @@
 extern int (*prom_printf)(char *, ...);
 #endif
 
-extern unsigned long mips_memory_upper;
-
 volatile unsigned long mem_err = 0;	/* So we know an error occured */
 
+extern char _end;
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_ALIGN(x)	(((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
 /*
  * Probe memory in 4MB chunks, waiting for an error to tell us we've fallen
  * off the end of real memory.  Only suitable for the 2100/3100's (PMAX).
@@ -78,26 +89,72 @@
 		if (bm->bitmap[i] == 0xff)
 			mem_size += (8 * bm->pagesize);
 	}
+
 	return (mem_size);
 }
 
 void __init prom_meminit(unsigned int magic)
 {
+	unsigned long free_start, free_end, start_pfn, bootmap_size;
+	unsigned long mem_size = 0;
+
 	if (magic != REX_PROM_MAGIC)
-		mips_memory_upper = KSEG0 + pmax_get_memory_size();
+		mem_size = pmax_get_memory_size();
 	else
-		mips_memory_upper = KSEG0 + rex_get_memory_size();
+		mem_size = rex_get_memory_size();
+
+	free_start = PHYSADDR(PFN_ALIGN(&_end));
+	free_end = mem_size;
+	start_pfn = PFN_UP((unsigned long)&_end);
 
 #ifdef PROM_DEBUG
-	prom_printf("mips_memory_upper: 0x%08x\n", mips_memory_upper);
+	prom_printf("free_start: 0x%08x\n", free_start);
+	prom_printf("free_end: 0x%08x\n", free_end);
+	prom_printf("start_pfn: 0x%08x\n", start_pfn);
 #endif
+
+	/* Register all the contiguous memory with the bootmem allocator
+	   and free it.  Be careful about the bootmem freemap.  */
+	bootmap_size = init_bootmem(start_pfn, mem_size >> PAGE_SHIFT);
+	free_bootmem(free_start + bootmap_size, free_end - free_start - bootmap_size);
 }
 
-/* Called from mem_init() to fixup the mem_map page settings. */
-void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+int __init page_is_ram(unsigned long pagenr)
 {
+        return 1;
 }
 
 void prom_free_prom_memory (void)
 {
+	unsigned long addr, end;
+	extern	char _ftext;
+
+	/*
+	 * Free everything below the kernel itself but leave
+	 * the first page reserved for the exception handlers.
+	 */
+
+#ifdef CONFIG_DECLANCE
+	/*
+	 * Leave 128 KB reserved for Lance memory for
+	 * IOASIC DECstations.
+	 *
+	 * XXX: save this address for use in dec_lance.c?
+	 */
+	if (IOASIC)
+		end = PHYSADDR(&_ftext) - 0x00020000;
+	else
+#endif
+		end = PHYSADDR(&_ftext);
+
+	addr = PAGE_SIZE;
+	while (addr < end) {
+		ClearPageReserved(mem_map + MAP_NR(addr));
+		set_page_count(mem_map + MAP_NR(addr), 1);
+		free_page(addr);
+		addr += PAGE_SIZE;
+	}
+
+	printk("Freeing unused PROM memory: %dk freed\n",
+	       (end - PAGE_SIZE) >> 10);
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/dec/rtc-dec.c linux/arch/mips/dec/rtc-dec.c
--- v2.3.47/linux/arch/mips/dec/rtc-dec.c	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/dec/rtc-dec.c	Thu Feb 24 22:52:30 2000
@@ -1,5 +1,5 @@
 
-/* $Id: rtc-jazz.c,v 1.2 1998/06/25 20:19:14 ralf Exp $
+/* $Id: rtc-dec.c,v 1.1 1999/01/17 03:49:42 ralf Exp $
 
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/arch/mips/dec/wbflush.c linux/arch/mips/dec/wbflush.c
--- v2.3.47/linux/arch/mips/dec/wbflush.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/dec/wbflush.c	Thu Feb 24 22:52:30 2000
@@ -102,3 +102,9 @@
 static void wbflush_kn03(void)
 {
 }
+
+#ifdef EXPORT_SYMTAB
+#include <linux/module.h>
+
+EXPORT_SYMBOL(__wbflush);
+#endif
diff -u --recursive --new-file v2.3.47/linux/arch/mips/defconfig linux/arch/mips/defconfig
--- v2.3.47/linux/arch/mips/defconfig	Wed Dec  8 14:11:25 1999
+++ linux/arch/mips/defconfig	Thu Feb 24 22:52:30 2000
@@ -5,18 +5,20 @@
 #
 # Code maturity level options
 #
-# CONFIG_EXPERIMENTAL is not set
+CONFIG_EXPERIMENTAL=y
 
 #
 # Machine selection
 #
 # CONFIG_ACER_PICA_61 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_DDB5074 is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_OLIVETTI_M700 is not set
-# CONFIG_SGI is not set
-CONFIG_SNI_RM200_PCI=y
-CONFIG_PCI=y
-CONFIG_PCI_NAMES=y
+CONFIG_SGI_IP22=y
+# CONFIG_SNI_RM200_PCI is not set
 
 #
 # CPU selection
@@ -24,77 +26,68 @@
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_R4300 is not set
-CONFIG_CPU_R4X00=y
-# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R4X00 is not set
+CONFIG_CPU_R5000=y
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_WB is not set
 
 #
 # General setup
 #
-CONFIG_PCI_QUIRKS=y
-CONFIG_PCI_OLD_PROC=y
-CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
 CONFIG_ELF_KERNEL=y
+CONFIG_BINFMT_IRIX=y
+CONFIG_FORWARD_KEYBOARD=y
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-# CONFIG_PARPORT is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
+# CONFIG_MODVERSIONS is not set
 CONFIG_KMOD=y
 
 #
-# I2O device support
+# Plug and Play configuration
 #
-# CONFIG_I2O is not set
-# CONFIG_I2O_PCI is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
 
 #
 # Block devices
 #
-CONFIG_BLK_DEV_FD=m
-CONFIG_BLK_DEV_IDE=m
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
 
 #
 # Please see Documentation/ide.txt for help/info on IDE drives
 #
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=m
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_HD_ONLY is not set
 
 #
 # Additional Block Devices
 #
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_MD is not set
-CONFIG_BLK_DEV_RAM=m
+# CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=y
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
 # CONFIG_BLK_DEV_HD is not set
@@ -102,15 +95,18 @@
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
 # CONFIG_NETLINK is not set
-# CONFIG_FIREWALL is not set
+# CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
 # CONFIG_IP_ROUTER is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
@@ -120,14 +116,36 @@
 #
 # (it is safe to leave these untouched)
 #
-# CONFIG_INET_RARP is not set
 # CONFIG_SKB_LARGE is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
 
 #
 #  
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
 
 #
 # SCSI support
@@ -138,14 +156,18 @@
 # SCSI support type (disk, tape, CD-ROM)
 #
 CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_SD_EXTRA_DEVS=40
+CONFIG_CHR_DEV_ST=y
+CONFIG_ST_EXTRA_DEVS=2
+CONFIG_BLK_DEV_SR=y
 # CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_SR_EXTRA_DEVS=2
 # CONFIG_CHR_DEV_SG is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
+# CONFIG_SCSI_DEBUG_QUEUES is not set
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
@@ -153,12 +175,14 @@
 #
 # SCSI low-level drivers
 #
+CONFIG_SCSI_SGIWD93=y
 # CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AHA152X is not set
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
@@ -171,212 +195,162 @@
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-CONFIG_SCSI_NCR53C8XX=y
-# CONFIG_SCSI_SYM53C8XX is not set
-CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
-CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
-CONFIG_SCSI_NCR53C8XX_SYNC=20
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_SIM710 is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
 # CONFIG_SCSI_PCI2220I is not set
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_SEAGATE is not set
-# CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
 
 #
 # Network device support
 #
 CONFIG_NETDEVICES=y
-# CONFIG_ARCNET is not set
 # CONFIG_DUMMY is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_NET_ETHERNET=y
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_EISA=y
-CONFIG_PCNET32=y
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_DE4X5 is not set
-# CONFIG_DEC_ELCP is not set
-# CONFIG_DEC_ELCP is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEXPRESS_PRO100 is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FDDI is not set
-# CONFIG_DLCI is not set
-# CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-# CONFIG_NET_RADIO is not set
-# CONFIG_TR is not set
-# CONFIG_HOSTESS_SV11 is not set
-# CONFIG_COSA is not set
-# CONFIG_RCPCI is not set
-# CONFIG_WAN_DRIVERS is not set
-# CONFIG_LAPBETHER is not set
-# CONFIG_X25_ASY is not set
+# CONFIG_PPP is not set
+CONFIG_SGISEEQ=y
 
 #
-# AX.25 network device drivers
+# Character devices
 #
-# CONFIG_MKISS is not set
-# CONFIG_6PACK is not set
-# CONFIG_BPQETHER is not set
-# CONFIG_DMASCC is not set
-# CONFIG_SCC is not set
-# CONFIG_BAYCOM_SER_FDX is not set
-# CONFIG_BAYCOM_SER_HDX is not set
-# CONFIG_BAYCOM_PAR is not set
-# CONFIG_BAYCOM_EPP is not set
-# CONFIG_SOUNDMODEM is not set
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
 
 #
-# ISDN subsystem
+# I2C support
 #
-# CONFIG_ISDN is not set
+# CONFIG_I2C is not set
 
 #
-# comment
+# Mice
 #
-# CONFIG_CD_NO_IDESCSI is not set
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
 
 #
-# Character devices
+# Joysticks
 #
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
-# CONFIG_MOUSE is not set
+# CONFIG_JOYSTICK is not set
 # CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
 # CONFIG_WATCHDOG is not set
 # CONFIG_NVRAM is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
 
 #
 # Video For Linux
 #
 # CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
 # CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
 
 #
 # Ftape, the floppy tape device driver
 #
 # CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
 
 #
-# USB drivers - not for the faint of heart
+# USB support
 #
 # CONFIG_USB is not set
 
 #
-# Filesystems
+# Misc devices
 #
-CONFIG_QUOTA=y
-CONFIG_AUTOFS_FS=m
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_UMSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_MINIX_FS=m
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
 # CONFIG_NTFS_FS is not set
-CONFIG_HPFS_FS=m
+# CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
-CONFIG_ROMFS_FS=m
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
 # CONFIG_UFS_FS is not set
 
 #
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
-CONFIG_NFS_FS=m
-CONFIG_SUNRPC=m
-CONFIG_LOCKD=m
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
 
 #
 # Partition Types
 #
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MAC_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_SMD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_SGI_DISKLABEL is not set
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_NLS is not set
 
 #
 # Console drivers
 #
-CONFIG_VGA_CONSOLE=y
-# CONFIG_FB is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-# CONFIG_FBCON_FONTS is not set
-CONFIG_FONT_8x8=y
+CONFIG_SGI_NEWPORT_CONSOLE=y
 CONFIG_FONT_8x16=y
 
 #
@@ -385,8 +359,15 @@
 # CONFIG_SOUND is not set
 
 #
+# SGI devices
+#
+CONFIG_SGI_SERIAL=y
+CONFIG_SGI_DS1286=y
+# CONFIG_SGI_NEWPORT_GFX is not set
+
+#
 # Kernel hacking
 #
-# CONFIG_CROSSCOMPILE is not set
+CONFIG_CROSSCOMPILE=y
 # CONFIG_MIPS_FPE_MODULE is not set
 # CONFIG_MAGIC_SYSRQ is not set
diff -u --recursive --new-file v2.3.47/linux/arch/mips/defconfig-decstation linux/arch/mips/defconfig-decstation
--- v2.3.47/linux/arch/mips/defconfig-decstation	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/defconfig-decstation	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,263 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+CONFIG_DECSTATION=y
+# CONFIG_DDB5074 is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SNI_RM200_PCI is not set
+
+#
+# CPU selection
+#
+CONFIG_CPU_R3000=y
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_ADVANCED is not set
+# CONFIG_CPU_HAS_LLSC is not set
+CONFIG_CPU_HAS_WB=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_KCORE_ELF=y
+CONFIG_ELF_KERNEL=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# TURBOchannel support
+#
+CONFIG_TC=y
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
+# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_SKB_LARGE is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_DECNCR=y
+# CONFIG_SCSI_DECSII is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_SLIP is not set
+# CONFIG_PPP is not set
+CONFIG_DECLANCE=y
+
+#
+# DECstation Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+# CONFIG_DZ is not set
+CONFIG_ZS=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_KEYBOARD is not set
+# CONFIG_MOUSE is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Misc devices
+#
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_BFS_FS_WRITE is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+CONFIG_ULTRIX_PARTITION=y
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_MIPS_FPE_MODULE is not set
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
diff -u --recursive --new-file v2.3.47/linux/arch/mips/defconfig-ip22 linux/arch/mips/defconfig-ip22
--- v2.3.47/linux/arch/mips/defconfig-ip22	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/defconfig-ip22	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,373 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_OLIVETTI_M700 is not set
+CONFIG_SGI_IP22=y
+# CONFIG_SNI_RM200_PCI is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_KCORE_ELF=y
+CONFIG_ELF_KERNEL=y
+CONFIG_BINFMT_IRIX=y
+CONFIG_FORWARD_KEYBOARD=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+# (it is safe to leave these untouched)
+#
+# CONFIG_SKB_LARGE is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+CONFIG_CHR_DEV_ST=y
+CONFIG_ST_EXTRA_DEVS=2
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_SR_EXTRA_DEVS=2
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SCSI_SGIWD93=y
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SEAGATE is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_SLIP is not set
+# CONFIG_PPP is not set
+CONFIG_SGISEEQ=y
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Misc devices
+#
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Console drivers
+#
+CONFIG_SGI_NEWPORT_CONSOLE=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# SGI devices
+#
+CONFIG_SGI_SERIAL=y
+CONFIG_SGI_DS1286=y
+# CONFIG_SGI_NEWPORT_GFX is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_MIPS_FPE_MODULE is not set
+# CONFIG_MAGIC_SYSRQ is not set
diff -u --recursive --new-file v2.3.47/linux/arch/mips/jazz/floppy-jazz.c linux/arch/mips/jazz/floppy-jazz.c
--- v2.3.47/linux/arch/mips/jazz/floppy-jazz.c	Wed Feb 16 17:03:51 2000
+++ linux/arch/mips/jazz/floppy-jazz.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: floppy-jazz.c,v 1.1 1998/05/07 18:38:29 ralf Exp $
+/* $Id: floppy-jazz.c,v 1.3 2000/02/24 00:12:40 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/arch/mips/jazz/int-handler.S linux/arch/mips/jazz/int-handler.S
--- v2.3.47/linux/arch/mips/jazz/int-handler.S	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/jazz/int-handler.S	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: int-handler.S,v 1.14 1999/05/01 22:40:34 ralf Exp $
+/* $Id: int-handler.S,v 1.15 1999/08/18 23:37:43 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -14,7 +14,6 @@
  *        cycle is a good cycle.
  */
 #include <asm/asm.h>
-#include <asm/mipsconfig.h>
 #include <asm/mipsregs.h>
 #include <asm/jazz.h>
 #include <asm/regdef.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/jazz/io.c linux/arch/mips/jazz/io.c
--- v2.3.47/linux/arch/mips/jazz/io.c	Fri Sep 10 23:57:27 1999
+++ linux/arch/mips/jazz/io.c	Thu Feb 24 22:52:30 2000
@@ -9,7 +9,6 @@
  */
 #include <linux/string.h>
 #include <linux/spinlock.h>
-#include <asm/mipsconfig.h>
 #include <asm/addrspace.h>
 #include <asm/system.h>
 #include <asm/jazz.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/jazz/jazzdma.c linux/arch/mips/jazz/jazzdma.c
--- v2.3.47/linux/arch/mips/jazz/jazzdma.c	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/jazz/jazzdma.c	Thu Feb 24 22:52:30 2000
@@ -10,10 +10,11 @@
  * and return the more usual NULL pointer as logical address.
  */
 #include <linux/kernel.h>
+#include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
+#include <linux/bootmem.h>
 #include <asm/mipsregs.h>
-#include <asm/mipsconfig.h>
 #include <asm/jazz.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -27,7 +28,6 @@
 #define CONF_DEBUG_VDMA 0
 
 static unsigned long vdma_pagetable_start = 0;
-static unsigned long vdma_pagetable_end = 0;
 
 /*
  * Debug stuff
@@ -59,30 +59,31 @@
 /*
  * Initialize the Jazz R4030 dma controller
  */
-unsigned long vdma_init(unsigned long memory_start, unsigned long memory_end)
+void __init vdma_init(void)
 {
-    /*
-     * Allocate 32k of memory for DMA page tables.
-     * This needs to be page aligned and should be
-     * uncached to avoid cache flushing after every
-     * update.
-     */
-    vdma_pagetable_start = KSEG1ADDR((memory_start + 4095) & ~4095);
-    vdma_pagetable_end = vdma_pagetable_start + VDMA_PGTBL_SIZE;
-    flush_cache_all();
-
-    /*
-     * Clear the R4030 translation table
-     */
-    vdma_pgtbl_init();
-
-    r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE,PHYSADDR(vdma_pagetable_start));
-    r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM,VDMA_PGTBL_SIZE);
-    r4030_write_reg32(JAZZ_R4030_TRSTBL_INV,0);
+	/*
+	 * Allocate 32k of memory for DMA page tables.  This needs to be page
+	 * aligned and should be uncached to avoid cache flushing after every
+	 * update.
+	 */
+	vdma_pagetable_start = alloc_bootmem_low_pages(VDMA_PGTBL_SIZE);
+	if (!vdma_pagetable_start)
+		BUG();
+	dma_cache_wback_inv(vdma_pagetable_start, VDMA_PGTBL_SIZE);
+	vdma_pagetable_start = KSEG1ADDR(vdma_pagetable_start);
+
+	/*
+	 * Clear the R4030 translation table
+	 */
+	vdma_pgtbl_init();
+
+	r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE,PHYSADDR(vdma_pagetable_start));
+	r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM, VDMA_PGTBL_SIZE);
+	r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
 
-    printk("VDMA: R4030 DMA pagetables initialized.\n");
+	printk("VDMA: R4030 DMA pagetables initialized.\n");
 
-    return KSEG0ADDR(vdma_pagetable_end);
+	return KSEG0ADDR(vdma_pagetable_end);
 }
 
 /*
diff -u --recursive --new-file v2.3.47/linux/arch/mips/jazz/kbd-jazz.c linux/arch/mips/jazz/kbd-jazz.c
--- v2.3.47/linux/arch/mips/jazz/kbd-jazz.c	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/jazz/kbd-jazz.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: kbd-jazz.c,v 1.1 1998/10/28 12:38:10 ralf Exp $
+/* $Id: kbd-jazz.c,v 1.1 1999/01/03 17:50:48 ralf Exp $
  *
  * Low-level hardware access stuff for Jazz family machines.
  *
diff -u --recursive --new-file v2.3.47/linux/arch/mips/jazz/rtc-jazz.c linux/arch/mips/jazz/rtc-jazz.c
--- v2.3.47/linux/arch/mips/jazz/rtc-jazz.c	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/jazz/rtc-jazz.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: rtc-jazz.c,v 1.2 1998/06/25 20:19:14 ralf Exp $
+/* $Id: rtc-jazz.c,v 1.2 1998/08/26 21:46:38 tsbogend Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/arch/mips/jazz/setup.c linux/arch/mips/jazz/setup.c
--- v2.3.47/linux/arch/mips/jazz/setup.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/jazz/setup.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.20 1999/02/25 21:57:47 tsbogend Exp $
+/* $Id: setup.c,v 1.25 2000/01/27 01:05:23 ralf Exp $
  *
  * Setup pointers to hardware-dependent routines.
  *
@@ -18,11 +18,12 @@
 #include <linux/console.h>
 #include <linux/fb.h>
 #include <linux/mc146818rtc.h>
+#include <linux/ide.h>
 #include <asm/bootinfo.h>
 #include <asm/keyboard.h>
-#include <asm/ide.h>
 #include <asm/irq.h>
 #include <asm/jazz.h>
+#include <asm/jazzdma.h>
 #include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/io.h>
@@ -79,6 +80,11 @@
 	i8259_setup_irq(2, &irq2);
 }
 
+int __init page_is_ram(unsigned long pagenr)
+{
+	return 1;
+}
+
 void __init jazz_setup(void)
 {
 	add_wired_entry (0x02000017, 0x03c00017, 0xe0000000, PM_64K);
@@ -102,8 +108,29 @@
 #ifdef CONFIG_BLK_DEV_IDE
 	ide_ops = &std_ide_ops;
 #endif
+#ifdef CONFIG_BLK_DEV_FD
+	fd_ops = &jazz_fd_ops;
+#endif
+#ifdef CONFIG_VT
 	conswitchp = &dummy_con;
+#endif
+
+#warning "Somebody should check if screen_info is ok for Jazz."
+
+	screen_info = (struct screen_info) {
+		0, 0,		/* orig-x, orig-y */
+		0,		/* unused */
+		0,		/* orig_video_page */
+		0,		/* orig_video_mode */
+		160,		/* orig_video_cols */
+		0, 0, 0,	/* unused, ega_bx, unused */
+		64,		/* orig_video_lines */
+		0,		/* orig_video_isVGA */
+		16		/* orig_video_points */
+	};
+
 	rtc_ops = &jazz_rtc_ops;
 	kbd_ops = &jazz_kbd_ops;
-	fd_ops = &jazz_fd_ops;
+
+	vdma_init();
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/Makefile linux/arch/mips/kernel/Makefile
--- v2.3.47/linux/arch/mips/kernel/Makefile	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/Makefile	Thu Feb 24 22:52:30 2000
@@ -1,3 +1,4 @@
+# $Id: Makefile,v 1.15 2000/01/26 00:07:44 ralf Exp $
 #
 # Makefile for the Linux/MIPS kernel.
 #
@@ -13,11 +14,21 @@
 EXTRA_ASFLAGS = -mips3 -mcpu=r4000
 O_TARGET := kernel.o
 O_OBJS	:= branch.o process.o signal.o entry.o traps.o ptrace.o vm86.o \
-	   ioport.o pci.o reset.o setup.o syscall.o sysmips.o ipc.o \
-	   r4k_switch.o r4k_misc.o r4k_fpu.o r2300_switch.o r2300_misc.o \
-	   r2300_fpu.o r6000_fpu.o scall_o32.o softfp.o unaligned.o
+	   ioport.o reset.o semaphore.o setup.o syscall.o sysmips.o ipc.o \
+	   scall_o32.o softfp.o unaligned.o
 OX_OBJS := mips_ksyms.o
 
+ifdef CONFIG_CPU_R3000
+O_OBJS	+= r2300_misc.o r2300_fpu.o r2300_switch.o
+else
+O_OBJS	+= r4k_misc.o r4k_switch.o 
+ifdef CONFIG_CPU_R6000
+O_OBJS	+= r6000_fpu.o
+else
+O_OBJS	+= r4k_fpu.o
+endif
+endif
+
 ifdef CONFIG_MIPS_FPE_MODULE
 M_OBJS += fpe.o
 endif
@@ -25,10 +36,11 @@
 #
 # SGIs have very different interrupt/timer hardware.
 #
-ifndef CONFIG_SGI
+ifndef CONFIG_SGI_IP22
   ifndef CONFIG_DECSTATION
     ifndef CONFIG_BAGET_MIPS
-      O_OBJS += irq.o time.o
+      O_OBJS += time.o
+      OX_OBJS += irq.o
     endif
   endif
 endif
@@ -61,8 +73,6 @@
 # compatibility stuff between various boards and boards.
 #
 O_OBJS := $(sort $(O_OBJS))
-
-all: kernel.o head.o
 
 entry.o: entry.S
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/entry.S linux/arch/mips/kernel/entry.S
--- v2.3.47/linux/arch/mips/kernel/entry.S	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/entry.S	Thu Feb 24 22:52:30 2000
@@ -1,20 +1,13 @@
-/*
+/* $Id: entry.S,v 1.20 2000/02/23 00:41:00 ralf Exp $
+ *
  * Low level exception handling
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994, 1995 by Ralf Baechle
- *
- * $Id: entry.S,v 1.14 1999/04/12 19:13:21 harald Exp $
- */
-
-/*
- * entry.S contains the system-call and fault low-level handling routines.
- * This also contains the timer-interrupt handler, as well as all interrupts
- * and faults that can result in a task-switch. The ISA dependent TLB
- * code is in arch/mips/<ISA-level>/<cputype>.S
+ * Copyright (C) 1994 - 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/config.h>
 #include <linux/sys.h>
@@ -23,7 +16,6 @@
 #include <asm/current.h>
 #include <asm/errno.h>
 #include <asm/mipsregs.h>
-#include <asm/mipsconfig.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/stackframe.h>
@@ -31,46 +23,45 @@
 #include <asm/regdef.h>
 #include <asm/fpregdef.h>
 #include <asm/unistd.h>
+#include <asm/isadep.h>
 
-/*
- * Heia ...  The %lo, %hi and %HI stuff is too strong for the ELF assembler
- * and the ABI to cope with ...
- */
 		.text
-		.set	noreorder
-		.set	mips3
 		.align 4
-EXPORT(handle_bottom_half)
-		jal	do_bottom_half
-		 nop
+		.set	push
+		.set	reorder
+EXPORT(ret_from_fork)
+		 move	a0, v0			# prev
+		jal	schedule_tail
+		j	ret_from_sys_call
+
+EXPORT(handle_softirq)
+		jal	do_softirq
 		b	9f
-		 nop
 
 reschedule:	jal	schedule 
-		 nop
 
 EXPORT(ret_from_sys_call)
 EXPORT(ret_from_irq)
-		lw	t0,bh_mask
-		lw	t1,bh_active		# unused delay slot
-		and	t0,t1
-		bnez	t0,handle_bottom_half
-9:		 lw	t0,PT_STATUS(sp)	# returning to kernel mode?
+		.type	ret_from_irq,@function
+		lw	t0, softirq_state
+		lw	t1, softirq_state+4	# unused delay slot
+		and	t0, t1
+		bnez	t0, handle_softirq
+
 
-		andi	t1, t0, 0x10
+9:		lw	t0,PT_STATUS(sp)	# returning to kernel mode?
+		lw	t2, TASK_NEED_RESCHED($28)
+		andi	t1, t0, KU_USER
 		beqz	t1, return		# -> yes
-		 lw	t1, TASK_NEED_RESCHED($28)
-		bnez	t1, reschedule
+		bnez	t2, reschedule
 		lw	v0, TASK_SIGPENDING($28)
 		 move	a0, zero
 		beqz	v0, return
-		 nop
-		jal	do_signal
 		 move	a1, sp
+		jal	do_signal
 
 EXPORT(return)	.set	noat
-		RESTORE_ALL
-		eret
+		RESTORE_ALL_AND_RET
 		.set	at
 
 /*
@@ -84,7 +75,9 @@
 		 * couldn't find a cause for it.
 		 */
 		lui     t1,%hi(spurious_count)
+		.set	reorder
 		lw      t0,%lo(spurious_count)(t1)
+		.set	noreorder
 		addiu   t0,1
 		j	ret_from_irq
 		 sw      t0,%lo(spurious_count)(t1)
@@ -107,7 +100,9 @@
 		ctc1	a2,fcr31;                                       \
 		STI
 #define __BUILD_clear_ade(exception)                                    \
+		.set	reorder;						\
 		MFC0	t0,CP0_BADVADDR;                                \
+		.set	noreorder;					\
 		REG_S	t0,PT_BVADDR(sp);                               \
 		KMODE
 #define __BUILD_silent(exception)
@@ -122,9 +117,9 @@
 #define __BUILD_count(exception)                                        \
 		.set	reorder;                                        \
 		lw	t0,exception_count_##exception;                 \
+		.set	noreorder;                                      \
 		addiu	t0, 1;                                          \
 		sw	t0,exception_count_##exception;                 \
-		.set	noreorder;                                      \
 		.data;                                                  \
 EXPORT(exception_count_##exception);                                    \
 		.word	0;                                              \
@@ -155,6 +150,8 @@
 		BUILD_HANDLER(fpe,fpe,fpe,silent)		/* #15 */
 		BUILD_HANDLER(watch,watch,sti,verbose)		/* #23 */
 		BUILD_HANDLER(reserved,reserved,sti,verbose)	/* others */
+
+		.set	pop
 
 /*
  * Table of syscalls
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/gdb-low.S linux/arch/mips/kernel/gdb-low.S
--- v2.3.47/linux/arch/mips/kernel/gdb-low.S	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/gdb-low.S	Thu Feb 24 22:52:30 2000
@@ -5,14 +5,13 @@
  *
  * Copyright (C) 1995 Andreas Busse
  *
- * $Id: gdb-low.S,v 1.4 1997/12/01 17:57:26 ralf Exp $
+ * $Id: gdb-low.S,v 1.5 1999/08/18 23:37:43 ralf Exp $
  */
 
 #include <linux/sys.h>
 
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
-#include <asm/mipsconfig.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
 #include <asm/gdb-stub.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/head.S linux/arch/mips/kernel/head.S
--- v2.3.47/linux/arch/mips/kernel/head.S	Tue Sep  7 12:14:06 1999
+++ linux/arch/mips/kernel/head.S	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.11 1998/10/18 13:27:12 tsbogend Exp $
+/* $Id: head.S,v 1.17 1999/12/04 03:58:59 ralf Exp $
  *
  * arch/mips/kernel/head.S
  *
@@ -8,10 +8,11 @@
  *
  * Copyright (C) 1994, 1995 Waldorf Electronics
  * Written by Ralf Baechle and Andreas Busse
- * Copyright (C) 1995, 1996, 1997, 1998 Ralf Baechle
+ * Copyright (C) 1995 - 1999 Ralf Baechle
  * Copyright (C) 1996 Paul M. Antoine
  * Modified for DECStation and hence R3000 support by Paul M. Antoine
- * Further modifications by David S. Miller
+ * Further modifications by David S. Miller and Harald Koerfgen
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  *
  * Head.S contains the MIPS exception handler and startup code.
  */
@@ -26,7 +27,6 @@
 #include <asm/regdef.h>
 #include <asm/cachectl.h>
 #include <asm/mipsregs.h>
-#include <asm/mipsconfig.h>
 #include <asm/stackframe.h>
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
@@ -54,9 +54,8 @@
 	LEAF(except_vec0_r4000)
 	.set	mips3
 	mfc0	k0, CP0_BADVADDR		# Get faulting address
-	_GET_CURRENT(k1)			# get current task ptr
 	srl	k0, k0, 22			# get pgd only bits
-	lw	k1, THREAD_PGDIR(k1)		# get task pg_dir
+	lw	k1, current_pgd			# get pgd pointer
 	sll	k0, k0, 2
 	addu	k1, k1, k0			# add in pgd offset
 	mfc0	k0, CP0_CONTEXT			# get context reg
@@ -81,9 +80,8 @@
 	LEAF(except_vec0_r4600)
 	.set	mips3
 	mfc0	k0, CP0_BADVADDR
-	_GET_CURRENT(k1)			# get current task ptr
 	srl	k0, k0, 22
-	lw	k1, THREAD_PGDIR(k1)
+	lw	k1, current_pgd			# get pgd pointer
 	sll	k0, k0, 2
 	addu	k1, k1, k0
 	mfc0	k0, CP0_CONTEXT
@@ -109,9 +107,8 @@
 	LEAF(except_vec0_nevada)
 	.set	mips3
 	mfc0	k0, CP0_BADVADDR		# Get faulting address
-	_GET_CURRENT(k1)			# get current task ptr
 	srl	k0, k0, 22			# get pgd only bits
-	lw	k1, THREAD_PGDIR(k1)		# get task pg_dir
+	lw	k1, current_pgd			# get pgd pointer
 	sll	k0, k0, 2
 	addu	k1, k1, k0			# add in pgd offset
 	lw	k1, (k1)
@@ -135,9 +132,8 @@
 	LEAF(except_vec0_r45k_bvahwbug)
 	.set	mips3
 	mfc0	k0, CP0_BADVADDR
-	_GET_CURRENT(k1)			# get current task ptr
 	srl	k0, k0, 22
-	lw	k1, THREAD_PGDIR(k1)
+	lw	k1, current_pgd			# get pgd pointer
 	sll	k0, k0, 2
 	addu	k1, k1, k0
 	mfc0	k0, CP0_CONTEXT
@@ -166,9 +162,8 @@
 	LEAF(except_vec0_r4k_mphwbug)
 	.set	mips3
 	mfc0	k0, CP0_BADVADDR
-	_GET_CURRENT(k1)			# get current task ptr
 	srl	k0, k0, 22
-	lw	k1, THREAD_PGDIR(k1)
+	lw	k1, current_pgd			# get pgd pointer
 	sll	k0, k0, 2
 	addu	k1, k1, k0
 	mfc0	k0, CP0_CONTEXT
@@ -197,9 +192,8 @@
 	LEAF(except_vec0_r4k_250MHZhwbug)
 	.set	mips3
 	mfc0	k0, CP0_BADVADDR
-	_GET_CURRENT(k1)			# get current task ptr
 	srl	k0, k0, 22
-	lw	k1, THREAD_PGDIR(k1)
+	lw	k1, current_pgd			# get pgd pointer
 	sll	k0, k0, 2
 	addu	k1, k1, k0
 	mfc0	k0, CP0_CONTEXT
@@ -227,9 +221,8 @@
 	LEAF(except_vec0_r4k_MP250MHZhwbug)
 	.set	mips3
 	mfc0	k0, CP0_BADVADDR
-	_GET_CURRENT(k1)			# get current task ptr
 	srl	k0, k0, 22
-	lw	k1, THREAD_PGDIR(k1)
+	lw	k1, current_pgd			# get pgd pointer
 	sll	k0, k0, 2
 	addu	k1, k1, k0
 	mfc0	k0, CP0_CONTEXT
@@ -258,27 +251,22 @@
 
 	/* TLB refill, EXL == 0, R[23]00 version */
 	LEAF(except_vec0_r2300)
+	.set	noat
 	.set	mips1
 	mfc0	k0, CP0_BADVADDR
-	_GET_CURRENT(k1)			# get current task ptr
+	lw	k1, current_pgd			# get pgd pointer
 	srl	k0, k0, 22
-	lw	k1, THREAD_PGDIR(k1)
 	sll	k0, k0, 2
 	addu	k1, k1, k0
 	mfc0	k0, CP0_CONTEXT
 	lw	k1, (k1)
-	srl	k0, k0, 1
 	and	k0, k0, 0xffc
 	addu	k1, k1, k0
 	lw	k0, (k1)
-	srl	k0, k0, 12
+	nop
 	mtc0	k0, CP0_ENTRYLO0
 	mfc0	k1, CP0_EPC
 	tlbwr
-	nop
-	nop
-	nop
-	nop
 	jr	k1
 	rfe
 	END(except_vec0_r2300)
@@ -346,23 +334,25 @@
  li k1, -4
  and k0, k1
 	mtc0	zero, CP0_TAGLO
- //	nop;nop
 	cache	Index_Store_Tag_D,(k0)
- //	nop;nop
 	cache	Hit_Writeback_Inv_SD,(k0)
+#ifdef CONFIG_PROC_FS
 	lui	k0, %hi(vced_count)
 	lw	k1, %lo(vced_count)(k0)
 	addiu	k1, 1
 	sw	k1, %lo(vced_count)(k0)
+#endif
 	eret
 
 handle_vcei:
 	mfc0	k0, CP0_BADVADDR
 	cache	Hit_Writeback_Inv_SD,(k0)		# also cleans pi
+#ifdef CONFIG_PROC_FS
 	lui	k0, %hi(vcei_count)
 	lw	k1, %lo(vcei_count)(k0)
 	addiu	k1, 1
 	sw	k1, %lo(vcei_count)(k0)
+#endif
 	eret
 
 	END(except_vec3_r4000)
@@ -371,6 +361,7 @@
 	/* General exception vector. */
 	NESTED(except_vec3_generic, 0, sp)
 	.set	noat
+	.set	mips0
 	mfc0	k1, CP0_CAUSE
 	la	k0, exception_handlers
 	andi	k1, k1, 0x7c
@@ -408,6 +399,14 @@
 
 probe_done:
 
+	/*
+	 * Stack for kernel and init, current variable
+	 */
+	la	$28, init_task_union
+	addiu	t0, $28, KERNEL_STACK_SIZE-32
+	sw	t0, kernelsp
+	subu	sp, t0, 4*SZREG
+
 	/* The firmware/bootloader passes argc/argp/envp
 	 * to us as arguments.  But clear bss first because
 	 * the romvec and other important info is stored there
@@ -423,7 +422,7 @@
 
 	jal	prom_init /* prom_init(argc, argv, envp); */
 	 nop
-#ifdef CONFIG_SGI
+#ifdef CONFIG_SGI_IP22
 	jal	sgi_sysinit
 	 nop
 #endif
@@ -441,14 +440,6 @@
 	jal	loadmmu
 	 nop
 
-	/*
-	 * Stack for kernel and init, current variable
-	 */
-	la	$28, init_task_union
-	addiu	t0, $28, KERNEL_STACK_SIZE-32
-	sw	t0, kernelsp
-	subu	sp, t0, 4*SZREG
-
 	/* Disable coprocessors */
 	mfc0	t0, CP0_STATUS
 	li	t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX)
@@ -598,6 +589,8 @@
 		.fill	32*4,1,0
 
 EXPORT(kernelsp)
+		PTR	0
+EXPORT(current_pgd)
 		PTR	0
 		.text
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/ipc.c linux/arch/mips/kernel/ipc.c
--- v2.3.47/linux/arch/mips/kernel/ipc.c	Fri May  8 00:13:23 1998
+++ linux/arch/mips/kernel/ipc.c	Thu Feb 24 22:52:30 2000
@@ -20,108 +20,79 @@
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  *
- * This is really horribly ugly.  FIXME: Get rid of this wrapper.
+ * This is really horribly ugly.
  */
-asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
+asmlinkage int sys_ipc (uint call, int first, int second,
+			int third, void *ptr, long fifth)
 {
 	int version, ret;
 
-	lock_kernel();
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
-	if (call <= SEMCTL)
-		switch (call) {
-		case SEMOP:
-			ret = sys_semop (first, (struct sembuf *)ptr, second);
-			goto out;
-		case SEMGET:
-			ret = sys_semget (first, second, third);
-			goto out;
-		case SEMCTL: {
-			union semun fourth;
-			ret = -EINVAL;
+	switch (call) {
+	case SEMOP:
+		return sys_semop (first, (struct sembuf *)ptr, second);
+	case SEMGET:
+		return sys_semget (first, second, third);
+	case SEMCTL: {
+		union semun fourth;
+		if (!ptr)
+			return -EINVAL;
+		if (get_user(fourth.__pad, (void **) ptr))
+			return -EFAULT;
+		return sys_semctl (first, second, third, fourth);
+	}
+
+	case MSGSND:
+		return sys_msgsnd (first, (struct msgbuf *) ptr, 
+				   second, third);
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
 			if (!ptr)
-				goto out;
-			ret = -EFAULT;
-			if (get_user(fourth.__pad, (void **) ptr))
-				goto out;	
-			ret = sys_semctl (first, second, third, fourth);
-			goto out;
-			}
-		default:
-			ret = -EINVAL;
-			goto out;
+				return -EINVAL;
+			
+			if (copy_from_user(&tmp,
+					   (struct ipc_kludge *) ptr, 
+					   sizeof (tmp)))
+				return -EFAULT;
+			return sys_msgrcv (first, tmp.msgp, second,
+					   tmp.msgtyp, third);
 		}
-	if (call <= MSGCTL) 
-		switch (call) {
-		case MSGSND:
-			ret = sys_msgsnd (first, (struct msgbuf *) ptr, 
-					  second, third);
-			goto out;
-		case MSGRCV:
-			switch (version) {
-			case 0: {
-				struct ipc_kludge tmp;
-				ret = -EINVAL;
-				if (!ptr)
-					goto out;
-				ret = -EFAULT;
-				if (copy_from_user(&tmp,(struct ipc_kludge *) ptr, 
-								   sizeof (tmp)))
-					goto out; 	
-				ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
-				goto out;
-				}
-			case 1: default:
-				ret = sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
-				goto out;
-			}
-		case MSGGET:
-			ret = sys_msgget ((key_t) first, second);
-			goto out;
-		case MSGCTL:
-			ret = sys_msgctl (first, second, (struct msqid_ds *) ptr);
-			goto out;
 		default:
-			ret = -EINVAL;
-			goto out;
+			return sys_msgrcv (first,
+					   (struct msgbuf *) ptr,
+					   second, fifth, third);
 		}
-	if (call <= SHMCTL) 
-		switch (call) {
-		case SHMAT:
-			switch (version) {
-			case 0: default: {
-				ulong raddr;
-				ret = sys_shmat (first, (char *) ptr, second, &raddr);
-				if (ret)
-					goto out;
-				ret = put_user (raddr, (ulong *) third);
-				goto out;
-			}
-			case 1:	/* iBCS2 emulator entry point */
-				ret = -EINVAL;
-				if (!segment_eq(get_fs(), get_ds()))
-					goto out;
-				ret = sys_shmat (first, (char *) ptr, second, (ulong *) third);
-				goto out;
-			}
-		case SHMDT: 
-			ret = sys_shmdt ((char *)ptr);
-			goto out;
-		case SHMGET:
-			ret = sys_shmget (first, second, third);
-			goto out;
-		case SHMCTL:
-			ret = sys_shmctl (first, second, (struct shmid_ds *) ptr);
-			goto out;
-		default:
-			ret = -EINVAL;
-			goto out;
+	case MSGGET:
+		return sys_msgget ((key_t) first, second);
+	case MSGCTL:
+		return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+			ret = sys_shmat (first, (char *) ptr, second, &raddr);
+			if (ret)
+				return ret;
+			return put_user (raddr, (ulong *) third);
+		}
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				return -EINVAL;
+			return sys_shmat (first, (char *) ptr, second, (ulong *) third);
 		}
-	else
-		ret = -EINVAL;
-out:
-	unlock_kernel();
-	return ret;
+	case SHMDT: 
+		return sys_shmdt ((char *)ptr);
+	case SHMGET:
+		return sys_shmget (first, second, third);
+	case SHMCTL:
+		return sys_shmctl (first, second,
+				   (struct shmid_ds *) ptr);
+	default:
+		return -EINVAL;
+	}
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/irixelf.c linux/arch/mips/kernel/irixelf.c
--- v2.3.47/linux/arch/mips/kernel/irixelf.c	Sun Jul 25 13:45:25 1999
+++ linux/arch/mips/kernel/irixelf.c	Sat Feb 26 20:33:02 2000
@@ -1,4 +1,4 @@
-/* $Id: irixelf.c,v 1.17 1999/06/17 13:25:45 ralf Exp $
+/* $Id: irixelf.c,v 1.24 2000/02/04 07:40:23 ralf Exp $
  *
  * irixelf.c: Code to load IRIX ELF executables which conform to
  *            the MIPS ABI.
@@ -22,6 +22,7 @@
 #include <linux/signal.h>
 #include <linux/binfmts.h>
 #include <linux/string.h>
+#include <linux/file.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
 #include <linux/malloc.h>
@@ -30,7 +31,7 @@
 #include <linux/elfcore.h>
 
 #include <asm/uaccess.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/mipsregs.h>
 #include <asm/prctl.h>
 
@@ -44,17 +45,13 @@
 
 static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs);
 static int load_irix_library(int fd);
-static int irix_core_dump(long signr, struct pt_regs * regs);
+static int irix_core_dump(long signr, struct pt_regs * regs,
+                          struct file *file);
 extern int dump_fpu (elf_fpregset_t *);
 
 static struct linux_binfmt irix_format = {
-	NULL,
-#ifndef MODULE
-	NULL,
-#else
-	&__this_module.usecount,
-#endif
-	load_irix_binary, load_irix_library, irix_core_dump, PAGE_SIZE
+	NULL, THIS_MODULE, load_irix_binary, load_irix_library,
+	irix_core_dump, PAGE_SIZE
 };
 
 #ifndef elf_addr_t
@@ -263,8 +260,8 @@
 	if((interp_elf_ex->e_type != ET_EXEC &&
 	    interp_elf_ex->e_type != ET_DYN) ||
 	    !elf_check_arch(interp_elf_ex->e_machine) ||
-	   (!interpreter_dentry->d_inode->i_op ||
-	    !interpreter_dentry->d_inode->i_op->default_file_ops->mmap)) {
+	   (!interpreter_dentry->d_inode->i_fop ||
+	    !interpreter_dentry->d_inode->i_fop->mmap)) {
 		printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type);
 		return 0xffffffff;
 	}
@@ -407,16 +404,14 @@
 /* Check sanity of IRIX elf executable header. */
 static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)
 {
-	if (ehp->e_ident[0] != 0x7f || strncmp(&ehp->e_ident[1], "ELF", 3)) {
-		return  -ENOEXEC;
-	}
+	if (memcmp(ehp->e_ident, ELFMAG, SELFMAG) != 0)
+		return -ENOEXEC;
 
 	/* First of all, some simple consistency checks */
 	if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) || 
 	    !elf_check_arch(ehp->e_machine) ||
-	   (!bprm->dentry->d_inode->i_op ||
-	    !bprm->dentry->d_inode->i_op->default_file_ops ||
-	    !bprm->dentry->d_inode->i_op->default_file_ops->mmap)) {
+	   (!bprm->dentry->d_inode->i_fop ||
+	    !bprm->dentry->d_inode->i_fop->mmap)) {
 		return -ENOEXEC;
 	}
 
@@ -498,7 +493,7 @@
 
 static inline int verify_irix_interpreter(struct elfhdr *ihp)
 {
-	if(ihp->e_ident[0] != 0x7f || strncmp(&ihp->e_ident[1], "ELF", 3))
+	if (memcmp(ihp->e_ident, ELFMAG, SELFMAG) != 0)
 		return -ELIBBAD;
 	return 0;
 }
@@ -625,9 +620,10 @@
 	has_interp = has_ephdr = 0;
 	elf_ihdr = elf_ephdr = 0;
 	elf_ex = *((struct elfhdr *) bprm->buf);
-	
-	if(verify_binary(&elf_ex, bprm))
-		return -ENOEXEC;
+	retval = -ENOEXEC;
+
+	if (verify_binary(&elf_ex, bprm))
+		goto out;
 
 #ifdef DEBUG_ELF
 	print_elfhdr(&elf_ex);
@@ -635,15 +631,19 @@
 
 	/* Now read in all of the header information */
 	size = elf_ex.e_phentsize * elf_ex.e_phnum;
+	if (size > 65536)
+		goto out;
 	elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
-	if (elf_phdata == NULL)
-		return -ENOMEM;
-	
+	if (elf_phdata == NULL) {
+		retval = -ENOMEM;
+		goto out;
+	}
+
 	retval = read_exec(bprm->dentry, elf_ex.e_phoff,
 	                   (char *) elf_phdata, size, 1);
 	if (retval < 0)
-		goto out_phdata;
-	
+		goto out_free_ph;
+
 #ifdef DEBUG_ELF
 	dump_phdrs(elf_phdata, elf_ex.e_phnum);
 #endif
@@ -669,39 +669,39 @@
 	elf_brk = 0;
 	retval = open_dentry(bprm->dentry, O_RDONLY);
 	if (retval < 0)
-		goto out_phdata;
+		goto out_free_ph;
 	file = fget(elf_exec_fileno = retval);
-	
+
 	elf_stack = 0xffffffff;
 	elf_interpreter = NULL;
 	start_code = 0xffffffff;
 	end_code = 0;
 	end_data = 0;
-	
+
 	retval = look_for_irix_interpreter(&elf_interpreter,
 	                                   &interpreter_dentry,
 					   &interp_elf_ex, elf_phdata, bprm,
 					   elf_ex.e_phnum);
 	if(retval)
-		goto out_file;
-	
+		goto out_free_file;
+
 	if(elf_interpreter) {
 		retval = verify_irix_interpreter(&interp_elf_ex);
 		if(retval)
-			goto out_interp;
+			goto out_free_interp;
 	}
-	
+
 	/* OK, we are done with that, now set up the arg stuff,
 	 * and then start this sucker up.
 	 */
 	retval = -E2BIG;
 	if (!bprm->sh_bang && !bprm->p)
-		goto out_interp;
-	
+		goto out_free_interp;
+
 	/* Flush all traces of the currently running executable */
 	retval = flush_old_exec(bprm);
 	if (retval)
-		goto out_interp;
+		goto out_free_dentry;
 
 	/* OK, This is the point of no return */
 	current->mm->end_data = 0;
@@ -716,15 +716,16 @@
 	current->mm->rss = 0;
 	setup_arg_pages(bprm);
 	current->mm->start_stack = bprm->p;
-	
+
 	/* At this point, we assume that the image should be loaded at
 	 * fixed address, not at a variable address.
 	 */
 	old_fs = get_fs();
 	set_fs(get_ds());
-	
-	map_executable(file, elf_phdata, elf_ex.e_phnum, &elf_stack, &load_addr,
-		       &start_code, &elf_bss, &end_code, &end_data, &elf_brk);
+
+	map_executable(file, elf_phdata, elf_ex.e_phnum, &elf_stack,
+	               &load_addr, &start_code, &elf_bss, &end_code,
+	               &end_data, &elf_brk);
 
 	if(elf_interpreter) {
 		retval = map_interpreter(elf_phdata, &interp_elf_ex,
@@ -736,12 +737,12 @@
 			printk("Unable to load IRIX ELF interpreter\n");
 			send_sig(SIGSEGV, current, 0);
 			retval = 0;
-			goto out_file;
+			goto out_free_file;
 		}
 	}
 
 	set_fs(old_fs);
-	
+
 	kfree(elf_phdata);
 	fput(file);
 	sys_close(elf_exec_fileno);
@@ -806,17 +807,20 @@
 	if (current->flags & PF_PTRACED)
 		send_sig(SIGTRAP, current, 0);
 	return 0;
+out:
+	return retval;
 
-out_interp:
-	if(elf_interpreter) {
-	      kfree(elf_interpreter);
-	}
-out_file:
+out_free_dentry:
+	dput(interpreter_dentry);
+out_free_interp:
+	if (elf_interpreter)
+		kfree(elf_interpreter);
+out_free_file:
 	fput(file);
 	sys_close(elf_exec_fileno);
-out_phdata:
+out_free_ph:
 	kfree (elf_phdata);
-	return retval;
+	goto out;
 }
 
 static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
@@ -866,15 +870,14 @@
 	if (error != sizeof(elf_ex))
 		return -ENOEXEC;
 
-	if (elf_ex.e_ident[0] != 0x7f ||
-	    strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
+	if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
 		return -ENOEXEC;
 
 	/* First of all, some simple consistency checks. */
 	if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
 	   !elf_check_arch(elf_ex.e_machine) ||
-	   (!dentry->d_inode->i_op ||
-	    !dentry->d_inode->i_op->default_file_ops->mmap))
+	   (!dentry->d_inode->i_fop ||
+	    !dentry->d_inode->i_fop->mmap))
 		return -ENOEXEC;
 	
 	/* Now read in all of the header information. */
@@ -982,7 +985,7 @@
 		return -EACCES;
 	if(!filp->f_op) {
 		printk("irix_mapelf: Bogon filp!\n");
-		fput(file);
+		fput(filp);
 		return -EACCES;
 	}
 
@@ -1000,7 +1003,7 @@
 
 		if(retval != (hp->p_vaddr & 0xfffff000)) {
 			printk("irix_mapelf: do_mmap fails with %d!\n", retval);
-			fput(file);
+			fput(filp);
 			return retval;
 		}
 	}
@@ -1008,7 +1011,7 @@
 #ifdef DEBUG_ELF
 	printk("irix_mapelf: Success, returning %08lx\n", user_phdrp->p_vaddr);
 #endif
-	fput(file);
+	fput(filp);
 	return user_phdrp->p_vaddr;
 }
 
@@ -1070,20 +1073,22 @@
 static int notesize(struct memelfnote *en)
 {
 	int sz;
-	
+
 	sz = sizeof(struct elf_note);
 	sz += roundup(strlen(en->name), 4);
 	sz += roundup(en->datasz, 4);
-	
+
 	return sz;
 }
 
 /* #define DEBUG */
 
 #define DUMP_WRITE(addr, nr)	\
-	do { if (!dump_write(file, (addr), (nr))) return 0; } while(0)
+	if (!dump_write(file, (addr), (nr))) \
+		goto end_coredump;
 #define DUMP_SEEK(off)	\
-	do { if (!dump_seek(file, (off))) return 0; } while(0)
+	if (!dump_seek(file, (off))) \
+		goto end_coredump;
 
 static int writenote(struct memelfnote *men, struct file *file)
 {
@@ -1101,6 +1106,9 @@
 	DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));	/* XXX */
 	
 	return 1;
+
+end_coredump:
+	return 0;
 }
 #undef DUMP_WRITE
 #undef DUMP_SEEK
@@ -1111,6 +1119,7 @@
 #define DUMP_SEEK(off)	\
 	if (!dump_seek(file, (off))) \
 		goto end_coredump;
+
 /* Actual dumper.
  *
  * This is a two-pass process; first we find the offsets of the bits,
@@ -1164,7 +1173,7 @@
 	elf.e_ident[EI_DATA] = ELFDATA2LSB;
 	elf.e_ident[EI_VERSION] = EV_CURRENT;
 	memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
-	
+
 	elf.e_type = ET_CORE;
 	elf.e_machine = ELF_ARCH;
 	elf.e_version = EV_CURRENT;
@@ -1255,7 +1264,7 @@
 	notes[2].type = NT_TASKSTRUCT;
 	notes[2].datasz = sizeof(*current);
 	notes[2].data = current;
-	
+
 	/* Try to dump the FPU. */
 	prstatus.pr_fpvalid = dump_fpu (&fpu);
 	if (!prstatus.pr_fpvalid) {
@@ -1266,7 +1275,7 @@
 		notes[3].datasz = sizeof(fpu);
 		notes[3].data = &fpu;
 	}
-	
+
 	/* Write notes phdr entry. */
 	{
 		struct elf_phdr phdr;
@@ -1345,34 +1354,24 @@
 		       (off_t) file->f_pos, offset);
 	}
 
- end_coredump:
+end_coredump:
 	set_fs(fs);
-#ifndef CONFIG_BINFMT_ELF
+#ifndef CONFIG_BINFMT_IRIX
 	MOD_DEC_USE_COUNT;
 #endif
 	return has_dumped;
 }
 
-int __init init_irix_binfmt(void)
+static int __init init_irix_binfmt(void)
 {
 	return register_binfmt(&irix_format);
 }
 
-#ifdef MODULE
-
-int init_module(void)
-{
-	/* Install the COFF, ELF and XOUT loaders.
-	 * N.B. We *rely* on the table being the right size with the
-	 * right number of free slots...
-	 */
-	return init_irix_binfmt();
-}
-
-
-void cleanup_module( void)
+static void __exit cleanup_module(void)
 {
 	/* Remove the IRIX ELF loaders. */
 	unregister_binfmt(&irix_format);
 }
-#endif
+
+module_init(init_irix_binfmt)
+module_exit(exit_irix_binfmt)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/irixinv.c linux/arch/mips/kernel/irixinv.c
--- v2.3.47/linux/arch/mips/kernel/irixinv.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/kernel/irixinv.c	Thu Feb 24 22:52:30 2000
@@ -5,7 +5,7 @@
  *
  * Miguel de Icaza, 1997.
  *
- * $Id: irixinv.c,v 1.3 1998/04/05 11:23:51 ralf Exp $
+ * $Id: irixinv.c,v 1.4 1999/10/09 00:00:58 ralf Exp $
  */
 #include <linux/mm.h>
 #include <linux/init.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/irixioctl.c linux/arch/mips/kernel/irixioctl.c
--- v2.3.47/linux/arch/mips/kernel/irixioctl.c	Tue Jul  6 10:11:40 1999
+++ linux/arch/mips/kernel/irixioctl.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: irixioctl.c,v 1.6 1999/02/06 05:12:56 adevries Exp $
+/* $Id: irixioctl.c,v 1.7 1999/09/28 22:25:46 ralf Exp $
  * irixioctl.c: A fucking mess...
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/irixsig.c linux/arch/mips/kernel/irixsig.c
--- v2.3.47/linux/arch/mips/kernel/irixsig.c	Thu Jul 22 09:47:55 1999
+++ linux/arch/mips/kernel/irixsig.c	Thu Feb 24 22:52:30 2000
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: irixsig.c,v 1.11 1999/06/17 13:25:46 ralf Exp $
+ * $Id: irixsig.c,v 1.14 2000/01/17 03:58:59 ralf Exp $
  */
 
 #include <linux/kernel.h>
@@ -114,17 +114,17 @@
 	dump_irix5_sigctx(ctx);
 #endif
 
-	regs->regs[5] = 0; /* XXX sigcode XXX */
 	regs->regs[4] = (unsigned long) signr;
+	regs->regs[5] = 0; /* XXX sigcode XXX */
 	regs->regs[6] = regs->regs[29] = sp;
 	regs->regs[7] = (unsigned long) ka->sa.sa_handler;
-	regs->regs[25] = regs->cp0_epc = current->tss.irix_trampoline;
+	regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa.sa_restorer;
 	return;
 
 segv_and_exit:
-	lock_kernel();
-	do_exit(SIGSEGV);
-	unlock_kernel();
+	if (signr == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
 }
 
 static void inline
@@ -296,11 +296,12 @@
 	return 0;
 }
 
-asmlinkage unsigned long irix_sigreturn(struct pt_regs *regs)
+asmlinkage void
+irix_sigreturn(struct pt_regs *regs)
 {
 	struct sigctx_irix5 *context, *magic;
 	unsigned long umask, mask;
-	u64 *fregs, res;
+	u64 *fregs;
 	int sig, i, base = 0;
 	sigset_t blocked;
 
@@ -333,10 +334,10 @@
 	__get_user(regs->lo, &context->lo);
 
 	if ((umask & 1) && context->usedfp) {
-		fregs = (u64 *) &current->tss.fpu;
+		fregs = (u64 *) &current->thread.fpu;
 		for(i = 0; i < 32; i++)
 			fregs[i] = (u64) context->fpregs[i];
-		__get_user(current->tss.fpu.hard.control, &context->fpcsr);
+		__get_user(current->thread.fpu.hard.control, &context->fpcsr);
 	}
 
 	/* XXX do sigstack crapola here... XXX */
@@ -361,11 +362,7 @@
 		/* Unreached */
 
 badframe:
-	lock_kernel();
-	do_exit(SIGSEGV);
-	unlock_kernel();
-
-	return res;
+	force_sig(SIGSEGV, current);
 }
 
 struct sigact_irix5 {
@@ -386,7 +383,7 @@
 
 asmlinkage int 
 irix_sigaction(int sig, const struct sigaction *act,
-	      struct sigaction *oact, unsigned long trampoline)
+	      struct sigaction *oact, void *trampoline)
 {
 	struct k_sigaction new_ka, old_ka;
 	int ret;
@@ -406,15 +403,14 @@
 			return -EFAULT;
 
 		__copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t));
-		new_ka.ka_restorer = NULL;
-	}
 
-	/*
-	 * Hmmm... methinks IRIX libc always passes a valid trampoline
-	 * value for all invocations of sigaction.  Will have to
-	 * investigate.  POSIX POSIX, die die die...
-	 */
-	current->tss.irix_trampoline = trampoline;
+		/*
+		 * Hmmm... methinks IRIX libc always passes a valid trampoline
+		 * value for all invocations of sigaction.  Will have to
+		 * investigate.  POSIX POSIX, die die die...
+		 */
+		new_ka.sa.sa_restorer = trampoline;
+	}
 
 /* XXX Implement SIG_SETMASK32 for IRIX compatibility */
 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
@@ -512,6 +508,7 @@
 	spin_lock_irq(&current->sigmask_lock);
 	saveset = current->blocked;
 	current->blocked = newset;
+	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
 
 	regs->regs[2] = -EINTR;
@@ -795,7 +792,7 @@
 	error = verify_area(VERIFY_WRITE, ctx, sizeof(*ctx));
 	if(error)
 		goto out;
-	__put_user(current->tss.irix_oldctx, &ctx->link);
+	__put_user(current->thread.irix_oldctx, &ctx->link);
 
 	__copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t));
 
@@ -867,7 +864,7 @@
 		/* XXX fpu context, blah... */
 		printk("Wheee, cannot restore FPU context yet...\n");
 	}
-	current->tss.irix_oldctx = ctx->link;
+	current->thread.irix_oldctx = ctx->link;
 	error = regs->regs[2];
 
 out:
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/irq.c linux/arch/mips/kernel/irq.c
--- v2.3.47/linux/arch/mips/kernel/irq.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/kernel/irq.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.15 1999/02/25 21:50:49 tsbogend Exp $
+/* $Id: irq.c,v 1.20 2000/02/23 00:41:00 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -29,6 +29,7 @@
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 #include <asm/sni.h>
+#include <asm/nile4.h>
 
 /*
  * This contains the irq mask for both 8259A irq controllers, it's an
@@ -72,7 +73,7 @@
 	}
 }
 
-void disable_irq(unsigned int irq_nr)
+void i8259_disable_irq(unsigned int irq_nr)
 {
 	unsigned long flags;
 
@@ -81,7 +82,7 @@
 	restore_flags(flags);
 }
 
-void enable_irq(unsigned int irq_nr)
+void i8259_enable_irq(unsigned int irq_nr)
 {
 	unsigned long flags;
 	save_and_cli(flags);
@@ -123,8 +124,6 @@
 	return len;
 }
 
-atomic_t __mips_bh_counter;
-
 static inline void i8259_mask_and_ack_irq(int irq)
 {
 	cached_irq_mask |= 1 << irq;
@@ -147,7 +146,7 @@
 	int do_random, cpu;
 
 	cpu = smp_processor_id();
-	hardirq_enter(cpu);
+	irq_enter(cpu);
 
 	if (irq >= 16)
 		goto out;
@@ -175,7 +174,7 @@
 	unmask_irq (irq);
 
 out:
-	hardirq_exit(cpu);
+	irq_exit(cpu);
 }
 
 /*
@@ -191,7 +190,7 @@
 	int do_random, cpu;
 
 	cpu = smp_processor_id();
-	hardirq_enter(cpu);
+	irq_enter(cpu);
 	kstat.irqs[cpu][irq]++;
 
 	action = *(irq + irq_action);
@@ -209,7 +208,10 @@
 			add_interrupt_randomness(irq);
 		__cli();
 	}
-	hardirq_exit(cpu);
+	irq_exit(cpu);
+
+	if (softirq_state[cpu].active&softirq_state[cpu].mask)
+		do_softirq();
 
 	/* unmasking and bottom half handling is done magically for us. */
 }
@@ -245,7 +247,10 @@
 	*p = new;
 
 	if (!shared) {
-		unmask_irq(irq);
+		if (is_i8259_irq(irq))
+		    unmask_irq(irq);
+		else
+		    nile4_enable_irq(irq_to_nile4(irq));
 	}
 	restore_flags(flags);
 	return 0;
@@ -356,7 +361,7 @@
 	return ((irq == 2) ? 9 : irq);
 }
 
-static void __init i8259_init(void)
+void __init i8259_init(void)
 {
 	/* Init master interrupt controller */
 	outb(0x11, 0x20); /* Start init sequence */
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/mips_ksyms.c linux/arch/mips/kernel/mips_ksyms.c
--- v2.3.47/linux/arch/mips/kernel/mips_ksyms.c	Thu Nov 11 20:11:32 1999
+++ linux/arch/mips/kernel/mips_ksyms.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: mips_ksyms.c,v 1.19 1999/04/11 18:37:55 harald Exp $
+/* $Id: mips_ksyms.c,v 1.25 2000/02/24 00:12:40 ralf Exp $
  *
  * Export MIPS-specific functions needed for loadable modules.
  *
@@ -22,8 +22,8 @@
 #include <asm/floppy.h>
 #include <asm/io.h>
 #include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/sgihpc.h>
+#include <asm/pgalloc.h>
+#include <asm/sgi/sgihpc.h>
 #include <asm/softirq.h>
 #include <asm/uaccess.h>
 
@@ -34,6 +34,8 @@
                                     long __len);
 extern long __strlen_user_nocheck_asm(const char *s);
 extern long __strlen_user_asm(const char *s);
+extern long __strnlen_user_nocheck_asm(const char *s);
+extern long __strnlen_user_asm(const char *s);
 
 EXPORT_SYMBOL(EISA_bus);
 
@@ -53,8 +55,7 @@
 EXPORT_SYMBOL_NOVERS(strtok);
 EXPORT_SYMBOL_NOVERS(strpbrk);
 
-EXPORT_SYMBOL(clear_page);
-EXPORT_SYMBOL(__mips_bh_counter);
+EXPORT_SYMBOL(_clear_page);
 EXPORT_SYMBOL(local_bh_count);
 EXPORT_SYMBOL(local_irq_count);
 EXPORT_SYMBOL(enable_irq);
@@ -70,6 +71,8 @@
 EXPORT_SYMBOL_NOVERS(__strncpy_from_user_asm);
 EXPORT_SYMBOL_NOVERS(__strlen_user_nocheck_asm);
 EXPORT_SYMBOL_NOVERS(__strlen_user_asm);
+EXPORT_SYMBOL_NOVERS(__strnlen_user_nocheck_asm);
+EXPORT_SYMBOL_NOVERS(__strnlen_user_asm);
 
 
 /* Networking helper routines. */
@@ -78,10 +81,10 @@
 /*
  * Functions to control caches.
  */
-EXPORT_SYMBOL(flush_page_to_ram);
-EXPORT_SYMBOL(flush_cache_all);
-EXPORT_SYMBOL(dma_cache_wback_inv);
-EXPORT_SYMBOL(dma_cache_inv);
+EXPORT_SYMBOL(_flush_page_to_ram);
+EXPORT_SYMBOL(_flush_cache_all);
+EXPORT_SYMBOL(_dma_cache_wback_inv);
+EXPORT_SYMBOL(_dma_cache_inv);
 
 EXPORT_SYMBOL(invalid_pte_table);
 
@@ -99,7 +102,7 @@
 EXPORT_SYMBOL(vdma_log2phys);
 #endif
 
-#ifdef CONFIG_SGI
+#ifdef CONFIG_SGI_IP22
 EXPORT_SYMBOL(hpc3c0);
 #endif
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/pci.c linux/arch/mips/kernel/pci.c
--- v2.3.47/linux/arch/mips/kernel/pci.c	Sat Oct  9 11:47:50 1999
+++ linux/arch/mips/kernel/pci.c	Wed Dec 31 16:00:00 1969
@@ -1,92 +0,0 @@
-/* $Id: pci.c,v 1.8 1999/05/01 22:40:36 ralf Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * MIPS implementation of PCI BIOS services for PCI support.
- *
- * Copyright (C) 1997, 1998 Ralf Baechle
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-
-#ifdef CONFIG_PCI
-
-struct pci_ops *pci_ops;
-
-/*
- * BIOS32 replacement.
- */
-void __init pcibios_init(void)
-{
-}
-
-/*
- * Following the generic parts of the MIPS BIOS32 code.
- */
-
-int pcibios_present (void)
-{
-	return pci_ops != NULL;
-}
-
-/*
- * The functions below are machine specific and must be reimplimented for
- * each PCI chipset configuration.  We just run the hook to the machine
- * specific implementation.
- */
-void pcibios_fixup (void)
-{
-	pci_ops->pcibios_fixup();
-}
-
-int pcibios_read_config_byte (unsigned char bus, unsigned char dev_fn,
-                              unsigned char where, unsigned char *val)
-{
-	return pci_ops->pcibios_read_config_byte(bus, dev_fn, where, val);
-}
-
-int pcibios_read_config_word (unsigned char bus, unsigned char dev_fn,
-                              unsigned char where, unsigned short *val)
-{
-	return pci_ops->pcibios_read_config_word(bus, dev_fn, where, val);
-}
-
-int pcibios_read_config_dword (unsigned char bus, unsigned char dev_fn,
-                               unsigned char where, unsigned int *val)
-{
-	return pci_ops->pcibios_read_config_dword(bus, dev_fn, where, val);
-}
-
-int pcibios_write_config_byte (unsigned char bus, unsigned char dev_fn,
-                               unsigned char where, unsigned char val)
-{
-	return pci_ops->pcibios_write_config_byte(bus, dev_fn, where, val);
-}
-
-int pcibios_write_config_word (unsigned char bus, unsigned char dev_fn,
-                               unsigned char where, unsigned short val)
-{
-	return pci_ops->pcibios_write_config_word(bus, dev_fn, where, val);
-}
-
-int pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn,
-                                unsigned char where, unsigned int val)
-{
-	return pci_ops->pcibios_write_config_dword(bus, dev_fn, where, val);
-}
-
-char * __init pcibios_setup(char *str)
-{
-	return str;
-}
-
-void __init pcibios_fixup_bus(struct pci_bus *bus)
-{
-}
-
-#endif /* defined(CONFIG_PCI) */
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/proc.c linux/arch/mips/kernel/proc.c
--- v2.3.47/linux/arch/mips/kernel/proc.c	Tue Oct 20 13:52:54 1998
+++ linux/arch/mips/kernel/proc.c	Thu Feb 24 22:52:30 2000
@@ -32,13 +32,17 @@
 	const char *mach_sni_rm_names[] = GROUP_SNI_RM_NAMES;
 	const char *mach_acn_names[] = GROUP_ACN_NAMES;
 	const char *mach_sgi_names[] = GROUP_SGI_NAMES;
+	const char *mach_cobalt_names[] = GROUP_COBALT_NAMES;
+	const char *mach_nec_ddb_names[] = GROUP_NEC_DDB_NAMES;
 	const char **mach_group_to_name[] = { mach_unknown_names,
 	                                      mach_jazz_names,
 	                                      mach_dec_names,
 	                                      mach_arc_names,
 	                                      mach_sni_rm_names,
 	                                      mach_acn_names,
-	                                      mach_sgi_names };
+	                                      mach_sgi_names,
+					      mach_cobalt_names,
+					      mach_nec_ddb_names };
 	unsigned int version = read_32bit_cp0_register(CP0_PRID);
 	int len;
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/process.c linux/arch/mips/kernel/process.c
--- v2.3.47/linux/arch/mips/kernel/process.c	Thu Nov 11 20:11:32 1999
+++ linux/arch/mips/kernel/process.c	Thu Feb 24 22:52:30 2000
@@ -1,10 +1,11 @@
-/* $Id: process.c,v 1.12 1999/06/17 13:25:46 ralf Exp $
+/* $Id: process.c,v 1.18 2000/01/29 01:41:59 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 - 1998 by Ralf Baechle and others.
+ * Copyright (C) 1994 - 1999 by Ralf Baechle and others.
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
 #include <linux/errno.h>
 #include <linux/sched.h>
@@ -28,23 +29,30 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/elf.h>
+#include <asm/isadep.h>
 
-struct task_struct *last_task_used_math = NULL;
-
-asmlinkage void ret_from_sys_call(void);
-
-/*
- * Do necessary setup to start up a newly executed thread.
- */
-void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
+void cpu_idle(void)
 {
-	/* New thread looses kernel privileges. */
-	regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU)) | KSU_USER;
-	regs->cp0_epc = pc;
-	regs->regs[29] = sp;
-	current->tss.current_ds = USER_DS;
+	/* endless idle loop with no priority at all */
+	current->priority = 0;
+	current->counter = -100;
+	init_idle();
+
+	while (1) {
+		while (!current->need_resched)
+			if (wait_available)
+				__asm__(".set\tmips3\n\t"
+					"wait\n\t"
+					".set\tmips0");
+		schedule();
+		check_pgt_cache();
+	}
 }
 
+struct task_struct *last_task_used_math = NULL;
+
+asmlinkage void ret_from_fork(void);
+
 void exit_thread(void)
 {
 	/* Forget lazy fpu state */
@@ -65,21 +73,18 @@
 	}
 }
 
-void release_thread(struct task_struct *dead_task)
-{
-}
-
 int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
                  struct task_struct * p, struct pt_regs * regs)
 {
 	struct pt_regs * childregs;
 	long childksp;
+	extern void save_fp(void*);
 
 	childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32;
 
 	if (last_task_used_math == current) {
 		set_cp0_status(ST0_CU1, ST0_CU1);
-		r4xx0_save_fp(p);
+		save_fp(p);
 	}
 	/* set up new TSS. */
 	childregs = (struct pt_regs *) childksp - 1;
@@ -98,22 +103,21 @@
 	if (childregs->cp0_status & ST0_CU0) {
 		childregs->regs[28] = (unsigned long) p;
 		childregs->regs[29] = childksp;
-		p->tss.current_ds = KERNEL_DS;
+		p->thread.current_ds = KERNEL_DS;
 	} else {
 		childregs->regs[29] = usp;
-		p->tss.current_ds = USER_DS;
+		p->thread.current_ds = USER_DS;
 	}
-	p->tss.reg29 = (unsigned long) childregs;
-	p->tss.reg31 = (unsigned long) ret_from_sys_call;
+	p->thread.reg29 = (unsigned long) childregs;
+	p->thread.reg31 = (unsigned long) ret_from_fork;
 
 	/*
 	 * New tasks loose permission to use the fpu. This accelerates context
 	 * switching for most programs since they don't use the fpu.
 	 */
-	p->tss.cp0_status = read_32bit_cp0_register(CP0_STATUS) &
-                            ~(ST0_CU3|ST0_CU2|ST0_CU1|ST0_KSU);
+	p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) &
+                            ~(ST0_CU3|ST0_CU2|ST0_CU1|KU_MASK);
 	childregs->cp0_status &= ~(ST0_CU3|ST0_CU2|ST0_CU1);
-	p->mm->context = 0;
 
 	return 0;
 }
@@ -121,11 +125,11 @@
 /* Fill in the fpu structure for a core dump.. */
 int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
 {
-	/* We actually store the FPU info in the task->tss
+	/* We actually store the FPU info in the task->thread
 	 * area.
 	 */
 	if(regs->cp0_status & ST0_CU1) {
-		memcpy(r, &current->tss.fpu, sizeof(current->tss.fpu));
+		memcpy(r, &current->thread.fpu, sizeof(current->thread.fpu));
 		return 1;
 	}
 	return 0; /* Task didn't use the fpu at all. */
@@ -143,7 +147,7 @@
 	dump->u_ssize =
 		(current->mm->start_stack - dump->start_stack + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	memcpy(&dump->regs[0], regs, sizeof(struct pt_regs));
-	memcpy(&dump->regs[EF_SIZE/4], &current->tss.fpu, sizeof(current->tss.fpu));
+	memcpy(&dump->regs[EF_SIZE/4], &current->thread.fpu, sizeof(current->thread.fpu));
 }
 
 /*
@@ -195,15 +199,24 @@
 {
 	unsigned long schedule_frame;
 	unsigned long pc;
+
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
-	/*
-	 * The same comment as on the Alpha applies here, too ...
-	 */
-	pc = thread_saved_pc(&p->tss);
-	if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) {
-		schedule_frame = ((unsigned long *)(long)p->tss.reg30)[16];
-		return (unsigned long)((unsigned long *)schedule_frame)[11];
+
+	pc = thread_saved_pc(&p->thread);
+	if (pc == (unsigned long) interruptible_sleep_on
+	    || pc == (unsigned long) sleep_on) {
+		schedule_frame = ((unsigned long *)p->thread.reg30)[9];
+		return ((unsigned long *)schedule_frame)[15];
+	}
+	if (pc == (unsigned long) interruptible_sleep_on_timeout
+	    || pc == (unsigned long) sleep_on_timeout) {
+		schedule_frame = ((unsigned long *)p->thread.reg30)[9];
+		return ((unsigned long *)schedule_frame)[16];
 	}
+	if (pc >= first_sched && pc < last_sched) {
+		printk(KERN_DEBUG "Bug in %s\n", __FUNCTION__);
+	}
+
 	return pc;
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c
--- v2.3.47/linux/arch/mips/kernel/ptrace.c	Mon Jul  5 19:44:57 1999
+++ linux/arch/mips/kernel/ptrace.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: ptrace.c,v 1.13 1999/06/17 13:25:46 ralf Exp $
+/* $Id: ptrace.c,v 1.18 1999/10/09 00:00:58 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -30,6 +30,7 @@
 	struct task_struct *child;
 	unsigned int flags;
 	int res;
+	extern void save_fp(void*);
 
 	lock_kernel();
 #if 0
@@ -136,17 +137,13 @@
 			break;
 		case FPR_BASE ... FPR_BASE + 31:
 			if (child->used_math) {
-				unsigned long long *fregs;
-
 				if (last_task_used_math == child) {
 					enable_cp1();
-					r4xx0_save_fp(child);
+					save_fp(child);
 					disable_cp1();
 					last_task_used_math = NULL;
 				}
-				fregs = (unsigned long long *)
-					&child->tss.fpu.hard.fp_regs[0];
-				tmp = (unsigned long) fregs[(addr - 32)];
+				tmp = child->thread.fpu.hard.fp_regs[addr - 32];
 			} else {
 				tmp = -1;	/* FP not yet used  */
 			}
@@ -167,11 +164,17 @@
 			tmp = regs->lo;
 			break;
 		case FPC_CSR:
-			tmp = child->tss.fpu.hard.control;
+			tmp = child->thread.fpu.hard.control;
 			break;
-		case FPC_EIR:	/* implementation / version register */
-			tmp = 0;	/* XXX */
+		case FPC_EIR: {	/* implementation / version register */
+			unsigned int flags;
+
+			__save_flags(flags);
+			enable_cp1();
+			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+			__restore_flags(flags);
 			break;
+		}
 		default:
 			tmp = 0;
 			res = -EIO;
@@ -191,33 +194,35 @@
 		goto out;
 
 	case PTRACE_POKEUSR: {
-		unsigned long long *fregs;
 		struct pt_regs *regs;
 		int res = 0;
+		regs = (struct pt_regs *) ((unsigned long) child +
+		       KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs));
 
 		switch (addr) {
 		case 0 ... 31:
-			regs = (struct pt_regs *) ((unsigned long) child +
-			       KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs));
+			regs->regs[addr] = data;
 			break;
-		case FPR_BASE ... FPR_BASE + 31:
+		case FPR_BASE ... FPR_BASE + 31: {
+			unsigned int *fregs;
 			if (child->used_math) {
 				if (last_task_used_math == child) {
 					enable_cp1();
-					r4xx0_save_fp(child);
+					save_fp(child);
 					disable_cp1();
 					last_task_used_math = NULL;
+					regs->cp0_status &= ~ST0_CU1;
 				}
 			} else {
 				/* FP not yet used  */
-				memset(&child->tss.fpu.hard, ~0,
-				       sizeof(child->tss.fpu.hard));
-				child->tss.fpu.hard.control = 0;
+				memset(&child->thread.fpu.hard, ~0,
+				       sizeof(child->thread.fpu.hard));
+				child->thread.fpu.hard.control = 0;
 			}
-			fregs = (unsigned long long *)
-				&child->tss.fpu.hard.fp_regs[0];
-			fregs[(addr - 32)] = (unsigned long long) data;
+			fregs = child->thread.fpu.hard.fp_regs;
+			fregs[addr - FPR_BASE] = data;
 			break;
+		}
 		case PC:
 			regs->cp0_epc = data;
 			break;
@@ -228,7 +233,7 @@
 			regs->lo = data;
 			break;
 		case FPC_CSR:
-			child->tss.fpu.hard.control = data;
+			child->thread.fpu.hard.control = data;
 			break;
 		default:
 			/* The rest are not allowed. */
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/r2300_fpu.S linux/arch/mips/kernel/r2300_fpu.S
--- v2.3.47/linux/arch/mips/kernel/r2300_fpu.S	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/r2300_fpu.S	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,5 @@
-/* $Id: r2300_fpu.S,v 1.5 1999/05/01 22:40:36 ralf Exp $
+/* $Id: r2300_fpu.S,v 1.7 1999/09/28 22:25:47 ralf Exp $
+ *
  * r2300_fpu.S: Save/restore floating point context for signal handlers.
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -14,6 +15,7 @@
  * Copyright (c) 1998 Harald Koerfgen
  */
 #include <asm/asm.h>
+#include <asm/errno.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 #include <asm/offset.h>
@@ -28,8 +30,8 @@
 	.set	noreorder
 	.set	mips1
 	/* Save floating point context */
-LEAF(r2300_save_fp_context)
-
+LEAF(save_fp_context)
+	li	v0, 0					# assume success
 	cfc1	t1,fcr31
 	EX(swc1	$f0,(SC_FPREGS+0)(a0))
 	EX(swc1	$f1,(SC_FPREGS+8)(a0))
@@ -69,7 +71,7 @@
 	.set	nomacro
 	 EX(sw	t0,SC_FPC_EIR(a0))
 	.set	macro
-	END(r2300_save_fp_context)
+	END(save_fp_context)
 
 /*
  * Restore FPU state:
@@ -80,7 +82,8 @@
  * frame on the current content of c0_status, not on the content of the
  * stack frame which might have been changed by the user.
  */
-LEAF(r2300_restore_fp_context)
+LEAF(restore_fp_context)
+	li	v0, 0					# assume success
 	EX(lw t0,SC_FPC_CSR(a0))
 	EX(lwc1	$f0,(SC_FPREGS+0)(a0))
 	EX(lwc1	$f1,(SC_FPREGS+8)(a0))
@@ -116,4 +119,10 @@
 	EX(lwc1	$f31,(SC_FPREGS+248)(a0))
 	jr	ra
 	 ctc1	t0,fcr31
-	END(r2300_restore_fp_context)
+	END(restore_fp_context)
+
+	.type	fault@function
+	.ent	fault
+fault:	li	v0, -EFAULT
+	jr	ra
+	.end	fault
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/r2300_misc.S linux/arch/mips/kernel/r2300_misc.S
--- v2.3.47/linux/arch/mips/kernel/r2300_misc.S	Wed Jun 30 11:24:54 1999
+++ linux/arch/mips/kernel/r2300_misc.S	Thu Feb 24 22:52:30 2000
@@ -1,5 +1,5 @@
-/* $Id: r2300_misc.S,v 1.3 1999/05/01 22:40:36 ralf Exp $
- * r2300_misc.S: Misc. exception handling code for R3000/R2000.
+/* $Id: r2300_misc.S,v 1.8 1999/12/08 22:05:10 harald Exp $
+ * misc.S: Misc. exception handling code for R3000/R2000.
  *
  * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
  *
@@ -8,14 +8,15 @@
  *
  * Further modifications to make this work:
  * Copyright (c) 1998 Harald Koerfgen
- * Copyright (c) 1998 Gleb Raiko & Vladimir Roganov
+ * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov
  */
+#include <linux/config.h>
+
 #include <asm/asm.h>
 #include <asm/current.h>
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
 #include <asm/fpregdef.h>
-#include <asm/mipsconfig.h>
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -38,11 +39,10 @@
 	 */
 #define LOAD_PTE(pte, ptr) \
 	mfc0	pte, CP0_BADVADDR; \
-	_GET_CURRENT(ptr); \
+	lw	ptr, current_pgd; \
 	srl	pte, pte, 22; \
-	lw	ptr, THREAD_PGDIR(ptr); \
 	sll	pte, pte, 2; \
-	addu	ptr, pte, ptr; \
+	addu	ptr, ptr, pte; \
 	mfc0	pte, CP0_CONTEXT; \
 	lw	ptr, (ptr); \
 	andi	pte, pte, 0xffc; \
@@ -115,56 +115,67 @@
 			   _PAGE_VALID | _PAGE_DIRTY); \
 	sw	pte, (ptr);
 
+/*
+ * The index register may have the probe fail bit set,
+ * because we would trap on access kseg2, i.e. without refill.
+ */
+#define TLB_WRITE(reg) \
+	mfc0	reg, CP0_INDEX; \
+	nop; \
+	bltz    reg, 1f; \
+	 nop; \
+	tlbwi; \
+	j	2f; \
+	 nop; \
+1:	tlbwr; \
+2:
+
+#define RET(reg) \
+	mfc0	reg, CP0_EPC; \
+	nop; \
+	jr	reg; \
+	 rfe
+			
 	.set	noreorder
 
 	.align	5
-NESTED(r2300_handle_tlbl, PT_SIZE, sp)
+NESTED(handle_tlbl, PT_SIZE, sp)
 	.set	noat
 
 #ifndef NOTLB_OPTIMIZE
 	/* Test present bit in entry. */
 	LOAD_PTE(k0, k1)
         tlbp
-	nop
         PTE_PRESENT(k0, k1, nopage_tlbl)
         PTE_MAKEVALID(k0, k1)
         PTE_RELOAD(k1)
-	tlbwi
-	nop
-	mfc0	k0, CP0_EPC
-	nop
-	jr	k0
-	 rfe
+	TLB_WRITE(k0)
+	RET(k0)
 nopage_tlbl:
 #endif
 
 	DO_FAULT(0)
-END(r2300_handle_tlbl)
+END(handle_tlbl)
 
-NESTED(r2300_handle_tlbs, PT_SIZE, sp)
+NESTED(handle_tlbs, PT_SIZE, sp)
 	.set	noat
 
 #ifndef NOTLB_OPTIMIZE
 	LOAD_PTE(k0, k1)
 	tlbp                            # find faulting entry
-	nop
 	PTE_WRITABLE(k0, k1, nopage_tlbs)
 	PTE_MAKEWRITE(k0, k1)
 	PTE_RELOAD(k1)
-	tlbwi
-	nop
-	mfc0	k0, CP0_EPC
-	nop
-	jr	k0
-	 rfe
+	TLB_WRITE(k0)
+	RET(k0)
 nopage_tlbs:
 #endif
 
 	DO_FAULT(1)
-END(r2300_handle_tlbs)
+END(handle_tlbs)
 
 	.align	5
-NESTED(r2300_handle_mod, PT_SIZE, sp)
+NESTED(handle_mod, PT_SIZE, sp)
 	.set	noat
 #ifndef NOTLB_OPTIMIZE
 	LOAD_PTE(k0, k1)
@@ -181,15 +192,10 @@
 
 	/* Now reload the entry into the tlb. */
 	PTE_RELOAD(k1)
-	nop
 	tlbwi
-	nop
-	mfc0	k0, CP0_EPC
-	nop
-	jr	k0
-	 rfe
+	RET(k0)
 #endif
 
 nowrite_mod:
 	DO_FAULT(1)
-END(r2300_handle_mod)
+END(handle_mod)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/r2300_switch.S linux/arch/mips/kernel/r2300_switch.S
--- v2.3.47/linux/arch/mips/kernel/r2300_switch.S	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/r2300_switch.S	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: r2300_switch.S,v 1.6 1999/06/13 16:30:32 ralf Exp $
+/* $Id: r2300_switch.S,v 1.9 1999/10/12 17:33:49 harald Exp $
  *
  * r2300_switch.S: R2300 specific task switching code.
  *
@@ -16,7 +16,6 @@
 #include <asm/cachectl.h>
 #include <asm/current.h>
 #include <asm/fpregdef.h>
-#include <asm/mipsconfig.h>
 #include <asm/mipsregs.h>
 #include <asm/offset.h>
 #include <asm/page.h>
@@ -34,7 +33,7 @@
  * task_struct *r4xx0_resume(task_struct *prev,
  *                           task_struct *next)
  */
-LEAF(r2300_resume)
+LEAF(resume)
 	.set	reorder
 	mfc0	t1, CP0_STATUS
 	.set	noreorder
@@ -56,15 +55,11 @@
 	lw	a2, THREAD_STATUS($28)
 	nor	a3, $0, a3
 	and	a2, a3
-	lw	a3, TASK_MM($28)
 	or	a2, t1
-	lw	a3, MM_CONTEXT(a3)
 	mtc0	a2, CP0_STATUS
-	andi	a3, 0xfc0
-	mtc0	a3, CP0_ENTRYHI
 	jr	ra
 	 move	v0, a0
-	END(r2300_resume)
+	END(resume)
 
 /*
  * Do lazy fpu context switch.  Saves FPU context to the process in a0
@@ -73,7 +68,7 @@
 
 #define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS)
 
-LEAF(r2300_lazy_fpu_switch)
+LEAF(lazy_fpu_switch)
 	mfc0	t0, CP0_STATUS			# enable cp1
 	li	t3, 0x20000000
 	or	t0, t3
@@ -87,24 +82,24 @@
 	and	t1, t3
 	sw	t1, ST_OFF(a0)
 	swc1	$f0, (THREAD_FPU + 0x00)(a0)
-	FPU_SAVE(a0, t1)			# clobbers t1
+	FPU_SAVE_SINGLE(a0, t1)			# clobbers t1
 
 2:
 	lwc1	$f0, (THREAD_FPU + 0x00)($28)
 	.set	reorder
-	FPU_RESTORE($28, t0)		# clobbers t0
+	FPU_RESTORE_SINGLE($28, t0)		# clobbers t0
 	jr	ra
-	END(r2300_lazy_fpu_switch)
+	END(lazy_fpu_switch)
 
 /*
  * Save a thread's fp context.
  */
 	.set	noreorder
-LEAF(r2300_save_fp)
-	FPU_SAVE(a0, t1)			# clobbers t1
+LEAF(save_fp)
+	FPU_SAVE_SINGLE(a0, t1)			# clobbers t1
 	jr	ra
 	 swc1	$f0, (THREAD_FPU + 0x00)(a0)
-	END(r2300_save_fp)
+	END(save_fp)
 
 /*
  * Load the FPU with signalling NANS.  This bit pattern we're using has
@@ -116,7 +111,7 @@
 
 #define FPU_DEFAULT  0x00000000
 
-LEAF(r2300_init_fpu)
+LEAF(init_fpu)
 	mfc0	t0, CP0_STATUS
 	li	t1, 0x20000000
 	or	t0, t1
@@ -160,4 +155,4 @@
 	mtc1	t0, $f30
 	jr	ra
 	 mtc1	t0, $f31
-	END(r2300_init_fpu)
+	END(init_fpu)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/r4k_fpu.S linux/arch/mips/kernel/r4k_fpu.S
--- v2.3.47/linux/arch/mips/kernel/r4k_fpu.S	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/r4k_fpu.S	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,5 @@
-/*
+/* $Id: r4k_fpu.S,v 1.8 1999/09/28 22:25:47 ralf Exp $
+ *
  * r4k_fpu.S: Save/restore floating point context for signal handlers.
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -9,10 +10,9 @@
  *
  * Multi-arch abstraction and asm macros for easier reading:
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: r4k_fpu.S,v 1.5 1999/05/01 22:40:36 ralf Exp $
  */
 #include <asm/asm.h>
+#include <asm/errno.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 #include <asm/offset.h>
@@ -21,35 +21,15 @@
 #define EX(a,b)							\
 9:	a,##b;							\
 	.section __ex_table,"a";				\
-	PTR	9b,bad_stack;					\
+	PTR	9b, fault;					\
 	.previous
 
 	.set	noreorder
 	.set	mips3
 	/* Save floating point context */
-LEAF(r4k_save_fp_context)
-	mfc0	t1,CP0_STATUS
-	 sll	t2,t1,5
-
-	bgez	t2,1f
-	 cfc1	t1,fcr31
-	/* Store the 16 odd double precision registers */
-	EX(sdc1	$f1,(SC_FPREGS+8)(a0))
-	EX(sdc1	$f3,(SC_FPREGS+24)(a0))
-	EX(sdc1	$f5,(SC_FPREGS+40)(a0))
-	EX(sdc1	$f7,(SC_FPREGS+56)(a0))
-	EX(sdc1	$f9,(SC_FPREGS+72)(a0))
-	EX(sdc1	$f11,(SC_FPREGS+88)(a0))
-	EX(sdc1	$f13,(SC_FPREGS+104)(a0))
-	EX(sdc1	$f15,(SC_FPREGS+120)(a0))
-	EX(sdc1	$f17,(SC_FPREGS+136)(a0))
-	EX(sdc1	$f19,(SC_FPREGS+152)(a0))
-	EX(sdc1	$f21,(SC_FPREGS+168)(a0))
-	EX(sdc1	$f23,(SC_FPREGS+184)(a0))
-	EX(sdc1	$f25,(SC_FPREGS+200)(a0))
-	EX(sdc1	$f27,(SC_FPREGS+216)(a0))
-	EX(sdc1	$f29,(SC_FPREGS+232)(a0))
-	EX(sdc1	$f31,(SC_FPREGS+248)(a0))
+LEAF(save_fp_context)
+	li	v0, 0					# assume success
+	cfc1	t1,fcr31
 
 	/* Store the 16 even double precision registers */
 1:
@@ -76,7 +56,7 @@
 	.set	nomacro
 	 EX(sw	t0,SC_FPC_EIR(a0))
 	.set	macro
-	END(r4k_save_fp_context)
+	END(save_fp_context)
 
 /*
  * Restore FPU state:
@@ -87,31 +67,9 @@
  * frame on the current content of c0_status, not on the content of the
  * stack frame which might have been changed by the user.
  */
-LEAF(r4k_restore_fp_context)
-	mfc0	t1, CP0_STATUS
-	sll	t0,t1,5
-	bgez	t0,1f
-	 EX(lw	t0,SC_FPC_CSR(a0))
-
-	/* Restore the 16 odd double precision registers only
-	 * when enabled in the cp0 status register.
-	 */
-	EX(ldc1	$f1,(SC_FPREGS+8)(a0))
-	EX(ldc1	$f3,(SC_FPREGS+24)(a0))
-	EX(ldc1	$f5,(SC_FPREGS+40)(a0))
-	EX(ldc1	$f7,(SC_FPREGS+56)(a0))
-	EX(ldc1	$f9,(SC_FPREGS+72)(a0))
-	EX(ldc1	$f11,(SC_FPREGS+88)(a0))
-	EX(ldc1	$f13,(SC_FPREGS+104)(a0))
-	EX(ldc1	$f15,(SC_FPREGS+120)(a0))
-	EX(ldc1	$f17,(SC_FPREGS+136)(a0))
-	EX(ldc1	$f19,(SC_FPREGS+152)(a0))
-	EX(ldc1	$f21,(SC_FPREGS+168)(a0))
-	EX(ldc1	$f23,(SC_FPREGS+184)(a0))
-	EX(ldc1	$f25,(SC_FPREGS+200)(a0))
-	EX(ldc1	$f27,(SC_FPREGS+216)(a0))
-	EX(ldc1	$f29,(SC_FPREGS+232)(a0))
-	EX(ldc1	$f31,(SC_FPREGS+248)(a0))
+LEAF(restore_fp_context)
+	li	v0, 0					# assume success
+	EX(lw	t0,SC_FPC_CSR(a0))
 
 	/*
 	 * Restore the 16 even double precision registers
@@ -135,4 +93,10 @@
 	EX(ldc1	$f30,(SC_FPREGS+240)(a0))
 	jr	ra
 	 ctc1	t0,fcr31
-	END(r4k_restore_fp_context)
+	END(restore_fp_context)
+
+	.type	fault@function
+	.ent	fault
+fault:	li	v0, -EFAULT
+	jr	ra
+	.end	fault
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/r4k_misc.S linux/arch/mips/kernel/r4k_misc.S
--- v2.3.47/linux/arch/mips/kernel/r4k_misc.S	Mon Jul  5 20:35:17 1999
+++ linux/arch/mips/kernel/r4k_misc.S	Thu Feb 24 22:52:30 2000
@@ -1,12 +1,11 @@
-/*
+/* $Id: r4k_misc.S,v 1.9 1999/12/04 03:59:00 ralf Exp $
+ *
  * r4k_misc.S: Misc. exception handling code for r4k.
  *
  * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
  *
  * Multi-cpu abstraction and reworking:
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: r4k_misc.S,v 1.4 1997/12/01 17:57:30 ralf Exp $
  */
 #include <asm/asm.h>
 #include <asm/current.h>
@@ -14,7 +13,6 @@
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
 #include <asm/fpregdef.h>
-#include <asm/mipsconfig.h>
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -33,10 +31,9 @@
 #define LOAD_PTE(pte, ptr) \
 	mfc0	pte, CP0_BADVADDR; \
 	srl	pte, pte, 22; \
-	_GET_CURRENT(ptr); \
+	lw	ptr, current_pgd; \
 	sll	pte, pte, 2; \
-	lw	ptr, THREAD_PGDIR(ptr); \
-	addu	ptr, pte, ptr; \
+	addu	ptr, ptr, pte; \
 	mfc0	pte, CP0_BADVADDR; \
 	lw	ptr, (ptr); \
 	srl	pte, pte, 10; \
@@ -60,7 +57,6 @@
 
 #define DO_FAULT(write) \
 	.set	noat; \
-	.set	macro; \
 	SAVE_ALL; \
 	mfc0	a2, CP0_BADVADDR; \
 	STI; \
@@ -70,8 +66,7 @@
 	 li	a1, write; \
 	j	ret_from_sys_call; \
 	 nop; \
-	.set	noat; \
-	.set	nomacro;
+	.set	noat;
 
 	/* Check is PTE is present, if not then jump to LABEL.
 	 * PTR points to the page table where this PTE is located,
@@ -136,9 +131,8 @@
 	 * of the instruction cache else you get bogus results.
 	 */
 	.align	5
-	NESTED(r4k_handle_tlbl, PT_SIZE, sp)
+	NESTED(handle_tlbl, PT_SIZE, sp)
 	.set	noat
-	.set	nomacro
 invalid_tlbl:
 #ifndef NOTLB_OPTIMIZE
 	/* Test present bit in entry. */
@@ -158,10 +152,10 @@
 
 nopage_tlbl:
 	DO_FAULT(0)
-	END(r4k_handle_tlbl)
+	END(handle_tlbl)
 
 	.align	5
-	NESTED(r4k_handle_tlbs, PT_SIZE, sp)
+	NESTED(handle_tlbs, PT_SIZE, sp)
 	.set	noat
 #ifndef NOTLB_OPTIMIZE
 	LOAD_PTE(k0, k1)
@@ -180,10 +174,10 @@
 
 nopage_tlbs:
 	DO_FAULT(1)
-	END(r4k_handle_tlbs)
+	END(handle_tlbs)
 
 	.align	5
-	NESTED(r4k_handle_mod, PT_SIZE, sp)
+	NESTED(handle_mod, PT_SIZE, sp)
 	.set	noat
 #ifndef NOTLB_OPTIMIZE
 	LOAD_PTE(k0, k1)
@@ -212,4 +206,4 @@
 
 nowrite_mod:
 	DO_FAULT(1)
-	END(r4k_handle_mod)
+	END(handle_mod)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/r4k_switch.S linux/arch/mips/kernel/r4k_switch.S
--- v2.3.47/linux/arch/mips/kernel/r4k_switch.S	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/r4k_switch.S	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: r4k_switch.S,v 1.7 1999/06/13 16:30:32 ralf Exp $
+/* $Id: r4k_switch.S,v 1.10 1999/10/09 00:00:58 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -7,13 +7,13 @@
  * Copyright (C) 1994, 1995, 1996, 1998, 1999 by Ralf Baechle
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1994, 1995, 1996, by Andreas Busse
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
 #include <asm/asm.h>
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
 #include <asm/current.h>
 #include <asm/fpregdef.h>
-#include <asm/mipsconfig.h>
 #include <asm/mipsregs.h>
 #include <asm/offset.h>
 #include <asm/page.h>
@@ -24,14 +24,14 @@
 
 #include <asm/asmmacro.h>
 
+	.set	mips3
+
 /*
- * task_struct *r4xx0_resume(task_struct *prev,
- *                           task_struct *next)
+ * task_struct *r4xx0_resume(task_struct *prev, task_struct *next)
  */
 	.set	noreorder
-	.set	mips3
 	.align	5
-	LEAF(r4xx0_resume)
+	LEAF(resume)
 	mfc0	t1, CP0_STATUS
 	sw	t1, THREAD_STATUS(a0)
 	CPU_SAVE_NONSCRATCH(a0)
@@ -51,15 +51,11 @@
 	lw	a2, THREAD_STATUS($28)
 	nor	a3, $0, a3
 	and	a2, a3
-	lw	a3, TASK_MM($28)
 	or	a2, t1
-	lw	a3, MM_CONTEXT(a3)
 	mtc0	a2, CP0_STATUS
-	andi	a3, a3, 0xff
-	mtc0	a3, CP0_ENTRYHI
 	jr	ra
 	 move	v0, a0
-	END(r4xx0_resume)
+	END(resume)
 
 /*
  * Do lazy fpu context switch.  Saves FPU context to the process in a0
@@ -68,7 +64,7 @@
 
 #define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS)
 
-LEAF(r4xx0_lazy_fpu_switch)
+LEAF(lazy_fpu_switch)
 	mfc0	t0, CP0_STATUS			# enable cp1
 	li	t3, 0x20000000
 	or	t0, t3
@@ -76,42 +72,27 @@
 
 	beqz	a0, 2f				# Save floating point state
 	 nor	t3, zero, t3
+
 	lw	t1, ST_OFF(a0)			# last thread looses fpu
 	and	t1, t3
 	sw	t1, ST_OFF(a0)
-	sll	t2, t1, 5
-	bgez	t2, 1f
-	 sdc1	$f0, (THREAD_FPU + 0x00)(a0)
-	FPU_SAVE_16ODD(a0)
-1:
-	FPU_SAVE_16EVEN(a0, t1)			# clobbers t1
+
+
+	FPU_SAVE_DOUBLE(a0, t1)			# clobbers t1
 2:
 
-	sll	t0, t0, 5			# load new fp state
-	bgez	t0, 1f
-	 ldc1	$f0, (THREAD_FPU + 0x00)($28)
-	FPU_RESTORE_16ODD($28)
-1:
 	.set	reorder
-	FPU_RESTORE_16EVEN($28, t0)		# clobbers t0
+	FPU_RESTORE_DOUBLE($28, t0)		# clobbers t0
 	jr	ra
-	END(r4xx0_lazy_fpu_switch)
+	END(lazy_fpu_switch)
 
 /*
  * Save a thread's fp context.
  */
-	.set	noreorder
-LEAF(r4xx0_save_fp)
-	mfc0	t0, CP0_STATUS
-	sll	t1, t0, 5
-	bgez	t1, 1f				# 16 register mode?
-	 nop
-	FPU_SAVE_16ODD(a0)
-1:
-	FPU_SAVE_16EVEN(a0, t1)			# clobbers t1
+LEAF(save_fp)
+	FPU_SAVE_DOUBLE(a0, t1)			# clobbers t1
 	jr	ra
-	 sdc1	$f0, (THREAD_FPU + 0x00)(a0)
-	END(r4xx0_save_fp)
+	END(save_fp)
 
 /*
  * Load the FPU with signalling NANS.  This bit pattern we're using has
@@ -123,37 +104,18 @@
 
 #define FPU_DEFAULT  0x00000000
 
-LEAF(r4xx0_init_fpu)
+LEAF(init_fpu)
 	mfc0	t0, CP0_STATUS
 	li	t1, 0x20000000
 	or	t0, t1
 	mtc0	t0, CP0_STATUS
-	sll	t0, t0, 5
 
 	li	t1, FPU_DEFAULT
 	ctc1	t1, fcr31
 
-	bgez	t0, 1f			# 16 / 32 register mode?
-	 li	t0, -1
-
-	dmtc1	t0, $f1
-	dmtc1	t0, $f3
-	dmtc1	t0, $f5
-	dmtc1	t0, $f7
-	dmtc1	t0, $f9
-	dmtc1	t0, $f11
-	dmtc1	t0, $f13
-	dmtc1	t0, $f15
-	dmtc1	t0, $f17
-	dmtc1	t0, $f19
-	dmtc1	t0, $f21
-	dmtc1	t0, $f23
-	dmtc1	t0, $f25
-	dmtc1	t0, $f27
-	dmtc1	t0, $f29
-	dmtc1	t0, $f31
+	li	t0, -1
 
-1:	dmtc1	t0, $f0
+	dmtc1	t0, $f0
 	dmtc1	t0, $f2
 	dmtc1	t0, $f4
 	dmtc1	t0, $f6
@@ -168,6 +130,8 @@
 	dmtc1	t0, $f24
 	dmtc1	t0, $f26
 	dmtc1	t0, $f28
+	.set	noreorder
 	jr	ra
 	 dmtc1	t0, $f30
-	END(r4xx0_init_fpu)
+	.set	reorder
+	END(init_fpu)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/r6000_fpu.S linux/arch/mips/kernel/r6000_fpu.S
--- v2.3.47/linux/arch/mips/kernel/r6000_fpu.S	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/r6000_fpu.S	Thu Feb 24 22:52:30 2000
@@ -10,7 +10,7 @@
  * Multi-arch abstraction and asm macros for easier reading:
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: r6000_fpu.S,v 1.5 1999/05/01 22:40:37 ralf Exp $
+ * $Id: r6000_fpu.S,v 1.6 1999/08/09 19:43:15 harald Exp $
  */
 #include <asm/asm.h>
 #include <asm/fpregdef.h>
@@ -21,7 +21,7 @@
 	.set	noreorder
 	.set	mips2
 	/* Save floating point context */
-	LEAF(r6000_save_fp_context)
+	LEAF(save_fp_context)
 	mfc0	t0,CP0_STATUS
 	sll	t0,t0,2
 	bgez	t0,1f
@@ -49,7 +49,7 @@
 	 sw	t0,SC_FPC_CSR(a0)
 1:	jr	ra
 	 nop
-	END(r6000_save_fp_context)
+	END(save_fp_context)
 
 /* Restore FPU state:
  *  - fp gp registers
@@ -59,7 +59,7 @@
  * frame on the current content of c0_status, not on the content of the
  * stack frame which might have been changed by the user.
  */
-	LEAF(r6000_restore_fp_context)
+	LEAF(restore_fp_context)
 	mfc0	t0,CP0_STATUS
 	sll	t0,t0,2
 
@@ -86,4 +86,4 @@
 	 ctc1	t0,fcr31
 1:	jr	ra
 	 nop
-	END(r6000_restore_fp_context)
+	END(restore_fp_context)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/scall_o32.S linux/arch/mips/kernel/scall_o32.S
--- v2.3.47/linux/arch/mips/kernel/scall_o32.S	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/scall_o32.S	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: scall_o32.S,v 1.4 1998/06/25 20:01:01 ralf Exp $
+/* $Id: scall_o32.S,v 1.11 2000/02/23 01:33:55 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -12,6 +12,7 @@
 #include <asm/mipsregs.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
+#include <asm/isadep.h>
 #include <asm/unistd.h>
 
 /* This duplicates the definition from <linux/sched.h> */
@@ -48,6 +49,7 @@
 	bgez	t0, stackargs
 
 stack_done:
+        sw      a3, PT_R26(sp)          # save for syscall restart
 	lw	t0, TASK_FLAGS($28)	# syscall tracing enabled?
 	andi	t0, PF_TRACESYS
 	bnez	t0, trace_a_syscall
@@ -64,13 +66,13 @@
 1:	sw	v0, PT_R2(sp)		# result
 
 EXPORT(o32_ret_from_sys_call)
-	lw	t0,bh_mask
-	lw	t1,bh_active		# unused delay slot
-	and	t0,t1
-	bnez	t0,o32_handle_bottom_half
+	lw	t0, softirq_state
+	lw	t1, softirq_state+4	# unused delay slot
+	and	t0, t1
+	bnez	t0, o32_handle_softirq
 
 9:	lw	t0,PT_STATUS(sp)	# returning to kernel mode?
-	andi	t1, t0, 0x10
+	andi	t1, t0, KU_USER
 	lw	t2, TASK_NEED_RESCHED($28)
 	beqz	t1, o32_return		# -> yes
 	bnez	t2, o32_reschedule
@@ -83,13 +85,10 @@
 
 o32_return:
 	RESTORE_SOME
-	RESTORE_SP
-	.set	mips3
-	eret
-	.set	mips0
+	RESTORE_SP_AND_RET
 
-o32_handle_bottom_half:
-	jal	do_bottom_half
+o32_handle_softirq:
+	jal	do_softirq
 	b	9b
 o32_reschedule:
 	SAVE_STATIC
@@ -100,9 +99,9 @@
 
 trace_a_syscall:
 	SAVE_STATIC
-	sw	t2,PT_R1(sp)
+	sw	t2, PT_R1(sp)
 	jal	syscall_trace
-	lw	t2,PT_R1(sp)
+	lw	t2, PT_R1(sp)
 
 	lw	a0, PT_R4(sp)		# Restore argument registers
 	lw	a1, PT_R5(sp)
@@ -140,15 +139,28 @@
 
 	lw	t0, PT_R29(sp)		# get old user stack pointer
 	la	t1, 3f			# copy 1 to 2 arguments
-	sll	t3, t3, 3
+	sll	t3, t3, 4
 	subu	t1, t3
 	jr	t1
 
 	/* Ok, copy the args from the luser stack to the kernel stack */
+	/*
+	 * I know Ralf doesn't like nops but this avoids code
+	 * duplication for R3000 targets (and this is the
+	 * only place where ".set reorder" doesn't help).
+	 * Harald.
+	 */
+	.set    push
+	.set    noreorder
 1:	lw	t1, 20(t0)		# argument #6 from usp
+	nop
 	sw	t1, 20(sp)
+	nop
 2:	lw	t1, 16(t0)		# argument #5 from usp
+	nop
 	sw	t1, 16(sp)
+	nop
+	.set	pop
 
 3:	j	stack_done		# go back
 
@@ -177,3 +189,4 @@
 	li	t0, 1				# set error flag
 	sw	t0, PT_R7(sp)
 	j	ret_from_sys_call
+	END(handle_sys)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/semaphore.c linux/arch/mips/kernel/semaphore.c
--- v2.3.47/linux/arch/mips/kernel/semaphore.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/kernel/semaphore.c	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,240 @@
+/*
+ *  Generic semaphore code. Buyer beware. Do your own
+ * specific changes in <asm/semaphore-helper.h>
+ */
+
+#include <linux/sched.h>
+#include <asm/semaphore-helper.h>
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to sleep, while the "waking" variable is
+ * incremented when the "up()" code goes to wake up waiting
+ * processes.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * waking_non_zero() (from asm/semaphore.h) must execute
+ * atomically.
+ *
+ * When __up() is called, the count was negative before
+ * incrementing it, and we need to wake up somebody.
+ *
+ * This routine adds one to the count of processes that need to
+ * wake up and exit.  ALL waiting processes actually wake up but
+ * only the one that gets to the "waking" field first will gate
+ * through and acquire the semaphore.  The others will go back
+ * to sleep.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+void __up(struct semaphore *sem)
+{
+	wake_one_more(sem);
+	wake_up(&sem->wait);
+}
+
+/*
+ * Perform the "down" function.  Return zero for semaphore acquired,
+ * return negative for signalled out of the function.
+ *
+ * If called from __down, the return is ignored and the wait loop is
+ * not interruptible.  This means that a task waiting on a semaphore
+ * using "down()" cannot be killed until someone does an "up()" on
+ * the semaphore.
+ *
+ * If called from __down_interruptible, the return value gets checked
+ * upon return.  If the return value is negative then the task continues
+ * with the negative value in the return register (it can be tested by
+ * the caller).
+ *
+ * Either form may be used in conjunction with "up()".
+ *
+ */
+
+#define DOWN_VAR				\
+	struct task_struct *tsk = current;	\
+	wait_queue_t wait;			\
+	init_waitqueue_entry(&wait, tsk);
+
+#define DOWN_HEAD(task_state)						\
+									\
+									\
+	tsk->state = (task_state);					\
+	add_wait_queue(&sem->wait, &wait);				\
+									\
+	/*								\
+	 * Ok, we're set up.  sem->count is known to be less than zero	\
+	 * so we must wait.						\
+	 *								\
+	 * We can let go the lock for purposes of waiting.		\
+	 * We re-acquire it after awaking so as to protect		\
+	 * all semaphore operations.					\
+	 *								\
+	 * If "up()" is called before we call waking_non_zero() then	\
+	 * we will catch it right away.  If it is called later then	\
+	 * we will have to go through a wakeup cycle to catch it.	\
+	 *								\
+	 * Multiple waiters contend for the semaphore lock to see	\
+	 * who gets to gate through and who has to wait some more.	\
+	 */								\
+	for (;;) {
+
+#define DOWN_TAIL(task_state)			\
+		tsk->state = (task_state);	\
+	}					\
+	tsk->state = TASK_RUNNING;		\
+	remove_wait_queue(&sem->wait, &wait);
+
+void __down(struct semaphore * sem)
+{
+	DOWN_VAR
+	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+	if (waking_non_zero(sem))
+		break;
+	schedule();
+	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+	DOWN_VAR
+	DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+	ret = waking_non_zero_interruptible(sem, tsk);
+	if (ret)
+	{
+		if (ret == 1)
+			/* ret != 0 only if we get interrupted -arca */
+			ret = 0;
+		break;
+	}
+	schedule();
+	DOWN_TAIL(TASK_INTERRUPTIBLE)
+	return ret;
+}
+
+int __down_trylock(struct semaphore * sem)
+{
+	return waking_non_zero_trylock(sem);
+}
+
+/*
+ * RW Semaphores
+ */
+void
+__down_read(struct rw_semaphore *sem, int count)
+{
+	DOWN_VAR;
+
+ retry_down:
+	if (count < 0) {
+		/* Wait for the lock to become unbiased.  Readers
+		   are non-exclusive.  */
+		
+		/* This takes care of granting the lock.  */
+		up_read(sem);
+
+		add_wait_queue(&sem->wait, &wait);
+		while (atomic_read(&sem->count) < 0) {
+			set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+			if (atomic_read(&sem->count) >= 0)
+				break;
+			schedule();
+		}
+
+		remove_wait_queue(&sem->wait, &wait);
+		tsk->state = TASK_RUNNING;
+
+		mb();
+		count = atomic_dec_return(&sem->count);
+		if (count <= 0)
+			goto retry_down;
+	} else {
+		add_wait_queue(&sem->wait, &wait);
+
+		while (1) {
+			if (test_and_clear_bit(0, &sem->granted))
+				break;
+			set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+			if ((sem->granted & 1) == 0)
+				schedule();
+		}
+
+		remove_wait_queue(&sem->wait, &wait);
+		tsk->state = TASK_RUNNING;
+	}
+}
+
+void
+__down_write(struct rw_semaphore *sem, int count)
+{
+	DOWN_VAR;
+
+ retry_down:
+	if (count + RW_LOCK_BIAS < 0) {
+		up_write(sem);
+
+		add_wait_queue_exclusive(&sem->wait, &wait);
+	
+		while (atomic_read(&sem->count) < 0) {
+			set_task_state(tsk, (TASK_UNINTERRUPTIBLE
+					     | TASK_EXCLUSIVE));
+			if (atomic_read(&sem->count) >= RW_LOCK_BIAS)
+				break;
+			schedule();
+		}
+
+		remove_wait_queue(&sem->wait, &wait);
+		tsk->state = TASK_RUNNING;
+
+		mb();
+		count = atomic_sub_return(RW_LOCK_BIAS, &sem->count);
+		if (count != 0)
+			goto retry_down;
+	} else {
+		/* Put ourselves at the end of the list.  */
+		add_wait_queue_exclusive(&sem->write_bias_wait, &wait);
+
+		while (1) {
+			if (test_and_clear_bit(1, &sem->granted))
+				break;
+			set_task_state(tsk, (TASK_UNINTERRUPTIBLE
+					     | TASK_EXCLUSIVE));
+			if ((sem->granted & 2) == 0)
+				schedule();
+		}
+
+		remove_wait_queue(&sem->write_bias_wait, &wait);
+		tsk->state = TASK_RUNNING;
+
+		/* If the lock is currently unbiased, awaken the sleepers.
+		   FIXME: This wakes up the readers early in a bit of a
+		   stampede -> bad!  */
+		if (atomic_read(&sem->count) >= 0)
+			wake_up(&sem->wait);
+	}
+}
+
+void
+__rwsem_wake(struct rw_semaphore *sem, unsigned long readers)
+{
+	if (readers) {
+		if (test_and_set_bit(0, &sem->granted))
+			BUG();
+		wake_up(&sem->wait);
+	} else {
+		if (test_and_set_bit(1, &sem->granted))
+			BUG();
+		wake_up(&sem->write_bias_wait);
+	}
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/setup.c linux/arch/mips/kernel/setup.c
--- v2.3.47/linux/arch/mips/kernel/setup.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/kernel/setup.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.16 1999/06/17 13:25:47 ralf Exp $
+/* $Id: setup.c,v 1.22 2000/01/27 01:05:23 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 #include <asm/stackframe.h>
 #include <asm/system.h>
-#ifdef CONFIG_SGI
+#ifdef CONFIG_SGI_IP22
 #include <asm/sgialib.h>
 #endif
 
@@ -66,16 +66,7 @@
  */
 int EISA_bus = 0;
 
-/*
- * Milo passes some information to the kernel that looks like as if it
- * had been returned by a Intel PC BIOS.  Milo doesn't fill the passed
- * drive_info and Linux can find out about this anyway, so I'm going to
- * remove this sometime.  screen_info contains information about the 
- * resolution of the text screen.  For VGA graphics based machine this
- * information is being use to continue the screen output just below
- * the BIOS printed text and with the same text resolution.
- */
-struct screen_info screen_info = DEFAULT_SCREEN_INFO;
+struct screen_info screen_info;
 
 #ifdef CONFIG_BLK_DEV_FD
 extern struct fd_ops no_fd_ops;
@@ -106,13 +97,6 @@
 unsigned char aux_device_present;
 extern int _end;
 
-extern char empty_zero_page[PAGE_SIZE];
-
-/*
- * This is set up by the setup-routine at boot-time
- */
-#define PARAM	empty_zero_page
-
 static char command_line[CL_SIZE] = { 0, };
        char saved_command_line[CL_SIZE];
 extern char arcs_cmdline[CL_SIZE];
@@ -140,10 +124,8 @@
 	panic("Unknown machtype in init_IRQ");
 }
 
-void __init setup_arch(char **cmdline_p,
-           unsigned long * memory_start_p, unsigned long * memory_end_p)
+void __init setup_arch(char **cmdline_p)
 {
-	unsigned long memory_end;
 #ifdef CONFIG_BLK_DEV_INITRD
 	unsigned long tmp;
 	unsigned long *initrd_header;
@@ -155,6 +137,7 @@
 	void jazz_setup(void);
 	void sni_rm200_pci_setup(void);
 	void sgi_setup(void);
+	void ddb_setup(void);
 
 	/* Save defaults for configuration-dependent routines.  */
 	irq_setup = default_irq_setup;
@@ -192,7 +175,8 @@
 		jazz_setup();
 		break;
 #endif
-#ifdef CONFIG_SGI
+#ifdef CONFIG_SGI_IP22
+	/* As of now this is only IP22.  */
 	case MACH_GROUP_SGI:
 		sgi_setup();
 		break;
@@ -202,29 +186,23 @@
 		sni_rm200_pci_setup();
 		break;
 #endif
+#ifdef CONFIG_DDB5074
+	case MACH_GROUP_NEC_DDB:
+		ddb_setup();
+		break;
+#endif
 	default:
 		panic("Unsupported architecture");
 	}
 
-	memory_end = mips_memory_upper;
-	/*
-	 * Due to prefetching and similar mechanism the CPU sometimes
-	 * generates addresses beyond the end of memory.  We leave the size
-	 * of one cache line at the end of memory unused to make shure we
-	 * don't catch this type of bus errors.
-	 */
-	memory_end -= 128;
-	memory_end &= PAGE_MASK;
-
         strncpy (command_line, arcs_cmdline, CL_SIZE);
 	memcpy(saved_command_line, command_line, CL_SIZE);
 	saved_command_line[CL_SIZE-1] = '\0';
 
 	*cmdline_p = command_line;
-	*memory_start_p = (unsigned long) &_end;
-	*memory_end_p = memory_end;
 
 #ifdef CONFIG_BLK_DEV_INITRD
+#error "Fixme, I'm broken."
 	tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
 	if (tmp < (unsigned long)&_end)
 		tmp += PAGE_SIZE;
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/signal.c linux/arch/mips/kernel/signal.c
--- v2.3.47/linux/arch/mips/kernel/signal.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/mips/kernel/signal.c	Thu Feb 24 22:52:30 2000
@@ -1,11 +1,12 @@
-/* $Id: signal.c,v 1.19 1999/06/17 13:25:47 ralf Exp $
+/* $Id: signal.c,v 1.25 2000/02/05 06:47:08 ralf Exp $
  *
- *  linux/arch/mips/kernel/signal.c
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *  Copyright (C) 1994, 1995, 1996, 1997, 1998  Ralf Baechle
- *
- * XXX Handle lazy fp context switches correctly.
+ * Copyright (C) 1991, 1992  Linus Torvalds
+ * Copyright (C) 1994 - 1999  Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
 #include <linux/config.h>
 #include <linux/sched.h>
@@ -21,19 +22,20 @@
 
 #include <asm/asm.h>
 #include <asm/bitops.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/stackframe.h>
 #include <asm/uaccess.h>
+#include <asm/ucontext.h>
 
 #define DEBUG_SIG 0
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
+extern asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
                          int options, unsigned long *ru);
-asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
-extern asmlinkage void (*save_fp_context)(struct sigcontext *sc);
-extern asmlinkage void (*restore_fp_context)(struct sigcontext *sc);
+extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+extern asmlinkage int save_fp_context(struct sigcontext *sc);
+extern asmlinkage int restore_fp_context(struct sigcontext *sc);
 
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
@@ -52,6 +54,7 @@
 	spin_lock_irq(&current->sigmask_lock);
 	saveset = current->blocked;
 	current->blocked = newset;
+	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
 
 	regs.regs[2] = EINTR;
@@ -67,17 +70,25 @@
 asmlinkage int
 sys_rt_sigsuspend(struct pt_regs regs)
 {
-	sigset_t *uset, saveset, newset;
+	sigset_t *unewset, saveset, newset;
+        size_t sigsetsize;
 
 	save_static(&regs);
-	uset = (sigset_t *) regs.regs[4];
-	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
+
+	/* XXX Don't preclude handling different sized sigset_t's.  */
+	sigsetsize = regs.regs[5];
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	unewset = (sigset_t *) regs.regs[4];
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
 	spin_lock_irq(&current->sigmask_lock);
 	saveset = current->blocked;
 	current->blocked = newset;
+        recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
 
 	regs.regs[2] = EINTR;
@@ -91,65 +102,74 @@
 }
 
 asmlinkage int 
-sys_sigaction(int sig, const struct sigaction *act,
-	      struct sigaction *oact)
+sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
 {
 	struct k_sigaction new_ka, old_ka;
 	int ret;
+	int err = 0;
 
 	if (act) {
-		sigset_t mask;
-		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
-		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-		    __get_user(new_ka.sa.sa_flags, &act->sa_flags))
+		old_sigset_t mask;
+
+		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+			return -EFAULT;
+		err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler);
+		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		err |= __get_user(mask, &act->sa_mask.sig[0]);
+		err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer);
+		if (err)
 			return -EFAULT;
 
-		__copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t));
-		new_ka.ka_restorer = NULL;
+		siginitset(&new_ka.sa.sa_mask, mask);
 	}
 
 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 
 	if (!ret && oact) {
-		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
-		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
+		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+                        return -EFAULT;
+		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
+		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
+                err |= __put_user(0, &oact->sa_mask.sig[1]);
+                err |= __put_user(0, &oact->sa_mask.sig[2]);
+                err |= __put_user(0, &oact->sa_mask.sig[3]);
+		err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer);
+                if (err)
 			return -EFAULT;
-		__copy_to_user(&old_ka.sa.sa_mask, &oact->sa_mask,
-		               sizeof(sigset_t));
 	}
 
 	return ret;
 }
 
 asmlinkage int
-sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+sys_sigaltstack(struct pt_regs regs)
 {
-	struct pt_regs *regs = (struct pt_regs *) &uss;
+	const stack_t *uss = (const stack_t *) regs.regs[4];
+	stack_t *uoss = (stack_t *) regs.regs[5];
+	unsigned long usp = regs.regs[29];
 
-	return do_sigaltstack(uss, uoss, regs->regs[29]);
+	return do_sigaltstack(uss, uoss, usp);
 }
 
-/*
- * To do: this entire function should be accessed over a function pointer
- * such that we can handle stack frames for different ABIs.
- */
-
-asmlinkage void
-restore_sigcontext(struct pt_regs *regs, struct sigcontext *context)
+asmlinkage int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
 {
-	long long reg;
 	int owned_fp;
+	int err = 0;
+	u64 reg;
 
-	__get_user(regs->cp0_epc, &context->sc_pc);
+	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
 
-	__get_user(reg, &context->sc_mdhi);
+	err |= __get_user(reg, &sc->sc_mdhi);
 	regs->hi = (int) reg;
-	__get_user(reg, &context->sc_mdlo);
+	err |= __get_user(reg, &sc->sc_mdlo);
 	regs->lo = (int) reg;
 
-#define restore_gp_reg(i) __get_user(reg, &context->sc_regs[i]); \
-			  regs->regs[i] = (int) reg;
+#define restore_gp_reg(i) do {						\
+	err |= __get_user(reg, &sc->sc_regs[i]);			\
+	regs->regs[i] = reg;						\
+} while(0);
 	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
 	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
 	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
@@ -163,55 +183,40 @@
 	restore_gp_reg(31);
 #undef restore_gp_reg
 
-	/* FP depends on what FPU in what mode we have.  */
-	__get_user(owned_fp, &context->sc_ownedfp);
-#if 0
+	err |= __get_user(owned_fp, &sc->sc_ownedfp);
 	if (owned_fp) {
-		restore_fp_context(context);
+		err |= restore_fp_context(sc);
 		last_task_used_math = current;
 	}
-#endif
-restore_fp_context(context);
+
+	return err;
 }
 
-/*
- * The structure sc describes the stackframe on the userstack.  The frames
- * are identical for normal and realtime signal stackframes with the
- * exception of the additional struct ucontext for rt frames.
- */
 struct sigframe {
-	unsigned long	ass[4];		/* argument save space for o32 */
-	unsigned int	code[4];	/* signal trampoline */
-	struct sigcontext scc;
+	u32 sf_ass[4];			/* argument save space for o32 */
+	u32 sf_code[2];			/* signal trampoline */
+	struct sigcontext sf_sc;
+	sigset_t sf_mask;
 };
 
 struct rt_sigframe {
-	unsigned long	ass[4];
-	unsigned int	code[4];
-	struct sigcontext scc;
-	// struct ucontext uc;
+	u32 rs_ass[4];			/* argument save space for o32 */
+	u32 rs_code[2];			/* signal trampoline */
+	struct siginfo rs_info;
+	struct ucontext rs_uc;
 };
 
-asmlinkage int sys_sigreturn(struct pt_regs regs)
+asmlinkage void
+sys_sigreturn(struct pt_regs regs)
 {
-	struct sigcontext *context;
+	struct sigframe *frame;
 	sigset_t blocked;
 
-	context = (struct sigcontext *)(long) regs.regs[29];
-	if (!access_ok(VERIFY_READ, context, sizeof(struct sigcontext)) ||
-	    (regs.regs[29] & (SZREG - 1)))
-		goto badframe;
-
-#if 1
-	if (__get_user(blocked.sig[0], &context->sc_sigset[0]) ||
-	    __get_user(blocked.sig[1], &context->sc_sigset[1]) ||
-	    __get_user(blocked.sig[2], &context->sc_sigset[2]) ||
-	    __get_user(blocked.sig[3], &context->sc_sigset[3]))
+	frame = (struct sigframe *) regs.regs[29];
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
-#else
-	if (__copy_from_user(&blocked, &context->sc_sigset, sizeof(blocked)))
+	if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
 		goto badframe;
-#endif
 
 	sigdelsetmask(&blocked, ~_BLOCKABLE);
 	spin_lock_irq(&current->sigmask_lock);
@@ -219,63 +224,79 @@
 	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
 
-	restore_sigcontext(&regs, context);
+	if (restore_sigcontext(&regs, &frame->sf_sc))
+		goto badframe;
 
 	/*
 	 * Don't let your children do this ...
 	 */
 	__asm__ __volatile__(
-		"move\t$29,%0\n\t"
+		"move\t$29, %0\n\t"
 		"j\tret_from_sys_call"
 		:/* no outputs */
 		:"r" (&regs));
 	/* Unreached */
 
 badframe:
-	lock_kernel();
-	do_exit(SIGSEGV);
-	unlock_kernel();
+	force_sig(SIGSEGV, current);
 }
 
-/* same as sys_sigreturn for now */
-asmlinkage int sys_rt_sigreturn(struct pt_regs regs)
+asmlinkage void
+sys_rt_sigreturn(struct pt_regs regs)
 {
-	return -ENOSYS;
-}
+	struct rt_sigframe *frame;
+	sigset_t set;
+	stack_t st;
 
-#define scc_offset ((size_t)&((struct sigframe *)0)->scc)
+	frame = (struct rt_sigframe *) regs.regs[29];
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+		goto badframe;
 
-/*
- * Set up the return code ...
- *
- *         .set    noreorder
- *         addiu   sp,0x20
- *         li      v0,__NR_sigreturn
- *         syscall
- *         .set    reorder
- */
-static void inline
-setup_trampoline(unsigned int *code)
-{
-	__put_user(0x27bd0000 + scc_offset    , code + 0);
-	__put_user(0x24020000 + __NR_sigreturn, code + 1);
-	__put_user(0x0000000c                 , code + 2);
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
+		goto badframe;
+
+	if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
+		goto badframe;
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, regs.regs[29]);
 
 	/*
-	 * Flush caches so that the instructions will be correctly executed.
+	 * Don't let your children do this ...
 	 */
-	flush_cache_sigtramp((unsigned long) code);
+	__asm__ __volatile__(
+		"move\t$29, %0\n\t"
+		"j\tret_from_sys_call"
+		:/* no outputs */
+		:"r" (&regs));
+	/* Unreached */
+
+badframe:
+	force_sig(SIGSEGV, current);
 }
 
-static void inline
-setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc, sigset_t *set)
+static int inline
+setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
 {
 	int owned_fp;
+	int err = 0;
+	u64 reg;
 
-	__put_user(regs->cp0_epc, &sc->sc_pc);
-	__put_user(regs->cp0_status, &sc->sc_status);	/* Status register */
+	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __put_user(regs->cp0_status, &sc->sc_status);
 
-#define save_gp_reg(i) __put_user(regs->regs[(i)], &sc->sc_regs[(i)])
+#define save_gp_reg(i) {						\
+	reg = regs->regs[i];						\
+	err |= __put_user(reg, &sc->sc_regs[i]);			\
+} while(0)
 	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
 	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
 	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
@@ -287,57 +308,93 @@
 	save_gp_reg(31);
 #undef save_gp_reg
 
-	__put_user(regs->hi, &sc->sc_mdhi);
-	__put_user(regs->lo, &sc->sc_mdlo);
-	__put_user(regs->cp0_cause, &sc->sc_cause);
+	err |= __put_user(regs->hi, &sc->sc_mdhi);
+	err |= __put_user(regs->lo, &sc->sc_mdlo);
+	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
+	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
 
 	owned_fp = (current == last_task_used_math);
-	__put_user(owned_fp, &sc->sc_ownedfp);
+	err |= __put_user(owned_fp, &sc->sc_ownedfp);
 
-#if 0
 	if (current->used_math) {	/* fp is active.  */
 		set_cp0_status(ST0_CU1, ST0_CU1);
-		save_fp_context(sc);		/* CPU-dependent */
+		err |= save_fp_context(sc);
 		last_task_used_math = NULL;
 		regs->cp0_status &= ~ST0_CU1;
 		current->used_math = 0;
 	}
-#endif
-set_cp0_status(ST0_CU1, ST0_CU1);
-save_fp_context(sc);		/* CPU-dependent */
 
-	__put_user(set->sig[0], &sc->sc_sigset[0]);
-	__put_user(set->sig[1], &sc->sc_sigset[1]);
-	__put_user(set->sig[2], &sc->sc_sigset[2]);
-	__put_user(set->sig[3], &sc->sc_sigset[3]);
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long sp;
+
+	/* Default to using normal stack */
+	sp = regs->regs[29];
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
+                sp = current->sas_ss_sp + current->sas_ss_size;
+
+	return (void *)((sp - frame_size) & ALMASK);
 }
 
 static void inline
 setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
-            int signr, sigset_t *oldmask)
+            int signr, sigset_t *set)
 {
 	struct sigframe *frame;
-	struct sigcontext *sc;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub already
+	   in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER)
+		regs->regs[31] = (unsigned long) ka->sa.sa_restorer;
+	else {
+		/*
+		 * Set up the return code ...
+		 *
+		 *         li      v0, __NR_sigreturn
+		 *         syscall
+		 */
+		err |= __put_user(0x24020000 + __NR_sigreturn,
+		                  frame->sf_code + 0);
+		err |= __put_user(0x0000000c                 ,
+		                  frame->sf_code + 1);
+		flush_cache_sigtramp((unsigned long) frame->sf_code);
+	}
 
-	/* Align the stackframe to an adequate boundary for the architecture. */
-	frame = (struct sigframe *) (long) regs->regs[29];
-	frame--;
-	frame = (struct sigframe *)((unsigned long)frame & ALMASK);
-
-	if (verify_area(VERIFY_WRITE, frame, sizeof (*frame)))
-		goto segv_and_exit;
-	sc = &frame->scc;
-
-	setup_trampoline(frame->code);
-	setup_sigcontext(regs, &frame->scc, oldmask);
-
-	regs->regs[4] = signr;				/* arguments */
-        regs->regs[5] = 0;                              /* should be cause  */
-        regs->regs[6] = (long) frame;                   /* ptr to sigcontext */
-        regs->regs[29] = (unsigned long) frame;         /* Stack pointer */
-        regs->regs[31] = (unsigned long) frame->code;   /* Return address */
-        regs->cp0_epc = (unsigned long) ka->sa.sa_handler; /* handler address */
-        regs->regs[25] = regs->cp0_epc;                 /* PIC shit... */
+	err |= setup_sigcontext(regs, &frame->sf_sc);
+	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Arguments to signal handler:
+	 *
+	 *   a0 = signal number
+	 *   a1 = 0 (should be cause)
+	 *   a2 = pointer to struct sigcontext
+	 *
+	 * $25 and c0_epc point to the signal handler, $29 points to the
+	 * struct sigframe.
+	 */
+	regs->regs[ 4] = signr;
+	regs->regs[ 5] = 0;
+	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
+	regs->regs[29] = (unsigned long) frame;
+	regs->regs[31] = (unsigned long) frame->sf_code;
+	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 #if DEBUG_SIG
 	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
@@ -345,22 +402,90 @@
 #endif
         return;
 
-segv_and_exit:
-	lock_kernel();
-	do_exit(SIGSEGV);
-	unlock_kernel();
+give_sigsegv:
+	if (signr == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
 }
 
 static void inline
 setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
-               int signr, sigset_t *oldmask, siginfo_t *info)
+               int signr, sigset_t *set, siginfo_t *info)
 {
-	printk("Aiee: setup_tr_frame wants to be written");
-}
+	struct rt_sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub already
+	   in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER)
+		regs->regs[31] = (unsigned long) ka->sa.sa_restorer;
+	else {
+		/*
+		 * Set up the return code ...
+		 *
+		 *         li      v0, __NR_sigreturn
+		 *         syscall
+		 */
+		err |= __put_user(0x24020000 + __NR_sigreturn,
+		                  frame->rs_code + 0);
+		err |= __put_user(0x0000000c                 ,
+		                  frame->rs_code + 1);
+		flush_cache_sigtramp((unsigned long) frame->rs_code);
+	}
 
-/* ------------------------------------------------------------------------- */
+	/* Create siginfo.  */
+	err |= __copy_to_user(&frame->rs_info, info, sizeof(*info));
 
-static inline void handle_signal(unsigned long sig, struct k_sigaction *ka,
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->rs_uc.uc_flags);
+	err |= __put_user(0, &frame->rs_uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+	                  &frame->rs_uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->regs[29]),
+	                  &frame->rs_uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size,
+	                  &frame->rs_uc.uc_stack.ss_size);
+	err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
+	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Arguments to signal handler:
+	 *
+	 *   a0 = signal number
+	 *   a1 = 0 (should be cause)
+	 *   a2 = pointer to ucontext
+	 *
+	 * $25 and c0_epc point to the signal handler, $29 points to
+	 * the struct rt_sigframe.
+	 */
+	regs->regs[ 4] = signr;
+	regs->regs[ 5] = (unsigned long) &frame->rs_info;
+	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
+	regs->regs[29] = (unsigned long) frame;
+	regs->regs[31] = (unsigned long) frame->rs_code;
+	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
+	       current->comm, current->pid, frame, regs->cp0_epc, frame->code);
+#endif
+	return;
+
+give_sigsegv:
+	if (signr == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static inline void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
 	siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
 {
 	if (ka->sa.sa_flags & SA_SIGINFO)
@@ -379,7 +504,8 @@
 	}
 }
 
-static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
+static inline void
+syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
 {
 	switch(regs->regs[0]) {
 	case ERESTARTNOHAND:
@@ -407,7 +533,7 @@
 	siginfo_t info;
 
 #ifdef CONFIG_BINFMT_IRIX
-	if (current->personality != PER_LINUX)           /* XXX */
+	if (current->personality != PER_LINUX)
 		return do_irix_signal(oldset, regs);
 #endif
 
@@ -528,14 +654,4 @@
 		}
 	}
 	return 0;
-}
-
-/*
- * Compatibility syscall.  Can be replaced in libc.
- */
-asmlinkage int sys_pause(void)
-{
-	current->state = TASK_INTERRUPTIBLE;
-	schedule();
-	return -ERESTARTNOHAND;
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/syscall.c linux/arch/mips/kernel/syscall.c
--- v2.3.47/linux/arch/mips/kernel/syscall.c	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/syscall.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: syscall.c,v 1.10 1999/02/15 02:16:52 ralf Exp $
+/* $Id: syscall.c,v 1.13 2000/02/04 07:40:23 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -55,64 +55,46 @@
 	return res;
 }
 
-asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, int prot,
-                                  int flags, int fd, off_t offset)
+/* common code for old and new mmaps */
+static inline long
+do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+        unsigned long flags, unsigned long fd, unsigned long pgoff)
 {
+	int error = -EBADF;
 	struct file * file = NULL;
-	unsigned long error = -EFAULT;
 
-	down(&current->mm->mmap_sem);
-	lock_kernel();
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 	if (!(flags & MAP_ANONYMOUS)) {
-		error = -EBADF;
 		file = fget(fd);
 		if (!file)
 			goto out;
 	}
-        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-        error = do_mmap(file, addr, len, prot, flags, offset);
-        if (file)
-                fput(file);
-out:
+
+	down(&current->mm->mmap_sem);
+	lock_kernel();
+
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+
 	unlock_kernel();
 	up(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
 	return error;
 }
 
-asmlinkage int sys_idle(void)
+asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot,
+                                  int flags, int fd, off_t offset)
 {
-	unsigned long start_idle = 0;
-
-	if (current->pid != 0)
-		return -EPERM;
-
-	/* endless idle loop with no priority at all */
-	current->priority = 0;
-	current->counter = 0;
-	for (;;) {
-		/*
-		 * R4[36]00 have wait, R4[04]00 don't.
-		 * FIXME: We should save power by reducing the clock where
-		 *        possible.  Thiss will cut down the power consuption
-		 *        of R4200 systems to about 1/16th of normal, the
-		 *        same for logic clocked with the processor generated
-		 *        clocks.
-		 */
-		if (!start_idle) {
-			check_pgt_cache();
-			start_idle = jiffies;
-		}
-		if (wait_available && !current->need_resched)
-			__asm__(".set\tmips3\n\t"
-				"wait\n\t"
-				".set\tmips0");
-		run_task_queue(&tq_scheduler);
-		if (current->need_resched)
-			start_idle = 0;
-		schedule();
-	}
+	return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+}
 
-	return 0;
+asmlinkage long
+sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+          unsigned long flags, unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
 }
 
 asmlinkage int sys_fork(struct pt_regs regs)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/syscalls.h linux/arch/mips/kernel/syscalls.h
--- v2.3.47/linux/arch/mips/kernel/syscalls.h	Wed Jul 28 10:30:10 1999
+++ linux/arch/mips/kernel/syscalls.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: syscalls.h,v 1.15 1998/09/19 19:16:17 ralf Exp $
+/* $Id: syscalls.h,v 1.22 2000/02/18 00:24:30 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -44,7 +44,7 @@
 SYS(sys_ptrace, 4)
 SYS(sys_alarm, 1)
 SYS(sys_fstat, 2)
-SYS(sys_pause, 0)
+SYS(sys_ni_syscall, 0)
 SYS(sys_utime, 2)				/* 4030 */
 SYS(sys_ni_syscall, 0)
 SYS(sys_ni_syscall, 0)
@@ -105,7 +105,7 @@
 SYS(sys_swapon, 2)
 SYS(sys_reboot, 3)
 SYS(old_readdir, 3)
-SYS(sys_mmap, 6)				/* 4090 */
+SYS(old_mmap, 6)				/* 4090 */
 SYS(sys_munmap, 2)
 SYS(sys_truncate, 2)
 SYS(sys_ftruncate, 2)
@@ -127,7 +127,7 @@
 SYS(sys_uname, 1)
 SYS(sys_iopl, 0)	/* Well, actually 17 args ... */				/* 4110 */
 SYS(sys_vhangup, 0)
-SYS(sys_idle, 0)
+SYS(sys_ni_syscall, 0)	/* was sys_idle() */
 SYS(sys_vm86, 1)
 SYS(sys_wait4, 4)
 SYS(sys_swapoff, 1)				/* 4115 */
@@ -214,14 +214,21 @@
 SYS(sys_rt_sigpending, 2)
 SYS(sys_rt_sigtimedwait, 4)
 SYS(sys_rt_sigqueueinfo, 3)
-SYS(sys_rt_sigsuspend, 2)
-SYS(sys_pread, 4)				/* 4200 */
-SYS(sys_pwrite, 4)
+SYS(sys_rt_sigsuspend, 0)
+SYS(sys_pread, 6)				/* 4200 */
+SYS(sys_pwrite, 6)
 SYS(sys_chown, 3)
 SYS(sys_getcwd, 2)
 SYS(sys_capget, 2)
 SYS(sys_capset, 2)				/* 4205 */
-SYS(sys_sigaltstack, 2)
+SYS(sys_sigaltstack, 0)
 SYS(sys_sendfile, 3)
 SYS(sys_ni_syscall, 0)
 SYS(sys_ni_syscall, 0)
+SYS(sys_mmap2, 6)				/* 4210 */
+SYS(sys_truncate64, 2)
+SYS(sys_ftruncate64, 2)
+SYS(sys_stat64, 3)
+SYS(sys_lstat64, 3)
+SYS(sys_fstat64, 3)				/* 4215 */
+SYS(sys_pivot_root, 2)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/sysirix.c linux/arch/mips/kernel/sysirix.c
--- v2.3.47/linux/arch/mips/kernel/sysirix.c	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/sysirix.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: sysirix.c,v 1.20 1999/06/17 13:25:48 ralf Exp $
+/* $Id: sysirix.c,v 1.24 2000/02/05 06:47:08 ralf Exp $
  *
  * sysirix.c: IRIX system call emulation.
  *
@@ -27,13 +27,15 @@
 
 #include <asm/ptrace.h>
 #include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/uaccess.h>
 #include <asm/sgialib.h>
 #include <asm/inventory.h>
 
 /* 2,526 lines of complete and utter shit coming up... */
 
+extern int max_threads;
+
 /* The sysmp commands supported thus far. */
 #define MP_NPROCS       	1 /* # processor in complex */
 #define MP_NAPROCS      	2 /* # active processors in complex */
@@ -45,7 +47,6 @@
 	int base = 0;
 	int error = 0;
 
-	lock_kernel();
 	if(regs->regs[2] == 1000)
 		base = 1;
 	cmd = regs->regs[base + 4];
@@ -55,8 +56,7 @@
 		break;
 	case MP_NPROCS:
 	case MP_NAPROCS:
-		error = 1;
-		error = NR_CPUS;
+		error = smp_num_cpus;
 		break;
 	default:
 		printk("SYSMP[%s:%ld]: Unsupported opcode %d\n",
@@ -65,7 +65,6 @@
 		break;
 	}
 
-	unlock_kernel();
 	return error;
 }
 
@@ -100,7 +99,7 @@
 	case PR_MAXPROCS:
 		printk("irix_prctl[%s:%ld]: Wants PR_MAXPROCS\n",
 		       current->comm, current->pid);
-		error = NR_TASKS;
+		error = max_threads;
 		break;
 
 	case PR_ISBLOCKED: {
@@ -113,7 +112,7 @@
 			error = -ESRCH;
 			break;
 		}
-		error = (task->next_run ? 0 : 1);
+		error = (task->run_list.next != NULL);
 		/* Can _your_ OS find this out that fast? */ 
 		break;
 	}
@@ -359,7 +358,7 @@
 			retval = (MAX_ARG_PAGES >> 4); /* XXX estimate... */
 			goto out;
 		case 2:
-			retval = NR_TASKS;
+			retval = max_threads;
 			goto out;
 		case 3:
 			retval = HZ;
@@ -1104,26 +1103,27 @@
 	struct file *file = NULL;
 	unsigned long retval;
 
-	down(&current->mm->mmap_sem);
 	lock_kernel();
-	if(!(flags & MAP_ANONYMOUS)) {
-		if(!(file = fget(fd))) {
+	if (!(flags & MAP_ANONYMOUS)) {
+		if (!(file = fget(fd))) {
 			retval = -EBADF;
 			goto out;
 		}
-		/* Ok, bad taste hack follows, try to think in something else when reading this */
-		if (flags & IRIX_MAP_AUTOGROW){
+
+		/* Ok, bad taste hack follows, try to think in something else
+		 * when reading this.  */
+		if (flags & IRIX_MAP_AUTOGROW) {
 			unsigned long old_pos;
 			long max_size = offset + len;
 			
-			if (max_size > file->f_dentry->d_inode->i_size){
+			if (max_size > file->f_dentry->d_inode->i_size) {
 				old_pos = sys_lseek (fd, max_size - 1, 0);
 				sys_write (fd, "", 1);
 				sys_lseek (fd, old_pos, 0);
 			}
 		}
 	}
-	
+
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
 	retval = do_mmap(file, addr, len, prot, flags, offset);
@@ -1132,7 +1132,7 @@
 
 out:
 	unlock_kernel();
-	up(&current->mm->mmap_sem);
+
 	return retval;
 }
 
@@ -1684,23 +1684,24 @@
 	return retval;
 }
 
-extern asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, int prot,
-					 int flags, int fd, off_t offset);
+extern asmlinkage unsigned long
+sys_mmap(unsigned long addr, size_t len, int prot, int flags, int fd,
+         off_t offset);
 
 asmlinkage int irix_mmap64(struct pt_regs *regs)
 {
 	int len, prot, flags, fd, off1, off2, error, base = 0;
-	unsigned long addr, *sp;
-	struct file *file;
-	
+	unsigned long addr, pgoff, *sp;
+	struct file *file = NULL;
+
 	lock_kernel();
-	if(regs->regs[2] == 1000)
+	if (regs->regs[2] == 1000)
 		base = 1;
 	sp = (unsigned long *) (regs->regs[29] + 16);
 	addr = regs->regs[base + 4];
 	len = regs->regs[base + 5];
 	prot = regs->regs[base + 6];
-	if(!base) {
+	if (!base) {
 		flags = regs->regs[base + 7];
 		error = verify_area(VERIFY_READ, sp, (4 * sizeof(unsigned long)));
 		if(error)
@@ -1717,63 +1718,72 @@
 		__get_user(off1, &sp[2]);
 		__get_user(off2, &sp[3]);
 	}
-	if(off1) {
-		error = -EINVAL;
+
+	if (off1 & PAGE_MASK) {
+		error = -EOVERFLOW;
 		goto out;
 	}
 
-	if(!(flags & MAP_ANONYMOUS)) {
-		if(!(file = fcheck(fd))) {
+	pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT);
+
+	if (!(flags & MAP_ANONYMOUS)) {
+		if (!(file = fcheck(fd))) {
 			error = -EBADF;
 			goto out;
 		}
-		
-		/* Ok, bad taste hack follows, try to think in something else when reading this */
-		if (flags & IRIX_MAP_AUTOGROW){
+
+		/* Ok, bad taste hack follows, try to think in something else
+		   when reading this */
+		if (flags & IRIX_MAP_AUTOGROW) {
 			unsigned long old_pos;
 			long max_size = off2 + len;
-			
-			if (max_size > file->f_dentry->d_inode->i_size){
+
+			if (max_size > file->f_dentry->d_inode->i_size) {
 				old_pos = sys_lseek (fd, max_size - 1, 0);
 				sys_write (fd, "", 1);
 				sys_lseek (fd, old_pos, 0);
 			}
 		}
 	}
-	
-	error = sys_mmap(addr, (size_t) len, prot, flags, fd, off2);
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	down(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
 
 out:
 	unlock_kernel();
+
 	return error;
 }
 
 asmlinkage int irix_dmi(struct pt_regs *regs)
 {
-	lock_kernel();
 	printk("[%s:%ld] Wheee.. irix_dmi()\n",
 	       current->comm, current->pid);
-	unlock_kernel();
+
 	return -EINVAL;
 }
 
 asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
 			  int off1, int off2)
 {
-	lock_kernel();
 	printk("[%s:%ld] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n",
 	       current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
-	unlock_kernel();
+
 	return -EINVAL;
 }
 
 asmlinkage int irix_pwrite(int fd, char *buf, int cnt, int off64,
 			   int off1, int off2)
 {
-	lock_kernel();
 	printk("[%s:%ld] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n",
 	       current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
-	unlock_kernel();
+
 	return -EINVAL;
 }
 
@@ -1781,12 +1791,11 @@
 				unsigned long arg2, unsigned long arg3,
 				unsigned long arg4, unsigned long arg5)
 {
-	lock_kernel();
 	printk("[%s:%ld] Wheee.. irix_fastpath(%d,%08lx,%08lx,%08lx,%08lx,"
 	       "%08lx,%08lx)\n",
 	       current->comm, current->pid, cmd, arg0, arg1, arg2,
 	       arg3, arg4, arg5);
-	unlock_kernel();
+
 	return -EINVAL;
 }
 
@@ -2414,12 +2423,10 @@
 
 asmlinkage int irix_unimp(struct pt_regs *regs)
 {
-	lock_kernel();
 	printk("irix_unimp [%s:%ld] v0=%d v1=%d a0=%08lx a1=%08lx a2=%08lx "
 	       "a3=%08lx\n", current->comm, current->pid,
 	       (int) regs->regs[2], (int) regs->regs[3],
 	       regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
-	unlock_kernel();
 
 	return -ENOSYS;
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/sysmips.c linux/arch/mips/kernel/sysmips.c
--- v2.3.47/linux/arch/mips/kernel/sysmips.c	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/sysmips.c	Thu Feb 24 22:52:30 2000
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
  *
- * $Id: sysmips.c,v 1.6 1998/08/25 09:14:42 ralf Exp $
+ * $Id: sysmips.c,v 1.9 2000/02/18 00:24:30 ralf Exp $
  */
 #include <linux/errno.h>
 #include <linux/linkage.h>
@@ -19,7 +19,7 @@
 #include <linux/utsname.h>
 
 #include <asm/cachectl.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/sysmips.h>
 #include <asm/uaccess.h>
 
@@ -72,6 +72,7 @@
 		if (len == 0 || len > __NEW_UTS_LEN)
 			goto out;
 
+		/* Fiiiixmeeee...  */
 		copy_from_user(system_utsname.nodename, name, len);
 		system_utsname.nodename[len] = '\0';
 		retval = 0;
@@ -91,8 +92,8 @@
 		goto out;
 
 	case MIPS_FIXADE:
-		tmp = current->tss.mflags & ~3;
-		current->tss.mflags = tmp | (arg1 & 3);
+		tmp = current->thread.mflags & ~3;
+		current->thread.mflags = tmp | (arg1 & 3);
 		retval = 0;
 		goto out;
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/time.c linux/arch/mips/kernel/time.c
--- v2.3.47/linux/arch/mips/kernel/time.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/kernel/time.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.12 1999/06/13 16:30:34 ralf Exp $
+/* $Id: time.c,v 1.14 2000/01/26 00:07:44 ralf Exp $
  *
  *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
  *  Copyright (C) 1996, 1997, 1998  Ralf Baechle
@@ -6,7 +6,6 @@
  * This file contains the time handling details for PC-style clocks as
  * found in some MIPS systems.
  */
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/sched.h>
@@ -20,6 +19,7 @@
 #include <asm/mipsregs.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/ddb5074.h>
 
 #include <linux/mc146818rtc.h>
 #include <linux/timex.h>
@@ -336,6 +336,24 @@
 static void inline
 timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
+#ifdef CONFIG_DDB5074
+	static unsigned cnt = 0, period = 0, dist = 0;
+
+	if (cnt == 0 || cnt == dist)
+	    ddb5074_led_d2(1);
+	else if (cnt == 7 || cnt == dist+7)
+	    ddb5074_led_d2(0);
+	
+	if (++cnt > period) {
+	    cnt = 0;
+	    /* The hyperbolic function below modifies the heartbeat period
+	     * length in dependency of the current (5min) load. It goes
+	     * through the points f(0)=126, f(1)=86, f(5)=51,
+	     * f(inf)->30. */
+	     period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+	     dist = period / 4;
+	}
+#endif
 #ifdef CONFIG_PROFILE
 	if(!user_mode(regs)) {
 		if (prof_buffer && current->pid) {
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/traps.c linux/arch/mips/kernel/traps.c
--- v2.3.47/linux/arch/mips/kernel/traps.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/kernel/traps.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.20 1999/06/13 16:30:34 ralf Exp $
+/* $Id: traps.c,v 1.27 2000/01/16 01:29:05 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/spinlock.h>
 
 #include <asm/branch.h>
 #include <asm/cachectl.h>
@@ -24,11 +25,19 @@
 #include <asm/watch.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/mmu_context.h>
+
+extern int console_loglevel;
+
+static inline void console_silent(void)
+{
+	console_loglevel = 0;
+}
 
 static inline void console_verbose(void)
 {
-	extern int console_loglevel;
-	console_loglevel = 15;
+	if (console_loglevel)
+		console_loglevel = 15;
 }
 
 /*
@@ -40,12 +49,9 @@
 extern asmlinkage void deskstation_tyne_handle_int(void);
 extern asmlinkage void mips_magnum_4000_handle_int(void);
 
-extern asmlinkage void r4k_handle_mod(void);
-extern asmlinkage void r2300_handle_mod(void);
-extern asmlinkage void r4k_handle_tlbl(void);
-extern asmlinkage void r2300_handle_tlbl(void);
-extern asmlinkage void r4k_handle_tlbs(void);
-extern asmlinkage void r2300_handle_tlbs(void);
+extern asmlinkage void handle_mod(void);
+extern asmlinkage void handle_tlbl(void);
+extern asmlinkage void handle_tlbs(void);
 extern asmlinkage void handle_adel(void);
 extern asmlinkage void handle_ades(void);
 extern asmlinkage void handle_ibe(void);
@@ -77,6 +83,23 @@
  */
 #define MODULE_RANGE (8*1024*1024)
 
+#if !defined(CONFIG_CPU_HAS_LLSC)
+/*
+ * This stuff is needed for the userland ll-sc emulation for R2300
+ */
+void simulate_ll(struct pt_regs *regs, unsigned int opcode);
+void simulate_sc(struct pt_regs *regs, unsigned int opcode);
+
+#define OPCODE 0xfc000000
+#define BASE   0x03e00000
+#define RT     0x001f0000
+#define OFFSET 0x0000ffff
+#define LL     0xc0000000
+#define SC     0xd0000000
+
+#define DEBUG_LLSC
+#endif
+
 /*
  * This routine abuses get_user()/put_user() to reference pointers
  * with at least a bit of error checking ...
@@ -173,13 +196,17 @@
 	}
 }
 
-void die(const char * str, struct pt_regs * regs, unsigned long err)
-{
-	if (user_mode(regs))	/* Just return if in user mode.  */
-		return;
+spinlock_t die_lock;
 
+extern void __die(const char * str, struct pt_regs * regs, const char *where,
+                  unsigned long line)
+{
 	console_verbose();
-	printk("%s: %04lx\n", str, err & 0xffff);
+	spin_lock_irq(&die_lock);
+	printk("%s", str);
+	if (where)
+		printk(" in %s, line %ld", where, line);
+	printk(":\n");
 	show_regs(regs);
 	printk("Process %s (pid: %ld, stackpage=%08lx)\n",
 		current->comm, current->pid, (unsigned long) current);
@@ -187,13 +214,16 @@
 	show_trace((unsigned int *) regs->regs[29]);
 	show_code((unsigned int *) regs->cp0_epc);
 	printk("\n");
+while(1);
+	spin_unlock_irq(&die_lock);
 	do_exit(SIGSEGV);
 }
 
-void die_if_kernel(const char * str, struct pt_regs * regs, unsigned long err)
+void __die_if_kernel(const char * str, struct pt_regs * regs, const char *where,
+	unsigned long line)
 {
 	if (!user_mode(regs))
-		die(str, regs, err);
+		__die(str, regs, where, line);
 }
 
 static void default_be_board_handler(struct pt_regs *regs)
@@ -201,8 +231,10 @@
 	/*
 	 * Assume it would be too dangerous to continue ...
 	 */
-	force_sig(SIGBUS, current);
+/* XXX */
+printk("Got Bus Error at %08x\n", (unsigned int)regs->cp0_epc);
 show_regs(regs); while(1);
+	force_sig(SIGBUS, current);
 }
 
 void do_ibe(struct pt_regs *regs)
@@ -249,6 +281,7 @@
 {
 	unsigned long pc;
 	unsigned int insn;
+	extern void simfp(void*);
 
 #ifdef CONFIG_MIPS_FPE_MODULE
 	if (fpe_handler != NULL) {
@@ -307,7 +340,6 @@
 	return 0;
 }
 
-
 void do_bp(struct pt_regs *regs)
 {
 	unsigned int opcode, bcode;
@@ -340,11 +372,115 @@
 	/*
 	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
 	 * insns, even for break codes that indicate arithmetic failures.
-	 * Wiered ...)
+	 * Weird ...)
 	 */
 	force_sig(SIGTRAP, current);
 }
 
+#if !defined(CONFIG_CPU_HAS_LLSC)
+
+/*
+ * userland emulation for R2300 CPUs
+ * needed for the multithreading part of glibc
+ */
+void do_ri(struct pt_regs *regs)
+{
+	unsigned int opcode;
+
+	lock_kernel();
+	if (!get_insn_opcode(regs, &opcode)) {
+		if ((opcode & OPCODE) == LL)
+			simulate_ll(regs, opcode);
+		if ((opcode & OPCODE) == SC)
+			simulate_sc(regs, opcode);
+	} else {
+	printk("[%s:%ld] Illegal instruction at %08lx ra=%08lx\n",
+	       current->comm, current->pid, regs->cp0_epc, regs->regs[31]);
+	}
+	unlock_kernel();
+	if (compute_return_epc(regs))
+		return;
+	force_sig(SIGILL, current);
+}
+
+/*
+ * the ll_bit will be cleared by r2300_switch.S
+ */
+unsigned long ll_bit, *lladdr;
+ 
+void simulate_ll(struct pt_regs *regp, unsigned int opcode)
+{
+	unsigned long *addr, *vaddr;
+	long offset;
+ 
+	/*
+	 * analyse the ll instruction that just caused a ri exception
+	 * and put the referenced address to addr.
+	 */
+	/* sign extend offset */
+	offset = opcode & OFFSET;
+	if (offset & 0x00008000)
+		offset = -(offset & 0x00007fff);
+	else
+		offset = (offset & 0x00007fff);
+
+	vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset);
+
+#ifdef DEBUG_LLSC
+	printk("ll: vaddr = 0x%08x, reg = %d\n", (unsigned int)vaddr, (opcode & RT) >> 16);
+#endif
+
+	/*
+	 * TODO: compute physical address from vaddr
+	 */
+	panic("ll: emulation not yet finished!");
+
+	lladdr = addr;
+	ll_bit = 1;
+	regp->regs[(opcode & RT) >> 16] = *addr;
+}
+ 
+void simulate_sc(struct pt_regs *regp, unsigned int opcode)
+{
+	unsigned long *addr, *vaddr, reg;
+	long offset;
+
+	/*
+	 * analyse the sc instruction that just caused a ri exception
+	 * and put the referenced address to addr.
+	 */
+	/* sign extend offset */
+	offset = opcode & OFFSET;
+	if (offset & 0x00008000)
+		offset = -(offset & 0x00007fff);
+	else
+		offset = (offset & 0x00007fff);
+
+	vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset);
+	reg = (opcode & RT) >> 16;
+
+#ifdef DEBUG_LLSC
+	printk("sc: vaddr = 0x%08x, reg = %d\n", (unsigned int)vaddr, (unsigned int)reg);
+#endif
+
+	/*
+	 * TODO: compute physical address from vaddr
+	 */
+	panic("sc: emulation not yet finished!");
+
+	lladdr = addr;
+
+	if (ll_bit == 0) {
+		regp->regs[reg] = 0;
+		return;
+	}
+
+	*addr = regp->regs[reg];
+	regp->regs[reg] = 1;
+}
+
+#else /* MIPS 2 or higher */
+
 void do_ri(struct pt_regs *regs)
 {
 	lock_kernel();
@@ -356,9 +492,13 @@
 	force_sig(SIGILL, current);
 }
 
+#endif
+
 void do_cpu(struct pt_regs *regs)
 {
 	unsigned int cpid;
+	extern void lazy_fpu_switch(void*);
+	extern void init_fpu(void);
 
 	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
 	if (cpid != 1)
@@ -369,10 +509,10 @@
 		return;
 
 	if (current->used_math) {		/* Using the FPU again.  */
-		r4xx0_lazy_fpu_switch(last_task_used_math);
+		lazy_fpu_switch(last_task_used_math);
 	} else {				/* First time FPU user.  */
 
-		r4xx0_init_fpu();
+		init_fpu();
 		current->used_math = 1;
 	}
 	last_task_used_math = current;
@@ -454,19 +594,6 @@
 	}
 }
 
-asmlinkage void (*save_fp_context)(struct sigcontext *sc);
-extern asmlinkage void r4k_save_fp_context(struct sigcontext *sc);
-extern asmlinkage void r2300_save_fp_context(struct sigcontext *sc);
-extern asmlinkage void r6000_save_fp_context(struct sigcontext *sc);
-
-asmlinkage void (*restore_fp_context)(struct sigcontext *sc);
-extern asmlinkage void r4k_restore_fp_context(struct sigcontext *sc);
-extern asmlinkage void r2300_restore_fp_context(struct sigcontext *sc);
-extern asmlinkage void r6000_restore_fp_context(struct sigcontext *sc);
-
-extern asmlinkage void *r4xx0_resume(void *last, void *next);
-extern asmlinkage void *r2300_resume(void *last, void *next);
-
 void __init trap_init(void)
 {
 	extern char except_vec0_nevada, except_vec0_r4000;
@@ -479,6 +606,9 @@
 	   mips_machtype == MACH_SNI_RM200_PCI)
 		EISA_bus = 1;
 
+	/* Some firmware leaves the BEV flag set, clear it.  */
+	set_cp0_status(ST0_BEV, 0);
+
 	/* Copy the generic exception handler code to it's final destination. */
 	memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80);
 	memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
@@ -497,6 +627,29 @@
 	watch_init(mips_cputype);
 	setup_dedicated_int();
 
+	set_except_vector(1, handle_mod);
+	set_except_vector(2, handle_tlbl);
+	set_except_vector(3, handle_tlbs);
+	set_except_vector(4, handle_adel);
+	set_except_vector(5, handle_ades);
+	/*
+	 * The Data Bus Error/ Instruction Bus Errors are signaled
+	 * by external hardware.  Therefore these two expection have
+	 * board specific handlers.
+	 */
+	set_except_vector(6, handle_ibe);
+	set_except_vector(7, handle_dbe);
+	ibe_board_handler = default_be_board_handler;
+	dbe_board_handler = default_be_board_handler;
+
+	set_except_vector(8, handle_sys);
+	set_except_vector(9, handle_bp);
+	set_except_vector(10, handle_ri);
+	set_except_vector(11, handle_cpu);
+	set_except_vector(12, handle_ov);
+	set_except_vector(13, handle_tr);
+	set_except_vector(15, handle_fpe);
+
 	/*
 	 * Handling the following exceptions depends mostly of the cpu type
 	 */
@@ -540,42 +693,16 @@
 
 		if (vce_available) {
 			memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000,
-			       0x180);
+			       0x80);
 		} else {
 			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
-			       0x100);
+			       0x80);
 		}
 
-		save_fp_context = r4k_save_fp_context;
-		restore_fp_context = r4k_restore_fp_context;
-		resume = r4xx0_resume;
-		set_except_vector(1, r4k_handle_mod);
-		set_except_vector(2, r4k_handle_tlbl);
-		set_except_vector(3, r4k_handle_tlbs);
-		set_except_vector(4, handle_adel);
-		set_except_vector(5, handle_ades);
-
-		/*
-		 * The following two are signaled by onboard hardware and
-		 * should get board specific handlers to get maximum
-		 * available information.
-		 */
-		set_except_vector(6, handle_ibe);
-		set_except_vector(7, handle_dbe);
-
-		set_except_vector(8, handle_sys);
-		set_except_vector(9, handle_bp);
-		set_except_vector(10, handle_ri);
-		set_except_vector(11, handle_cpu);
-		set_except_vector(12, handle_ov);
-		set_except_vector(13, handle_tr);
-		set_except_vector(15, handle_fpe);
 		break;
 
 	case CPU_R6000:
 	case CPU_R6000A:
-		save_fp_context = r6000_save_fp_context;
-		restore_fp_context = r6000_restore_fp_context;
 #if 0
 		/*
 		 * The R6000 is the only R-series CPU that features a machine
@@ -592,31 +719,7 @@
 	case CPU_R3000:
 	case CPU_R3000A:
 		memcpy((void *)KSEG0, &except_vec0_r2300, 0x80);
-		save_fp_context = r2300_save_fp_context;
-		restore_fp_context = r2300_restore_fp_context;
-		resume = r2300_resume;
-		set_except_vector(1, r2300_handle_mod);
-		set_except_vector(2, r2300_handle_tlbl);
-		set_except_vector(3, r2300_handle_tlbs);
-		set_except_vector(4, handle_adel);
-		set_except_vector(5, handle_ades);
-		/*
-		 * The Data Bus Error/ Instruction Bus Errors are signaled
-		 * by external hardware.  Therefore these two expection have
-		 * board specific handlers.
-		 */
-		set_except_vector(6, handle_ibe);
-		set_except_vector(7, handle_dbe);
-		ibe_board_handler = default_be_board_handler;
-		dbe_board_handler = default_be_board_handler;
-
-		set_except_vector(8, handle_sys);
-		set_except_vector(9, handle_bp);
-		set_except_vector(10, handle_ri);
-		set_except_vector(11, handle_cpu);
-		set_except_vector(12, handle_ov);
-		set_except_vector(13, handle_tr);
-		set_except_vector(15, handle_fpe);
+		memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80);
 		break;
 	case CPU_R3041:
 	case CPU_R3051:
@@ -634,4 +737,8 @@
 		panic("Unknown CPU type");
 	}
 	flush_icache_range(KSEG0, KSEG0 + 0x200);
+
+	atomic_inc(&init_mm.mm_count);	/* XXX  UP?  */
+	current->active_mm = &init_mm;
+	current_pgd = init_mm.pgd;
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/unaligned.c linux/arch/mips/kernel/unaligned.c
--- v2.3.47/linux/arch/mips/kernel/unaligned.c	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/kernel/unaligned.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,5 @@
-/*
+/* $Id: unaligned.c,v 1.7 1999/12/04 03:59:00 ralf Exp $
+ *
  * Handle unaligned accesses by emulation.
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -7,7 +8,7 @@
  *
  * Copyright (C) 1996, 1998 by Ralf Baechle
  *
- * $Id: unaligned.c,v 1.5 1999/05/01 22:40:39 ralf Exp $
+ * $Id: unaligned.c,v 1.7 1999/12/04 03:59:00 ralf Exp $
  *
  * This file contains exception handler for address error exception with the
  * special capability to execute faulting instructions in software.  The
@@ -365,19 +366,13 @@
 		return;
 	}
 
-	lock_kernel();
 	send_sig(SIGSEGV, current, 1);
-	unlock_kernel();
 	return;
 sigbus:
-	lock_kernel();
 	send_sig(SIGBUS, current, 1);
-	unlock_kernel();
 	return;
 sigill:
-	lock_kernel();
 	send_sig(SIGILL, current, 1);
-	unlock_kernel();
 	return;
 }
 
@@ -398,7 +393,7 @@
 	pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0);
 	if (compute_return_epc(regs))
 		return;
-	if ((current->tss.mflags & MF_FIXADE) == 0)
+	if ((current->thread.mflags & MF_FIXADE) == 0)
 		goto sigbus;
 
 	emulate_load_store_insn(regs, regs->cp0_badvaddr, pc);
@@ -407,9 +402,7 @@
 	return;
 
 sigbus:
-	lock_kernel();
 	force_sig(SIGBUS, current);
-	unlock_kernel();
 
 	return;
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/ld.script.big linux/arch/mips/ld.script.big
--- v2.3.47/linux/arch/mips/ld.script.big	Fri May  8 00:13:24 1998
+++ linux/arch/mips/ld.script.big	Thu Feb 24 22:52:30 2000
@@ -5,26 +5,6 @@
 {
   /* Read-only sections, merged into text segment: */
   . = 0x80000000;
-  .rel.text      : { *(.rel.text)	}
-  .rela.text     : { *(.rela.text) 	}
-  .rel.data      : { *(.rel.data)	}
-  .rela.data     : { *(.rela.data) 	}
-  .rel.rodata    : { *(.rel.rodata) 	}
-  .rela.rodata   : { *(.rela.rodata) 	}
-  .rel.got       : { *(.rel.got)	}
-  .rela.got      : { *(.rela.got)	}
-  .rel.ctors     : { *(.rel.ctors)	}
-  .rela.ctors    : { *(.rela.ctors)	}
-  .rel.dtors     : { *(.rel.dtors)	}
-  .rela.dtors    : { *(.rela.dtors)	}
-  .rel.init      : { *(.rel.init)	}
-  .rela.init     : { *(.rela.init)	}
-  .rel.fini      : { *(.rel.fini)	}
-  .rela.fini     : { *(.rela.fini)	}
-  .rel.bss       : { *(.rel.bss)	}
-  .rela.bss      : { *(.rela.bss)	}
-  .rel.plt       : { *(.rel.plt)	}
-  .rela.plt      : { *(.rela.plt)	}
   .init          : { *(.init)		} =0
   .text      :
   {
@@ -38,14 +18,30 @@
   _etext = .;
   PROVIDE (etext = .);
 
+  . = ALIGN(8192);
+  .data.init_task : { *(.data.init_task) }
+
   /* Startup code */
   . = ALIGN(4096);
   __init_begin = .;
   .text.init : { *(.text.init) }
   .data.init : { *(.data.init) }
+  . = ALIGN(16);
+  __setup_start = .;
+  .setup.init : { *(.setup.init) }
+  __setup_end = .;
+  __initcall_start = .;
+  .initcall.init : { *(.initcall.init) }
+  __initcall_end = .;
   . = ALIGN(4096);	/* Align double page for init_task_union */
   __init_end = .;
 
+  . = ALIGN(4096);
+  .data.page_aligned : { *(.data.idt) }
+
+  . = ALIGN(32);
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
   .fini      : { *(.fini)    } =0
   .reginfo : { *(.reginfo) }
   /* Adjust the address for the data segment.  We want to adjust up to
@@ -86,6 +82,7 @@
 
   __bss_start = .;
   _fbss = .;
+  .sbss      : { *(.sbss) *(.scommon) }
   .bss       :
   {
    *(.dynbss)
@@ -93,8 +90,6 @@
    *(COMMON)
   _end = . ;
   PROVIDE (end = .);
-   *(.sbss)
-   *(.scommon)
   }
   /* These are needed for ELF backends which have not yet been
      converted to the new style linker.  */
diff -u --recursive --new-file v2.3.47/linux/arch/mips/ld.script.little linux/arch/mips/ld.script.little
--- v2.3.47/linux/arch/mips/ld.script.little	Fri May  8 00:13:24 1998
+++ linux/arch/mips/ld.script.little	Thu Feb 24 22:52:30 2000
@@ -5,26 +5,6 @@
 {
   /* Read-only sections, merged into text segment: */
   . = 0x80000000;
-  .rel.text      : { *(.rel.text)	}
-  .rela.text     : { *(.rela.text) 	}
-  .rel.data      : { *(.rel.data)	}
-  .rela.data     : { *(.rela.data) 	}
-  .rel.rodata    : { *(.rel.rodata) 	}
-  .rela.rodata   : { *(.rela.rodata) 	}
-  .rel.got       : { *(.rel.got)	}
-  .rela.got      : { *(.rela.got)	}
-  .rel.ctors     : { *(.rel.ctors)	}
-  .rela.ctors    : { *(.rela.ctors)	}
-  .rel.dtors     : { *(.rel.dtors)	}
-  .rela.dtors    : { *(.rela.dtors)	}
-  .rel.init      : { *(.rel.init)	}
-  .rela.init     : { *(.rela.init)	}
-  .rel.fini      : { *(.rel.fini)	}
-  .rela.fini     : { *(.rela.fini)	}
-  .rel.bss       : { *(.rel.bss)	}
-  .rela.bss      : { *(.rela.bss)	}
-  .rel.plt       : { *(.rel.plt)	}
-  .rela.plt      : { *(.rela.plt)	}
   .init          : { *(.init)		} =0
   .text      :
   {
@@ -38,14 +18,30 @@
   _etext = .;
   PROVIDE (etext = .);
 
+  . = ALIGN(8192);
+  .data.init_task : { *(.data.init_task) }
+
   /* Startup code */
   . = ALIGN(4096);
   __init_begin = .;
   .text.init : { *(.text.init) }
   .data.init : { *(.data.init) }
+  . = ALIGN(16);
+  __setup_start = .;
+  .setup.init : { *(.setup.init) }
+  __setup_end = .;
+  __initcall_start = .;
+  .initcall.init : { *(.initcall.init) }
+  __initcall_end = .;
   . = ALIGN(4096);	/* Align double page for init_task_union */
   __init_end = .;
 
+  . = ALIGN(4096);
+  .data.page_aligned : { *(.data.idt) }
+
+  . = ALIGN(32);
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
   .fini      : { *(.fini)    } =0
   .reginfo : { *(.reginfo) }
   /* Adjust the address for the data segment.  We want to adjust up to
@@ -86,6 +82,7 @@
 
   __bss_start = .;
   _fbss = .;
+  .sbss      : { *(.sbss) *(.scommon) }
   .bss       :
   {
    *(.dynbss)
@@ -93,8 +90,6 @@
    *(COMMON)
   _end = . ;
   PROVIDE (end = .);
-   *(.sbss)
-   *(.scommon)
   }
   /* These are needed for ELF backends which have not yet been
      converted to the new style linker.  */
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/Makefile linux/arch/mips/lib/Makefile
--- v2.3.47/linux/arch/mips/lib/Makefile	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/lib/Makefile	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.9 1999/01/04 16:03:50 ralf Exp $
+# $Id: Makefile,v 1.12 1999/12/04 03:59:00 ralf Exp $
 #
 # Makefile for MIPS-specific library files..
 #
@@ -9,8 +9,15 @@
 	$(CC) $(CFLAGS) -c $< -o $*.o
 
 L_TARGET = lib.a
-L_OBJS	= csum_partial.o csum_partial_copy.o dump_tlb.o floppy-std.o \
+L_OBJS	= csum_partial.o csum_partial_copy.o floppy-std.o \
 	  floppy-no.o ide-std.o ide-no.o kbd-std.o kbd-no.o rtc-std.o \
-	  rtc-no.o memset.o memcpy.o strlen_user.o strncpy_user.o watch.o
+	  rtc-no.o memcpy.o memset.o strlen_user.o strncpy_user.o \
+	  strnlen_user.o watch.o
+
+ifdef CONFIG_CPU_R3000
+  L_OBJS += r3k_dump_tlb.o 
+else
+  L_OBJS += dump_tlb.o 
+endif
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/csum_partial_copy.c linux/arch/mips/lib/csum_partial_copy.c
--- v2.3.47/linux/arch/mips/lib/csum_partial_copy.c	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/lib/csum_partial_copy.c	Thu Feb 24 22:52:30 2000
@@ -14,7 +14,7 @@
  *		as published by the Free Software Foundation; either version
  *		2 of the License, or (at your option) any later version.
  *
- * $Id: csum_partial_copy.c,v 1.2 1998/09/19 19:16:17 ralf Exp $
+ * $Id: csum_partial_copy.c,v 1.3 2000/02/05 06:47:08 ralf Exp $
  */
 #include <net/checksum.h>
 #include <linux/types.h>
@@ -55,21 +55,4 @@
 	}
 		
 	return csum_partial(dst, len, sum);
-}
-
-/*
- * Copy to userspace and compute checksum.
- */
-unsigned int csum_partial_copy_to_user (const char *src, char *dst,
-                                        int len, unsigned int sum,
-                                        int *err_ptr)
-{
-	sum = csum_partial(src, len, sum);
-
-	if (copy_to_user(dst, src, len)) {
-		*err_ptr = -EFAULT;
-		return sum;
-	}
-
-	return sum;
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/dump_tlb.c linux/arch/mips/lib/dump_tlb.c
--- v2.3.47/linux/arch/mips/lib/dump_tlb.c	Fri May  8 00:13:24 1998
+++ linux/arch/mips/lib/dump_tlb.c	Thu Feb 24 22:52:30 2000
@@ -1,8 +1,8 @@
 /*
  * Dump R4x00 TLB for debugging purposes.
  *
- * Copyright (C) 1994, 1995 by Waldorf Electronics,
- * written by Ralf Baechle.
+ * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
  */
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -11,27 +11,22 @@
 
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
-#include <asm/mipsconfig.h>
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
-static char *region_map [] = {
-	"u", "s", "k", "!"
-};
+#define mips_tlb_entries 48
 
 void
 dump_tlb(int first, int last)
 {
 	int	i;
-	int	wired;
-	unsigned int pagemask, c0, c1, r;
-	unsigned long long entryhi, entrylo0, entrylo1;
+	unsigned int pagemask, c0, c1, asid;
+	unsigned long entryhi, entrylo0, entrylo1;
 
-	wired = read_32bit_cp0_register(CP0_WIRED);
-	printk("Wired: %d", wired);
-	
-	for(i=first;i<last;i++)
+	asid = get_entryhi() & 0xff;
+
+	for(i=first;i<=last;i++)
 	{
 		write_32bit_cp0_register(CP0_INDEX, i);
 		__asm__ __volatile__(
@@ -43,30 +38,31 @@
 			".set\treorder\n\t"
 			".set\tmips0\n\t");
 		pagemask = read_32bit_cp0_register(CP0_PAGEMASK);
-		entryhi  = read_64bit_cp0_register(CP0_ENTRYHI);
-		entrylo0 = read_64bit_cp0_register(CP0_ENTRYLO0);
-		entrylo1 = read_64bit_cp0_register(CP0_ENTRYLO1);
-
-		if((entrylo0|entrylo1) & 2)
-		{
+		entryhi  = read_32bit_cp0_register(CP0_ENTRYHI);
+		entrylo0 = read_32bit_cp0_register(CP0_ENTRYLO0);
+		entrylo1 = read_32bit_cp0_register(CP0_ENTRYLO1);
+
+		/* Unused entries have a virtual address of KSEG0.  */
+		if ((entryhi & 0xffffe000) != 0x80000000
+		    && (entryhi & 0xff) == asid) {
 			/*
 			 * Only print entries in use
 			 */
-			printk("\nIndex: %2d pgmask=%08x ", i, pagemask);
+			printk("Index: %2d pgmask=%08x ", i, pagemask);
 
-			r  = entryhi >> 62;
 			c0 = (entrylo0 >> 3) & 7;
 			c1 = (entrylo1 >> 3) & 7;
 
-			printk("%s vpn2=%08Lx "
-			       "[pfn=%06Lx c=%d d=%d v=%d g=%Ld]"
-			       "[pfn=%06Lx c=%d d=%d v=%d g=%Ld]",
-			       region_map [r], (entryhi >> 13) & 0xffffffff,
-			       (entrylo0 >> 6) & 0xffffff, c0,
+			printk("va=%08lx asid=%08lx"
+			       "  [pa=%06lx c=%d d=%d v=%d g=%ld]"
+			       "  [pa=%06lx c=%d d=%d v=%d g=%ld]",
+			       (entryhi & 0xffffe000),
+			       entryhi & 0xff,
+			       entrylo0 & PAGE_MASK, c0,
 			       (entrylo0 & 4) ? 1 : 0,
 			       (entrylo0 & 2) ? 1 : 0,
 			       (entrylo0 & 1),
-			       (entrylo1 >> 6) & 0xffffff, c1,
+			       entrylo1 & PAGE_MASK, c1,
 			       (entrylo1 & 4) ? 1 : 0,
 			       (entrylo1 & 2) ? 1 : 0,
 			       (entrylo1 & 1));
@@ -74,6 +70,8 @@
 		}
 	}
 	printk("\n");
+
+	set_entryhi(asid);
 }
 
 void
@@ -85,9 +83,45 @@
 void
 dump_tlb_wired(void)
 {
+	int	wired;
+
+	wired = read_32bit_cp0_register(CP0_WIRED);
+	printk("Wired: %d", wired);
 	dump_tlb(0, read_32bit_cp0_register(CP0_WIRED));
 }
 
+#define BARRIER						\
+	__asm__ __volatile__(				\
+		".set\tnoreorder\n\t"			\
+		"nop;nop;nop;nop;nop;nop;nop\n\t"	\
+		".set\treorder");
+
+void
+dump_tlb_addr(unsigned long addr)
+{
+	unsigned int flags, oldpid;
+	int index;
+
+	__save_and_cli(flags);
+	oldpid = get_entryhi() & 0xff;
+	BARRIER;
+	set_entryhi((addr & PAGE_MASK) | oldpid);
+	BARRIER;
+	tlb_probe();
+	BARRIER;
+	index = get_index();
+	set_entryhi(oldpid);
+	__restore_flags(flags);
+
+	if (index < 0) {
+		printk("No entry for address 0x%08lx in TLB\n", addr);
+		return;
+	}
+
+	printk("Entry %d maps address 0x%08lx\n", index, addr);
+	dump_tlb(index, index);
+}
+
 void
 dump_tlb_nonwired(void)
 {
@@ -101,12 +135,12 @@
 	pmd_t	*pmd;
 	pte_t	*pte, page;
 	unsigned int addr;
+	unsigned long val;
 
 	addr = (unsigned int) address;
 
-	printk("Addr              == %08x\n", addr);
-	printk("tasks->tss.pg_dir == %08x\n", (unsigned int) t->tss.pg_dir);
-	printk("tasks->mm.pgd     == %08x\n", (unsigned int) t->mm->pgd);
+	printk("Addr                 == %08x\n", addr);
+	printk("tasks->mm.pgd        == %08x\n", (unsigned int) t->mm->pgd);
 
 	page_dir = pgd_offset(t->mm, 0);
 	printk("page_dir == %08x\n", (unsigned int) page_dir);
@@ -122,6 +156,17 @@
 
 	page = *pte;
 	printk("page == %08x\n", (unsigned int) pte_val(page));
+
+	val = pte_val(page);
+	if (val & _PAGE_PRESENT) printk("present ");
+	if (val & _PAGE_READ) printk("read ");
+	if (val & _PAGE_WRITE) printk("write ");
+	if (val & _PAGE_ACCESSED) printk("accessed ");
+	if (val & _PAGE_MODIFIED) printk("modified ");
+	if (val & _PAGE_R4KBUG) printk("r4kbug ");
+	if (val & _PAGE_GLOBAL) printk("global ");
+	if (val & _PAGE_VALID) printk("valid ");
+	printk("\n");
 }
 
 void
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/floppy-no.c linux/arch/mips/lib/floppy-no.c
--- v2.3.47/linux/arch/mips/lib/floppy-no.c	Tue Oct 20 13:52:54 1998
+++ linux/arch/mips/lib/floppy-no.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: floppy-no.c,v 1.1 1998/05/07 18:38:32 ralf Exp $
+/* $Id: floppy-no.c,v 1.1 1998/06/30 00:21:54 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/floppy-std.c linux/arch/mips/lib/floppy-std.c
--- v2.3.47/linux/arch/mips/lib/floppy-std.c	Wed Feb 16 17:03:51 2000
+++ linux/arch/mips/lib/floppy-std.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: floppy-std.c,v 1.3 1998/10/28 12:38:13 ralf Exp $
+/* $Id: floppy-std.c,v 1.3 2000/02/24 00:12:40 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/kbd-no.c linux/arch/mips/lib/kbd-no.c
--- v2.3.47/linux/arch/mips/lib/kbd-no.c	Fri Jun 25 17:40:13 1999
+++ linux/arch/mips/lib/kbd-no.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: kbd-no.c,v 1.1 1998/10/28 12:38:14 ralf Exp $
+/* $Id: kbd-no.c,v 1.1 1999/01/04 16:03:51 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/kbd-std.c linux/arch/mips/lib/kbd-std.c
--- v2.3.47/linux/arch/mips/lib/kbd-std.c	Fri Jun 25 17:40:13 1999
+++ linux/arch/mips/lib/kbd-std.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: kbd-std.c,v 1.2 1999/06/11 14:29:45 ralf Exp $
+/* $Id: kbd-std.c,v 1.2 1999/06/17 13:25:50 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/memcpy.S linux/arch/mips/lib/memcpy.S
--- v2.3.47/linux/arch/mips/lib/memcpy.S	Fri Jun 25 17:40:13 1999
+++ linux/arch/mips/lib/memcpy.S	Thu Feb 24 22:52:30 2000
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * $Id: memcpy.S,v 1.3 1998/07/10 01:14:49 ralf Exp $
+ * $Id: memcpy.S,v 1.4 2000/01/27 01:05:23 ralf Exp $
  *
  * Unified implementation of memcpy, memmove and the __copy_user backend.
  * For __rmemcpy and memmove an exception is always a kernel bug, therefore
@@ -688,8 +688,8 @@
 
 	jr	ra
 	 move	a2, zero
-	END(__rmemcpy)
 #endif /* Horror fix */
+	END(__rmemcpy)
 
 l_fixup:					# clear the rest of the buffer
 	lw	t0, THREAD_BUADDR($28)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/r3k_dump_tlb.c linux/arch/mips/lib/r3k_dump_tlb.c
--- v2.3.47/linux/arch/mips/lib/r3k_dump_tlb.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/r3k_dump_tlb.c	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,185 @@
+/*
+ * Dump R3000 TLB for debugging purposes.
+ *
+ * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Harald Koerfgen
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#define mips_tlb_entries 64
+
+void
+dump_tlb(int first, int last)
+{
+	int	i;
+	unsigned int asid;
+	unsigned long entryhi, entrylo0;
+
+	asid = get_entryhi() & 0xfc0;
+
+	for(i=first;i<=last;i++)
+	{
+		write_32bit_cp0_register(CP0_INDEX, i);
+		__asm__ __volatile__(
+			".set\tnoreorder\n\t"
+			"tlbr\n\t"
+			"nop\n\t"
+			".set\treorder");
+		entryhi  = read_32bit_cp0_register(CP0_ENTRYHI);
+		entrylo0 = read_32bit_cp0_register(CP0_ENTRYLO0);
+
+		/* Unused entries have a virtual address of KSEG0.  */
+		if ((entryhi & 0xffffe000) != 0x80000000
+		    && (entryhi & 0xfc0) == asid) {
+			/*
+			 * Only print entries in use
+			 */
+			printk("Index: %2d ", i);
+
+			printk("va=%08lx asid=%08lx"
+			       "  [pa=%06lx n=%d d=%d v=%d g=%ld]",
+			       (entryhi & 0xffffe000),
+			       entryhi & 0xfc0,
+			       entrylo0 & PAGE_MASK,
+			       (entrylo0 & (1 << 11)) ? 1 : 0,
+			       (entrylo0 & (1 << 10)) ? 1 : 0,
+			       (entrylo0 & (1 << 9)) ? 1 : 0,
+			       (entrylo0 & (1 << 8)) ? 1 : 0);
+		}
+	}
+	printk("\n");
+
+	set_entryhi(asid);
+}
+
+void
+dump_tlb_all(void)
+{
+	dump_tlb(0, mips_tlb_entries - 1);
+}
+
+void
+dump_tlb_wired(void)
+{
+	int	wired = 7;
+
+	printk("Wired: %d", wired);
+	dump_tlb(0, read_32bit_cp0_register(CP0_WIRED));
+}
+
+void
+dump_tlb_addr(unsigned long addr)
+{
+	unsigned int flags, oldpid;
+	int index;
+
+	__save_and_cli(flags);
+	oldpid = get_entryhi() & 0xff;
+	set_entryhi((addr & PAGE_MASK) | oldpid);
+	tlb_probe();
+	index = get_index();
+	set_entryhi(oldpid);
+	__restore_flags(flags);
+
+	if (index < 0) {
+		printk("No entry for address 0x%08lx in TLB\n", addr);
+		return;
+	}
+
+	printk("Entry %d maps address 0x%08lx\n", index, addr);
+	dump_tlb(index, index);
+}
+
+void
+dump_tlb_nonwired(void)
+{
+	dump_tlb(8, mips_tlb_entries - 1);
+}
+
+void
+dump_list_process(struct task_struct *t, void *address)
+{
+	pgd_t	*page_dir, *pgd;
+	pmd_t	*pmd;
+	pte_t	*pte, page;
+	unsigned int addr;
+	unsigned long val;
+
+	addr = (unsigned int) address;
+
+	printk("Addr                 == %08x\n", addr);
+	printk("tasks->mm.pgd        == %08x\n", (unsigned int) t->mm->pgd);
+
+	page_dir = pgd_offset(t->mm, 0);
+	printk("page_dir == %08x\n", (unsigned int) page_dir);
+
+	pgd = pgd_offset(t->mm, addr);
+	printk("pgd == %08x, ", (unsigned int) pgd);
+
+	pmd = pmd_offset(pgd, addr);
+	printk("pmd == %08x, ", (unsigned int) pmd);
+
+	pte = pte_offset(pmd, addr);
+	printk("pte == %08x, ", (unsigned int) pte);
+
+	page = *pte;
+	printk("page == %08x\n", (unsigned int) pte_val(page));
+
+	val = pte_val(page);
+	if (val & _PAGE_PRESENT) printk("present ");
+	if (val & _PAGE_READ) printk("read ");
+	if (val & _PAGE_WRITE) printk("write ");
+	if (val & _PAGE_ACCESSED) printk("accessed ");
+	if (val & _PAGE_MODIFIED) printk("modified ");
+	if (val & _PAGE_GLOBAL) printk("global ");
+	if (val & _PAGE_VALID) printk("valid ");
+	printk("\n");
+}
+
+void
+dump_list_current(void *address)
+{
+	dump_list_process(current, address);
+}
+
+unsigned int
+vtop(void *address)
+{
+	pgd_t	*pgd;
+	pmd_t	*pmd;
+	pte_t	*pte;
+	unsigned int addr, paddr;
+
+	addr = (unsigned long) address;
+	pgd = pgd_offset(current->mm, addr);
+	pmd = pmd_offset(pgd, addr);
+	pte = pte_offset(pmd, addr);
+	paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
+	paddr |= (addr & ~PAGE_MASK);
+
+	return paddr;
+}
+
+void
+dump16(unsigned long *p)
+{
+	int i;
+
+	for(i=0;i<8;i++)
+	{
+		printk("*%08lx == %08lx, ",
+		       (unsigned long)p, (unsigned long)*p++);
+		printk("*%08lx == %08lx\n",
+		       (unsigned long)p, (unsigned long)*p++);
+	}
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/rtc-no.c linux/arch/mips/lib/rtc-no.c
--- v2.3.47/linux/arch/mips/lib/rtc-no.c	Tue Oct 20 13:52:54 1998
+++ linux/arch/mips/lib/rtc-no.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: rtc-no.c,v 1.2 1998/06/25 20:19:15 ralf Exp $
+/* $Id: rtc-no.c,v 1.1 1998/06/30 00:21:55 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/rtc-std.c linux/arch/mips/lib/rtc-std.c
--- v2.3.47/linux/arch/mips/lib/rtc-std.c	Tue Oct 20 13:52:54 1998
+++ linux/arch/mips/lib/rtc-std.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: rtc-std.c,v 1.2 1998/06/25 20:19:16 ralf Exp $
+/* $Id: rtc-std.c,v 1.1 1998/06/30 00:21:55 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/strlen_user.S linux/arch/mips/lib/strlen_user.S
--- v2.3.47/linux/arch/mips/lib/strlen_user.S	Fri Jun 25 17:40:13 1999
+++ linux/arch/mips/lib/strlen_user.S	Thu Feb 24 22:52:30 2000
@@ -1,13 +1,11 @@
-/*
- * arch/mips/lib/strlen_user.S
+/* $Id: strlen_user.S,v 1.4 1999/12/04 03:59:00 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1996, 1998 by Ralf Baechle
- *
- * $Id: strlen_user.S,v 1.2 1998/05/04 09:12:54 ralf Exp $
+ * Copyright (c) 1996, 1998, 1999 by Ralf Baechle
+ * Copyright (c) 1999 Silicon Graphics, Inc.
  */
 #include <asm/asm.h>
 #include <asm/offset.h>
@@ -25,24 +23,23 @@
  *
  * Return 0 for error
  */
-LEAF(__strlen_user_nocheck_asm)
-	lw	v0, THREAD_CURDS($28)			# pointer ok?
-	subu	v0, zero, v0
+LEAF(__strlen_user_asm)
+	lw	v0, THREAD_CURDS($28)	# pointer ok?
 	and	v0, a0
-	nor	v0, zero, v0
-	beqz	v0, fault
-EXPORT(__strlen_user_asm)
-	move		v0, a0
+	bltz	v0, fault
+
+EXPORT(__strlen_user_nocheck_asm)
+	move	v0, a0
 1:	EX(lb, t0, (v0), fault)
-	LONG_ADDIU	v0, 1
-	bnez		t0, 1b
-	LONG_SUBU	v0, a0
-	jr		ra
+	addiu	v0, 1
+	bnez	t0, 1b
+	subu	v0, a0
+	jr	ra
 	END(__strlen_user_nocheck_asm)
 
-	.section	__ex_table,"a"
-	PTR		1b, fault
+	.section __ex_table,"a"
+	PTR	1b, fault
 	.previous
 
-fault:	move		v0, zero
-	jr		ra
+fault:	move	v0, zero
+	jr	ra
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/strncpy_user.S linux/arch/mips/lib/strncpy_user.S
--- v2.3.47/linux/arch/mips/lib/strncpy_user.S	Fri Jun 25 17:40:13 1999
+++ linux/arch/mips/lib/strncpy_user.S	Thu Feb 24 22:52:30 2000
@@ -1,13 +1,10 @@
-/*
- * arch/mips/lib/strncpy_user.S
+/* $Id: strncpy_user.S,v 1.4 1999/12/04 03:59:00 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1996 by Ralf Baechle
- *
- * $Id: strncpy_user.S,v 1.2 1998/05/04 09:12:54 ralf Exp $
+ * Copyright (c) 1996, 1999 by Ralf Baechle
  */
 #include <linux/errno.h>
 #include <asm/asm.h>
@@ -32,32 +29,31 @@
  */
 
 LEAF(__strncpy_from_user_asm)
-	lw	v0, THREAD_CURDS($28)		# pointer ok?
-	subu	v0, zero, v0
+	lw	v0, THREAD_CURDS($28)	# pointer ok?
 	and	v0, a1
-	nor	v0, zero, v0
-	beqz	v0, fault
+	bltz	v0, fault
+
 EXPORT(__strncpy_from_user_nocheck_asm)
-	move		v0,zero
-	move		v1,a1
-	.set		noreorder
+	move	v0, zero
+	move	v1, a1
+	.set	noreorder
 1:	EX(lbu,	 t0, (v1), fault)
-	LONG_ADDIU	v1,1
-	beqz		t0,2f
-	 sb		t0,(a0)
-	LONG_ADDIU	v0,1
-	bne		v0,a2,1b
-	 LONG_ADDIU	a0,1
-	.set		reorder
-2:	LONG_ADDU	t0,a1,v0
-	xor		t0,a1
-	bltz		t0,fault
-	jr		ra			# return n
+	addiu	v1, v1, 1
+	beqz	t0, 2f
+	 sb	t0, (a0)
+	addiu	v0, 1
+	bne	v0, a2, 1b
+	 addiu	a0, 1
+	.set	reorder
+2:	addu	t0, a1, v0
+	xor	t0, a1
+	bltz	t0, fault
+	jr	ra				# return n
 	END(__strncpy_from_user_asm)
 
-fault:	li		v0,-EFAULT
-	jr		ra
+fault:	li	v0, -EFAULT
+	jr	ra
 
-	.section	__ex_table,"a"
-	PTR		1b,fault
+	.section __ex_table,"a"
+	PTR	1b, fault
 	.previous
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/strnlen_user.S linux/arch/mips/lib/strnlen_user.S
--- v2.3.47/linux/arch/mips/lib/strnlen_user.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/strnlen_user.S	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,54 @@
+/* $Id: strnlen_user.S,v 1.2 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1996, 1998, 1999 by Ralf Baechle
+ * Copyright (c) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+#include <asm/sgidefs.h>
+
+#define EX(insn,reg,addr,handler)			\
+9:	insn	reg, addr;				\
+	.section __ex_table,"a";			\
+	PTR	9b, handler;				\
+	.previous
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error, len of string but at max a1 otherwise
+ *
+ * Note: for performance reasons we deliberately accept that a user may
+ *       make strlen_user and strnlen_user access the first few KSEG0
+ *       bytes.  There's nothing secret there ...
+ */
+LEAF(__strnlen_user_asm)
+	lw	v0, THREAD_CURDS($28)	# pointer ok?
+	and	v0, a0
+	bltz	v0, fault
+
+EXPORT(__strnlen_user_nocheck_asm)
+	.type	__strnlen_user_nocheck_asm,@function
+	move	v0, a0
+	addu	a1, a0			# stop pointer
+	.set	noreorder
+1:	beq	v0, a1, 1f		# limit reached?
+	 addiu	v0, 1
+	.set	reorder
+	EX(lb, t0, -1(v0), fault)
+	bnez	t0, 1b
+1:	subu	v0, a0
+	jr	ra
+	END(__strnlen_user_asm)
+
+	.section	__ex_table,"a"
+	PTR		1b, fault
+	.previous
+
+fault:	move	v0, zero
+	jr	ra
diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/watch.S linux/arch/mips/lib/watch.S
--- v2.3.47/linux/arch/mips/lib/watch.S	Fri Jun 25 17:40:13 1999
+++ linux/arch/mips/lib/watch.S	Thu Feb 24 22:52:30 2000
@@ -1,12 +1,13 @@
-/*
- * Kernel debug stuff to use the Watch registers.
- * Useful to find stack overflows, dangling pointers etc.
+/* $Id: watch.S,v 1.3 1999/08/21 22:19:11 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996 by Ralf Baechle
+ * Kernel debug stuff to use the Watch registers.
+ * Useful to find stack overflows, dangling pointers etc.
+ *
+ * Copyright (C) 1995, 1996, 1999 by Ralf Baechle
  */
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
@@ -48,7 +49,6 @@
  */
 		LEAF(__watch_reenable)
 		lw	t0,watch_savelo
-
 		jr	ra
 		 mtc0	t0,CP0_WATCHLO
 		END(__watch_reenable)
@@ -59,67 +59,3 @@
 		.data
 watch_savelo:	.word	0
 		.text
-
-/*
- * The stuff below are just some kernel debugging gadgets. It is only here
- * because it had to be somewhere and will go away.
- */
-
-/*
- * Parameter: none
- * Results  : none
- */
-		LEAF(get_sp)
-		jr	ra
-		 move	v0,sp
-		END(get_sp)
-
-/*
- * Parameter: none
- * Results  : none
- */
-		LEAF(get_ra)
-		jr	ra
-		 move	v0,ra
-		END(get_ra)
-
-/*
- * Parameter: none
- * Results  : none
- */
-		LEAF(get_status)
-		jr	ra
-		 mfc0	v0,CP0_STATUS
-		END(get_status)
-
-/*
- * Parameter: none
- * Results  : none
- */
-		NESTED(print_sp, ((5*SZREG)+ALSZ)&ALMASK, sp)
-		.mask	0x80000000,4*SZREG
-		PTR_SUBU	sp,((5*SZREG)+ALSZ)&ALMASK
-		REG_S		ra,4*SZREG(sp)
-		move		a1,sp
-		PRINT("$sp == %08lx\n")
-		REG_L		ra,4*SZREG(sp)
-
-		jr		ra
-		 PTR_ADDU	sp,((5*SZREG)+ALSZ)&ALMASK
-		END(print_sp)
-
-/*
- * Parameter: none
- * Results  : none
- */
-		NESTED(print_st, ((5*SZREG)+ALSZ)&ALMASK, sp)
-		.mask	0x80000000,4*SZREG
-		PTR_SUBU	sp,((5*SZREG)+ALSZ)&ALMASK
-		REG_S		ra,4*SZREG(sp)
-		mfc0		a1,CP0_STATUS
-		PRINT("cp0_status == %08lx\n")
-		REG_L		ra,4*SZREG(sp)
-
-		jr		ra
-		 PTR_ADDU	sp,((5*SZREG)+ALSZ)&ALMASK
-		END(print_st)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/mm/Makefile linux/arch/mips/mm/Makefile
--- v2.3.47/linux/arch/mips/mm/Makefile	Fri Jun 25 17:40:13 1999
+++ linux/arch/mips/mm/Makefile	Thu Feb 24 22:52:30 2000
@@ -8,10 +8,29 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-O_OBJS	 := extable.o init.o fault.o r4xx0.o r2300.o r6000.o tfp.o \
-            andes.o loadmmu.o
+O_OBJS	 := extable.o init.o fault.o loadmmu.o
 
-ifdef CONFIG_SGI
+ifdef CONFIG_CPU_R3000
+O_OBJS   += r2300.o
+endif
+
+ifdef CONFIG_CPU_R4300
+O_OBJS   += r4xx0.o
+endif
+
+ifdef CONFIG_CPU_R4X00
+O_OBJS   += r4xx0.o
+endif
+
+ifdef CONFIG_CPU_R5000
+O_OBJS   += r4xx0.o
+endif
+
+ifdef CONFIG_CPU_NEVADA
+O_OBJS   += r4xx0.o
+endif
+
+ifdef CONFIG_SGI_IP22
 O_OBJS   += umap.o
 endif
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/mm/andes.c linux/arch/mips/mm/andes.c
--- v2.3.47/linux/arch/mips/mm/andes.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/mm/andes.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: andes.c,v 1.6 1999/01/04 16:03:52 ralf Exp $
+/* $Id: andes.c,v 1.11 2000/02/24 00:12:40 ralf Exp $
  *
  * andes.c: MMU and cache operations for the R10000 (ANDES).
  *
@@ -14,7 +14,82 @@
 #include <asm/sgialib.h>
 #include <asm/mmu_context.h>
 
-extern unsigned long mips_tlb_entries;
+/* page functions */
+void andes_clear_page(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"addiu\t$1,%0,%2\n"
+		"1:\tsw\t$0,(%0)\n\t"
+		"sw\t$0,4(%0)\n\t"
+		"sw\t$0,8(%0)\n\t"
+		"sw\t$0,12(%0)\n\t"
+		"addiu\t%0,32\n\t"
+		"sw\t$0,-16(%0)\n\t"
+		"sw\t$0,-12(%0)\n\t"
+		"sw\t$0,-8(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sw\t$0,-4(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page),
+		 "I" (PAGE_SIZE)
+		:"$1","memory");
+}
+
+static void andes_copy_page(void * to, void * from)
+{
+	unsigned long dummy1, dummy2;
+	unsigned long reg1, reg2, reg3, reg4;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"addiu\t$1,%0,%8\n"
+		"1:\tlw\t%2,(%1)\n\t"
+		"lw\t%3,4(%1)\n\t"
+		"lw\t%4,8(%1)\n\t"
+		"lw\t%5,12(%1)\n\t"
+		"sw\t%2,(%0)\n\t"
+		"sw\t%3,4(%0)\n\t"
+		"sw\t%4,8(%0)\n\t"
+		"sw\t%5,12(%0)\n\t"
+		"lw\t%2,16(%1)\n\t"
+		"lw\t%3,20(%1)\n\t"
+		"lw\t%4,24(%1)\n\t"
+		"lw\t%5,28(%1)\n\t"
+		"sw\t%2,16(%0)\n\t"
+		"sw\t%3,20(%0)\n\t"
+		"sw\t%4,24(%0)\n\t"
+		"sw\t%5,28(%0)\n\t"
+		"addiu\t%0,64\n\t"
+		"addiu\t%1,64\n\t"
+		"lw\t%2,-32(%1)\n\t"
+		"lw\t%3,-28(%1)\n\t"
+		"lw\t%4,-24(%1)\n\t"
+		"lw\t%5,-20(%1)\n\t"
+		"sw\t%2,-32(%0)\n\t"
+		"sw\t%3,-28(%0)\n\t"
+		"sw\t%4,-24(%0)\n\t"
+		"sw\t%5,-20(%0)\n\t"
+		"lw\t%2,-16(%1)\n\t"
+		"lw\t%3,-12(%1)\n\t"
+		"lw\t%4,-8(%1)\n\t"
+		"lw\t%5,-4(%1)\n\t"
+		"sw\t%2,-16(%0)\n\t"
+		"sw\t%3,-12(%0)\n\t"
+		"sw\t%4,-8(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sw\t%5,-4(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2),
+		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
+		:"0" (to), "1" (from),
+		 "I" (PAGE_SIZE));
+}
 
 /* Cache operations. XXX Write these dave... */
 static inline void andes_flush_cache_all(void)
@@ -40,7 +115,7 @@
 	/* XXX */
 }
 
-static void andes_flush_page_to_ram(unsigned long page)
+static void andes_flush_page_to_ram(struct page * page)
 {
 	/* XXX */
 }
@@ -51,67 +126,52 @@
 }
 
 /* TLB operations. XXX Write these dave... */
-static inline void andes_flush_tlb_all(void)
+void flush_tlb_all(void)
 {
 	/* XXX */
 }
 
-static void andes_flush_tlb_mm(struct mm_struct *mm)
+void flush_tlb_mm(struct mm_struct *mm)
 {
 	/* XXX */
 }
 
-static void andes_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+void flush_tlb_range(struct mm_struct *mm, unsigned long start,
 				  unsigned long end)
 {
 	/* XXX */
 }
 
-static void andes_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
 	/* XXX */
 }
 
-static void andes_load_pgd(unsigned long pg_dir)
+void load_pgd(unsigned long pg_dir)
 {
 }
 
-static void andes_pgd_init(unsigned long page)
+void pgd_init(unsigned long page)
 {
 }
 
-static void andes_add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
 				  unsigned long entryhi, unsigned long pagemask)
 {
         /* XXX */
 }
 
-static int andes_user_mode(struct pt_regs *regs)
-{
-	return (regs->cp0_status & ST0_KSU) == KSU_USER;
-}
-
 void __init ld_mmu_andes(void)
 {
-	flush_cache_all = andes_flush_cache_all;
-	flush_cache_mm = andes_flush_cache_mm;
-	flush_cache_range = andes_flush_cache_range;
-	flush_cache_page = andes_flush_cache_page;
-	flush_cache_sigtramp = andes_flush_cache_sigtramp;
-	flush_page_to_ram = andes_flush_page_to_ram;
-
-	flush_tlb_all = andes_flush_tlb_all;
-	flush_tlb_mm = andes_flush_tlb_mm;
-	flush_tlb_range = andes_flush_tlb_range;
-	flush_tlb_page = andes_flush_tlb_page;
-	andes_asid_setup();
-    
-        add_wired_entry = andes_add_wired_entry;
-
-	user_mode = andes_user_mode;
+	_clear_page = andes_clear_page;
+	_copy_page = andes_copy_page;
 
-	load_pgd = andes_load_pgd;
-	pgd_init = andes_pgd_init;
+	_flush_cache_all = andes_flush_cache_all;
+	_flush_cache_mm = andes_flush_cache_mm;
+	_flush_cache_range = andes_flush_cache_range;
+	_flush_cache_page = andes_flush_cache_page;
+	_flush_cache_sigtramp = andes_flush_cache_sigtramp;
+	_flush_page_to_ram = andes_flush_page_to_ram;
 
 	flush_cache_all();
 	flush_tlb_all();
diff -u --recursive --new-file v2.3.47/linux/arch/mips/mm/extable.c linux/arch/mips/mm/extable.c
--- v2.3.47/linux/arch/mips/mm/extable.c	Thu Jun 26 12:33:38 1997
+++ linux/arch/mips/mm/extable.c	Thu Feb 24 22:52:30 2000
@@ -8,7 +8,7 @@
 extern const struct exception_table_entry __start___ex_table[];
 extern const struct exception_table_entry __stop___ex_table[];
 
-static inline unsigned
+static inline unsigned long
 search_one_table(const struct exception_table_entry *first,
                  const struct exception_table_entry *last,
                  unsigned long value)
diff -u --recursive --new-file v2.3.47/linux/arch/mips/mm/fault.c linux/arch/mips/mm/fault.c
--- v2.3.47/linux/arch/mips/mm/fault.c	Fri Jul 23 12:20:23 1999
+++ linux/arch/mips/mm/fault.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.9 1999/01/04 16:03:53 ralf Exp $
+/* $Id: fault.c,v 1.16 2000/02/18 00:24:30 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -21,7 +21,7 @@
 #include <linux/version.h>
 
 #include <asm/hardirq.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
 #include <asm/softirq.h>
 #include <asm/system.h>
@@ -29,9 +29,7 @@
 
 #define development_version (LINUX_VERSION_CODE & 0x100)
 
-extern void die(char *, struct pt_regs *, unsigned long write);
-
-unsigned long asid_cache;
+unsigned long asid_cache = ASID_FIRST_VERSION;
 
 /*
  * Macro for exception fixup code to access integer registers.
@@ -49,6 +47,7 @@
 	struct vm_area_struct * vma;
 	struct task_struct *tsk = current;
 	struct mm_struct *mm = tsk->mm;
+	int si_code = SEGV_MAPERR;
 	unsigned long fixup;
 
 	/*
@@ -76,6 +75,8 @@
  * we can handle it..
  */
 good_area:
+	si_code = SEGV_ACCERR;
+
 	if (write) {
 		if (!(vma->vm_flags & VM_WRITE))
 			goto bad_area;
@@ -96,6 +97,7 @@
 		if (!fault)
 			goto do_sigbus;
 	}
+
 	up(&mm->mmap_sem);
 	return;
 
@@ -107,8 +109,9 @@
 	up(&mm->mmap_sem);
 
 	if (user_mode(regs)) {
-		tsk->tss.cp0_badvaddr = address;
-		tsk->tss.error_code = write;
+		struct siginfo si;
+		tsk->thread.cp0_badvaddr = address;
+		tsk->thread.error_code = write;
 #if 0
 		printk("do_page_fault() #2: sending SIGSEGV to %s for illegal %s\n"
 		       "%08lx (epc == %08lx, ra == %08lx)\n",
@@ -118,7 +121,10 @@
 		       (unsigned long) regs->cp0_epc,
 		       (unsigned long) regs->regs[31]);
 #endif
-		force_sig(SIGSEGV, tsk);
+		si.si_signo = SIGSEGV;
+		si.si_code = si_code;
+		si.si_addr = (void *) address;
+		force_sig_info(SIGSEGV, &si, tsk);
 		return;
 	}
 
@@ -128,7 +134,7 @@
 	if (fixup) {
 		long new_epc;
 
-		tsk->tss.cp0_baduaddr = address;
+		tsk->thread.cp0_baduaddr = address;
 		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
 		if (development_version)
 			printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n",
@@ -144,7 +150,7 @@
 	printk(KERN_ALERT "Unable to handle kernel paging request at virtual "
 	       "address %08lx, epc == %08lx, ra == %08lx\n",
 	       address, regs->cp0_epc, regs->regs[31]);
-	die("Oops", regs, write);
+	die("Oops", regs);
 	do_exit(SIGKILL);
 
 /*
@@ -164,8 +170,8 @@
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
 	 * or user mode.
-	 * XXX Store details about fault for siginfo handling into tss.
 	 */
+	tsk->thread.cp0_badvaddr = address;
 	force_sig(SIGBUS, tsk);
 
 	/* Kernel mode? Handle exceptions or die */
diff -u --recursive --new-file v2.3.47/linux/arch/mips/mm/init.c linux/arch/mips/mm/init.c
--- v2.3.47/linux/arch/mips/mm/init.c	Thu Feb 10 17:11:04 2000
+++ linux/arch/mips/mm/init.c	Thu Feb 24 22:52:30 2000
@@ -1,10 +1,11 @@
-/* $Id: init.c,v 1.13 1999/05/01 22:40:40 ralf Exp $
+/* $Id: init.c,v 1.27 2000/02/23 01:33:56 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 - 1998 by Ralf Baechle
+ * Copyright (C) 1994 - 2000 by Ralf Baechle
+ * Copyright (C) 2000 Silicon Graphics, Inc.
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -18,6 +19,8 @@
 #include <linux/ptrace.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
 #include <linux/swap.h>
 #include <linux/swapctl.h>
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -30,21 +33,28 @@
 #include <asm/jazzdma.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
-#ifdef CONFIG_SGI
+#include <asm/pgalloc.h>
+#ifdef CONFIG_SGI_IP22
 #include <asm/sgialib.h>
 #endif
 #include <asm/mmu_context.h>
 
+static unsigned long totalram_pages = 0;
+
+extern void prom_fixup_mem_map(unsigned long start, unsigned long end);
+extern void prom_free_prom_memory(void);
+
+
 void __bad_pte_kernel(pmd_t *pmd)
 {
 	printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
-	pmd_val(*pmd) = BAD_PAGETABLE;
+	pmd_set(pmd, BAD_PAGETABLE);
 }
 
 void __bad_pte(pmd_t *pmd)
 {
 	printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-	pmd_val(*pmd) = BAD_PAGETABLE;
+	pmd_set(pmd, BAD_PAGETABLE);
 }
 
 pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
@@ -54,11 +64,11 @@
 	page = (pte_t *) __get_free_page(GFP_USER);
 	if (pmd_none(*pmd)) {
 		if (page) {
-			clear_page((unsigned long)page);
+			clear_page(page);
 			pmd_val(*pmd) = (unsigned long)page;
 			return page + offset;
 		}
-		pmd_val(*pmd) = BAD_PAGETABLE;
+		pmd_set(pmd, BAD_PAGETABLE);
 		return NULL;
 	}
 	free_page((unsigned long)page);
@@ -76,11 +86,11 @@
 	page = (pte_t *) __get_free_page(GFP_KERNEL);
 	if (pmd_none(*pmd)) {
 		if (page) {
-			clear_page((unsigned long)page);
+			clear_page(page);
 			pmd_val(*pmd) = (unsigned long)page;
 			return page + offset;
 		}
-		pmd_val(*pmd) = BAD_PAGETABLE;
+		pmd_set(pmd, BAD_PAGETABLE);
 		return NULL;
 	}
 	free_page((unsigned long)page);
@@ -128,9 +138,9 @@
 		panic("Oh boy, that early out of memory?");
 
 	pg = MAP_NR(empty_zero_page);
-	while(pg < MAP_NR(empty_zero_page) + (1 << order)) {
+	while (pg < MAP_NR(empty_zero_page) + (1 << order)) {
 		set_bit(PG_reserved, &mem_map[pg].flags);
-		atomic_set(&mem_map[pg].count, 0);
+		set_page_count(mem_map + pg, 0);
 		pg++;
 	}
 
@@ -138,7 +148,7 @@
 	zero_page_mask = (size - 1) & PAGE_MASK;
 	memset((void *)empty_zero_page, 0, size);
 
-	return size;
+	return 1UL << order;
 }
 
 int do_check_pgt_cache(int low, int high)
@@ -174,43 +184,9 @@
 pte_t * __bad_pagetable(void)
 {
 	extern char empty_bad_page_table[PAGE_SIZE];
-	unsigned long page;
-	unsigned long dummy1, dummy2;
-#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
-	unsigned long dummy3;
-#endif
+	unsigned long page, dummy1, dummy2;
 
 	page = (unsigned long) empty_bad_page_table;
-	/*
-	 * As long as we only save the low 32 bit of the 64 bit wide
-	 * R4000 registers on interrupt we cannot use 64 bit memory accesses
-	 * to the main memory.
-	 */
-#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
-        /*
-         * Use 64bit code even for Linux/MIPS 32bit on R4000
-         */
-	__asm__ __volatile__(
-		".set\tnoreorder\n"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"dsll32\t$1,%2,0\n\t"
-		"dsrl32\t%2,$1,0\n\t"
-		"or\t%2,$1\n"
-		"1:\tsd\t%2,(%0)\n\t"
-		"subu\t%1,1\n\t"
-		"bnez\t%1,1b\n\t"
-		"addiu\t%0,8\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n"
-		".set\treorder"
-		:"=r" (dummy1),
-		 "=r" (dummy2),
-		 "=r" (dummy3)
-		:"0" (page),
-		 "1" (PAGE_SIZE/8),
-		 "2" (pte_val(BAD_PAGE)));
-#else /* (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) */
 	__asm__ __volatile__(
 		".set\tnoreorder\n"
 		"1:\tsw\t%2,(%0)\n\t"
@@ -218,12 +194,9 @@
 		"bnez\t%1,1b\n\t"
 		"addiu\t%0,4\n\t"
 		".set\treorder"
-		:"=r" (dummy1),
-		 "=r" (dummy2)
-		:"r" (pte_val(BAD_PAGE)),
-		 "0" (page),
-		 "1" (PAGE_SIZE/4));
-#endif
+		:"=r" (dummy1), "=r" (dummy2)
+		:"r" (pte_val(BAD_PAGE)), "0" (page), "1" (PAGE_SIZE/4)
+		:"$1");
 
 	return (pte_t *)page;
 }
@@ -231,10 +204,10 @@
 pte_t __bad_page(void)
 {
 	extern char empty_bad_page[PAGE_SIZE];
-	unsigned long page = (unsigned long)empty_bad_page;
+	unsigned long page = (unsigned long) empty_bad_page;
 
-	clear_page(page);
-	return pte_mkdirty(mk_pte(page, PAGE_SHARED));
+	clear_page((void *)page);
+	return pte_mkdirty(mk_pte_phys(__pa(page), PAGE_SHARED));
 }
 
 void show_mem(void)
@@ -252,10 +225,10 @@
 			reserved++;
 		else if (PageSwapCache(mem_map+i))
 			cached++;
-		else if (!atomic_read(&mem_map[i].count))
+		else if (!page_count(mem_map + i))
 			free++;
 		else
-			shared += atomic_read(&mem_map[i].count) - 1;
+			shared += page_count(mem_map + i) - 1;
 	}
 	printk("%d pages of RAM\n", total);
 	printk("%d reserved pages\n", reserved);
@@ -266,79 +239,83 @@
 	show_buffers();
 }
 
-extern unsigned long free_area_init(unsigned long, unsigned long);
+/* References to section boundaries */
 
-unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem)
+extern char _ftext, _etext, _fdata, _edata;
+extern char __init_begin, __init_end;
+
+void __init paging_init(void)
 {
+	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+	unsigned long max_dma, low;
+
 	/* Initialize the entire pgd.  */
 	pgd_init((unsigned long)swapper_pg_dir);
 	pgd_init((unsigned long)swapper_pg_dir + PAGE_SIZE / 2);
-	return free_area_init(start_mem, end_mem);
+
+	max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+	low = max_low_pfn;
+
+	if (low < max_dma)
+		zones_size[ZONE_DMA] = low;
+	else {
+		zones_size[ZONE_DMA] = max_dma;
+		zones_size[ZONE_NORMAL] = low - max_dma;
+	}
+
+	free_area_init(zones_size);
 }
 
-void __init mem_init(unsigned long start_mem, unsigned long end_mem)
+extern int page_is_ram(unsigned long pagenr);
+
+void __init mem_init(void)
 {
-	int codepages = 0;
-	int datapages = 0;
-	unsigned long tmp;
-	extern int _etext, _ftext;
+	unsigned long codesize, reservedpages, datasize, initsize;
+	unsigned long tmp, ram;
 
-#ifdef CONFIG_MIPS_JAZZ
-	if (mips_machgroup == MACH_GROUP_JAZZ)
-		start_mem = vdma_init(start_mem, end_mem);
-#endif
+	max_mapnr = num_physpages = max_low_pfn;
+	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
 
-	end_mem &= PAGE_MASK;
-	max_mapnr = MAP_NR(end_mem);
-	high_memory = (void *)end_mem;
-	num_physpages = 0;
-
-	/* mark usable pages in the mem_map[] */
-	start_mem = PAGE_ALIGN(start_mem);
-
-	for(tmp = MAP_NR(start_mem);tmp < max_mapnr;tmp++)
-		clear_bit(PG_reserved, &mem_map[tmp].flags);
-
-	prom_fixup_mem_map(start_mem, (unsigned long)high_memory);
-
-	for (tmp = PAGE_OFFSET; tmp < end_mem; tmp += PAGE_SIZE) {
-		/*
-		 * This is only for PC-style DMA.  The onboard DMA
-		 * of Jazz and Tyne machines is completely different and
-		 * not handled via a flag in mem_map_t.
-		 */
-		if (tmp >= MAX_DMA_ADDRESS)
-			clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
-		if (PageReserved(mem_map+MAP_NR(tmp))) {
-			if ((tmp < (unsigned long) &_etext) &&
-			    (tmp >= (unsigned long) &_ftext))
-				codepages++;
-			else if ((tmp < start_mem) &&
-				 (tmp > (unsigned long) &_etext))
-				datapages++;
-			continue;
+	totalram_pages += free_all_bootmem();
+	totalram_pages -= setup_zero_pages();	/* Setup zeroed pages.  */
+
+	reservedpages = ram = 0;
+	for (tmp = 0; tmp < max_low_pfn; tmp++)
+		if (page_is_ram(tmp)) {
+			ram++;
+			if (PageReserved(mem_map+tmp))
+				reservedpages++;
 		}
-		num_physpages++;
-		atomic_set(&mem_map[MAP_NR(tmp)].count, 1);
-#ifdef CONFIG_BLK_DEV_INITRD
-		if (!initrd_start || (tmp < initrd_start || tmp >=
-		    initrd_end))
-#endif
-			free_page(tmp);
-	}
-	tmp = nr_free_pages << PAGE_SHIFT;
 
-	/* Setup zeroed pages.  */
-	tmp -= setup_zero_pages();
+	codesize =  (unsigned long) &_etext - (unsigned long) &_ftext;
+	datasize =  (unsigned long) &_edata - (unsigned long) &_fdata;
+	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
+	       "%ldk data, %ldk init)\n",
+	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+	       ram << (PAGE_SHIFT-10),
+	       codesize >> 10,
+	       reservedpages << (PAGE_SHIFT-10),
+	       datasize >> 10,
+	       initsize >> 10);
+}
 
-	printk("Memory: %luk/%luk available (%dk kernel code, %dk data)\n",
-		tmp >> 10,
-		max_mapnr << (PAGE_SHIFT-10),
-		codepages << (PAGE_SHIFT-10),
-		datapages << (PAGE_SHIFT-10));
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(mem_map + MAP_NR(start));
+		set_page_count(mem_map+MAP_NR(start), 1);
+		free_page(start);
+		totalram_pages++;
+	}
+	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
 }
+#endif
 
 extern char __init_begin, __init_end;
+extern void prom_free_prom_memory(void);
 
 void free_initmem(void)
 {
@@ -346,11 +323,13 @@
 
 	prom_free_prom_memory ();
     
-	addr = (unsigned long)(&__init_begin);
-	for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
-		mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
-		atomic_set(&mem_map[MAP_NR(addr)].count, 1);
+	addr = (unsigned long) &__init_begin;
+	while (addr < (unsigned long) &__init_end) {
+		ClearPageReserved(mem_map + MAP_NR(addr));
+		set_page_count(mem_map + MAP_NR(addr), 1);
 		free_page(addr);
+		totalram_pages++;
+		addr += PAGE_SIZE;
 	}
 	printk("Freeing unused kernel memory: %dk freed\n",
 	       (&__init_end - &__init_begin) >> 10);
@@ -358,54 +337,13 @@
 
 void si_meminfo(struct sysinfo *val)
 {
-	int i;
-
-	i = MAP_NR(high_memory);
-	val->totalram = 0;
+	val->totalram = totalram_pages;
 	val->sharedram = 0;
-	val->freeram = nr_free_pages << PAGE_SHIFT;
-	val->bufferram = atomic_read(&buffermem);
-	while (i-- > 0)  {
-		if (PageReserved(mem_map+i))
-			continue;
-		val->totalram++;
-		if (!atomic_read(&mem_map[i].count))
-			continue;
-		val->sharedram += atomic_read(&mem_map[i].count) - 1;
-	}
-	val->totalram <<= PAGE_SHIFT;
-	val->sharedram <<= PAGE_SHIFT;
-	return;
-}
-
-/* Fixup an immediate instruction  */
-static void __init __i_insn_fixup(unsigned int **start, unsigned int **stop,
-                         unsigned int i_const)
-{
-	unsigned int **p, *ip;
-
-	for (p = start;p < stop; p++) {
-		ip = *p;
-		*ip = (*ip & 0xffff0000) | i_const;
-	}
-}
-
-#define i_insn_fixup(section, const)					  \
-do {									  \
-	extern unsigned int *__start_ ## section;			  \
-	extern unsigned int *__stop_ ## section;			  \
-	__i_insn_fixup(&__start_ ## section, &__stop_ ## section, const); \
-} while(0)
+	val->freeram = nr_free_pages();
+	val->bufferram = atomic_read(&buffermem_pages);
+	val->totalhigh = 0;
+	val->freehigh = nr_free_highpages();
+	val->mem_unit = PAGE_SIZE;
 
-/* Caller is assumed to flush the caches before the first context switch.  */
-void __init __asid_setup(unsigned int inc, unsigned int mask,
-                             unsigned int version_mask,
-                             unsigned int first_version)
-{
-	i_insn_fixup(__asid_inc, inc);
-	i_insn_fixup(__asid_mask, mask);
-	i_insn_fixup(__asid_version_mask, version_mask);
-	i_insn_fixup(__asid_first_version, first_version);
-
-	asid_cache = first_version;
+	return;
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/mm/loadmmu.c linux/arch/mips/mm/loadmmu.c
--- v2.3.47/linux/arch/mips/mm/loadmmu.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/mm/loadmmu.c	Thu Feb 24 22:52:30 2000
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: loadmmu.c,v 1.10 1999/06/17 13:25:51 ralf Exp $
+ * $Id: loadmmu.c,v 1.15 2000/02/24 00:12:40 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -17,61 +17,54 @@
 #include <asm/sgialib.h>
 
 /* memory functions */
-void (*clear_page)(unsigned long page);
-void (*copy_page)(unsigned long to, unsigned long from);
+void (*_clear_page)(void * page);
+void (*_copy_page)(void * to, void * from);
 
 /* Cache operations. */
-void (*flush_cache_all)(void);
-void (*flush_cache_mm)(struct mm_struct *mm);
-void (*flush_cache_range)(struct mm_struct *mm, unsigned long start,
+void (*_flush_cache_all)(void);
+void (*_flush_cache_mm)(struct mm_struct *mm);
+void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
 			  unsigned long end);
-void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
-void (*flush_cache_sigtramp)(unsigned long addr);
-void (*flush_page_to_ram)(unsigned long page);
+void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
+void (*_flush_cache_sigtramp)(unsigned long addr);
+void (*_flush_page_to_ram)(struct page * page);
 
 /* DMA cache operations. */
-void (*dma_cache_wback_inv)(unsigned long start, unsigned long size);
-void (*dma_cache_wback)(unsigned long start, unsigned long size);
-void (*dma_cache_inv)(unsigned long start, unsigned long size);
-
-/* TLB operations. */
-void (*flush_tlb_all)(void);
-void (*flush_tlb_mm)(struct mm_struct *mm);
-void (*flush_tlb_range)(struct mm_struct *mm, unsigned long start,
-			unsigned long end);
-void (*flush_tlb_page)(struct vm_area_struct *vma, unsigned long page);
-
-/* Miscellaneous. */
-void (*load_pgd)(unsigned long pg_dir);
-void (*pgd_init)(unsigned long page);
-void (*update_mmu_cache)(struct vm_area_struct * vma,
-			 unsigned long address, pte_t pte);
-
-void (*show_regs)(struct pt_regs *);
-
-void (*add_wired_entry)(unsigned long entrylo0, unsigned long entrylo1,
-			unsigned long entryhi, unsigned long pagemask);
-
-int (*user_mode)(struct pt_regs *);
-
-asmlinkage void *(*resume)(void *last, void *next);
+void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
+void (*_dma_cache_wback)(unsigned long start, unsigned long size);
+void (*_dma_cache_inv)(unsigned long start, unsigned long size);
 
+#ifdef CONFIG_CPU_R3000
 extern void ld_mmu_r2300(void);
+#endif
+#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_R4300) || \
+    defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)
 extern void ld_mmu_r4xx0(void);
+#endif
+#ifdef CONFIG_CPU_R6000
 extern void ld_mmu_r6000(void);
+#endif
+#ifdef CONFIG_CPU_R8000
 extern void ld_mmu_tfp(void);
+#endif
+#ifdef CONFIG_CPU_R10000
 extern void ld_mmu_andes(void);
+#endif
 
 void __init loadmmu(void)
 {
 	switch(mips_cputype) {
+#ifdef CONFIG_CPU_R3000
 	case CPU_R2000:
 	case CPU_R3000:
 	case CPU_R3000A:
 		printk("Loading R[23]00 MMU routines.\n");
 		ld_mmu_r2300();
 		break;
+#endif
 
+#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_R4300) || \
+    defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)
 	case CPU_R4000PC:
 	case CPU_R4000SC:
 	case CPU_R4000MC:
@@ -90,22 +83,14 @@
 		printk("Loading R4000 MMU routines.\n");
 		ld_mmu_r4xx0();
 		break;
+#endif
 
-	case CPU_R6000:
-	case CPU_R6000A:
-		printk("Loading R6000 MMU routines.\n");
-		ld_mmu_r6000();
-		break;
-
-	case CPU_R8000:
-		printk("Loading TFP MMU routines.\n");
-		ld_mmu_tfp();
-		break;
-
+#ifdef CONFIG_CPU_R10000
 	case CPU_R10000:
 		printk("Loading R10000 MMU routines.\n");
 		ld_mmu_andes();
 		break;
+#endif
 
 	default:
 		/* XXX We need an generic routine in the MIPS port
diff -u --recursive --new-file v2.3.47/linux/arch/mips/mm/r2300.c linux/arch/mips/mm/r2300.c
--- v2.3.47/linux/arch/mips/mm/r2300.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/mm/r2300.c	Thu Feb 24 22:52:30 2000
@@ -4,10 +4,10 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
  * with a lot of changes to make this thing work for R3000s
- * Copyright (C) 1998 Harald Koerfgen
+ * Copyright (C) 1998, 2000 Harald Koerfgen
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  *
- * $Id: r2300.c,v 1.8 1999/04/11 17:13:56 harald Exp $
+ * $Id: r2300.c,v 1.15 2000/02/24 00:12:40 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -19,13 +19,9 @@
 #include <asm/mmu_context.h>
 #include <asm/system.h>
 #include <asm/sgialib.h>
-#include <asm/mipsregs.h>
+#include <asm/isadep.h>
 #include <asm/io.h>
-/*
- * Temporarily disabled
- *
 #include <asm/wbflush.h>
- */
 
 /*
  * According to the paper written by D. Miller about Linux cache & TLB
@@ -33,25 +29,18 @@
  * driver layer.  Thus, normally, we don't need flush dcache for R3000.
  * Define this if driver does not handle cache consistency during DMA ops.
  */
-#undef DO_DCACHE_FLUSH
 
-/*
- *  Unified cache space description structure
- */
-static struct cache_space {
-	unsigned long ca_flags;  /* Cache space access flags */
-	int           size;      /* Cache space size */
-} icache, dcache;
+/* Primary cache parameters. */
+static int icache_size, dcache_size; /* Size in bytes */
+/* the linesizes are usually fixed on R3000s */
 
 #undef DEBUG_TLB
 #undef DEBUG_CACHE
 
-extern unsigned long mips_tlb_entries;
-
 #define NTLB_ENTRIES       64  /* Fixed on all R23000 variants... */
 
 /* page functions */
-void r2300_clear_page(unsigned long page)
+void r3k_clear_page(void * page)
 {
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -75,7 +64,7 @@
 		:"$1","memory");
 }
 
-static void r2300_copy_page(unsigned long to, unsigned long from)
+static void r3k_copy_page(void * to, void * from)
 {
 	unsigned long dummy1, dummy2;
 	unsigned long reg1, reg2, reg3, reg4;
@@ -163,278 +152,248 @@
 
 static void __init probe_dcache(void)
 {
-	dcache.size = size_cache(dcache.ca_flags = ST0_DE);
-	printk("Data cache %dkb\n", dcache.size >> 10);
+	dcache_size = size_cache(ST0_DE);
+	printk("Primary data cache %dkb, linesize 4 bytes\n",
+		dcache_size >> 10);
 }
 
 static void __init probe_icache(void)
 {
-	icache.size = size_cache(icache.ca_flags = ST0_DE|ST0_CE);
-	printk("Instruction cache %dkb\n", icache.size >> 10);
+	icache_size = size_cache(ST0_DE|ST0_CE);
+	printk("Primary instruction cache %dkb, linesize 8 bytes\n",
+		icache_size >> 10);
 }
 
-static inline unsigned long get_phys_page (unsigned long page,
-					   struct mm_struct *mm)
+static void r3k_flush_icache_range(unsigned long start, unsigned long size)
 {
-        page &= PAGE_MASK;
-	if (page >= KSEG0 && page < KSEG1) {
-		/*
-		 *  We already have physical address
-		 */
-		return page;
-	} else {
-		if (!mm) {
-			printk ("get_phys_page: vaddr without mm\n");
-			return 0;
-		} else {
-			/* 
-			 *  Find a physical page using mm_struct
-			 */
-			pgd_t *page_dir;
-			pmd_t *page_middle;
-			pte_t *page_table, pte;
-
-			unsigned long address = page;
-
-			page_dir = pgd_offset(mm, address);
-			if (pgd_none(*page_dir))
-				return 0; 
-			page_middle = pmd_offset(page_dir, address);
-			if (pmd_none(*page_middle))
-				return 0; 
-			page_table = pte_offset(page_middle, address);
-			pte = *page_table;
-			if (!pte_present(pte))
-				return 0; 
-			return pte_page(pte);
-	}
+	unsigned long i, flags;
+	volatile unsigned char *p = (char *)start;
+
+	if (size > icache_size)
+		size = icache_size;
+
+	save_and_cli(flags);
+
+	/* isolate cache space */
+	write_32bit_cp0_register(CP0_STATUS, (ST0_DE|ST0_CE|flags)&~ST0_IEC);
+
+	for (i = 0; i < size; i += 0x100) {
+		asm ( 	"sb\t$0,0x000(%0)\n\t"
+			"sb\t$0,0x008(%0)\n\t"
+			"sb\t$0,0x010(%0)\n\t"
+			"sb\t$0,0x018(%0)\n\t"
+			"sb\t$0,0x020(%0)\n\t"
+			"sb\t$0,0x028(%0)\n\t"
+			"sb\t$0,0x030(%0)\n\t"
+			"sb\t$0,0x038(%0)\n\t"
+		 	"sb\t$0,0x040(%0)\n\t"
+			"sb\t$0,0x048(%0)\n\t"
+			"sb\t$0,0x050(%0)\n\t"
+			"sb\t$0,0x058(%0)\n\t"
+			"sb\t$0,0x060(%0)\n\t"
+			"sb\t$0,0x068(%0)\n\t"
+			"sb\t$0,0x070(%0)\n\t"
+			"sb\t$0,0x078(%0)\n\t"
+			"sb\t$0,0x080(%0)\n\t"
+			"sb\t$0,0x088(%0)\n\t"
+			"sb\t$0,0x090(%0)\n\t"
+			"sb\t$0,0x098(%0)\n\t"
+			"sb\t$0,0x0a0(%0)\n\t"
+			"sb\t$0,0x0a8(%0)\n\t"
+			"sb\t$0,0x0b0(%0)\n\t"
+			"sb\t$0,0x0b8(%0)\n\t"
+		 	"sb\t$0,0x0c0(%0)\n\t"
+			"sb\t$0,0x0c8(%0)\n\t"
+			"sb\t$0,0x0d0(%0)\n\t"
+			"sb\t$0,0x0d8(%0)\n\t"
+			"sb\t$0,0x0e0(%0)\n\t"
+			"sb\t$0,0x0e8(%0)\n\t"
+			"sb\t$0,0x0f0(%0)\n\t"
+			"sb\t$0,0x0f8(%0)\n\t"
+			: : "r" (p) );
+		p += 0x100;
 	}
+
+	restore_flags(flags);
 }
 
-static inline void flush_cache_space_page(struct cache_space *space,
-					  unsigned long page)
+static void r3k_flush_dcache_range(unsigned long start, unsigned long size)
 {
-	register unsigned long i, flags, size = space->size;
-	register volatile unsigned char *p = (volatile unsigned char*) page;
+	unsigned long i, flags;
+	volatile unsigned char *p = (char *)start;
 
-#ifndef DO_DCACHE_FLUSH
-	if (space == &dcache)
-		return;
-#endif
-	if (size > PAGE_SIZE)
-		size = PAGE_SIZE;
+	if (size > icache_size)
+		size = icache_size;
 
 	save_and_cli(flags);
 
 	/* isolate cache space */
-	write_32bit_cp0_register(CP0_STATUS, (space->ca_flags|flags)&~ST0_IEC);
+	write_32bit_cp0_register(CP0_STATUS, (ST0_DE|flags)&~ST0_IEC);
 
-	for (i = 0; i < size; i += 64) {
-		asm ( 	"sb\t$0,(%0)\n\t"
-			"sb\t$0,4(%0)\n\t"
-			"sb\t$0,8(%0)\n\t"
-			"sb\t$0,12(%0)\n\t"
-			"sb\t$0,16(%0)\n\t"
-			"sb\t$0,20(%0)\n\t"
-			"sb\t$0,24(%0)\n\t"
-			"sb\t$0,28(%0)\n\t"
- 		        "sb\t$0,32(%0)\n\t"
- 			"sb\t$0,36(%0)\n\t"
- 			"sb\t$0,40(%0)\n\t"
- 			"sb\t$0,44(%0)\n\t"
- 			"sb\t$0,48(%0)\n\t"
- 			"sb\t$0,52(%0)\n\t"
- 			"sb\t$0,56(%0)\n\t"
- 			"sb\t$0,60(%0)\n\t"
+	for (i = 0; i < size; i += 0x080) {
+		asm ( 	"sb\t$0,0x000(%0)\n\t"
+			"sb\t$0,0x004(%0)\n\t"
+			"sb\t$0,0x008(%0)\n\t"
+			"sb\t$0,0x00c(%0)\n\t"
+		 	"sb\t$0,0x010(%0)\n\t"
+			"sb\t$0,0x014(%0)\n\t"
+			"sb\t$0,0x018(%0)\n\t"
+			"sb\t$0,0x01c(%0)\n\t"
+		 	"sb\t$0,0x020(%0)\n\t"
+			"sb\t$0,0x024(%0)\n\t"
+			"sb\t$0,0x028(%0)\n\t"
+			"sb\t$0,0x02c(%0)\n\t"
+		 	"sb\t$0,0x030(%0)\n\t"
+			"sb\t$0,0x034(%0)\n\t"
+			"sb\t$0,0x038(%0)\n\t"
+			"sb\t$0,0x03c(%0)\n\t"
+		 	"sb\t$0,0x040(%0)\n\t"
+			"sb\t$0,0x044(%0)\n\t"
+			"sb\t$0,0x048(%0)\n\t"
+			"sb\t$0,0x04c(%0)\n\t"
+		 	"sb\t$0,0x050(%0)\n\t"
+			"sb\t$0,0x054(%0)\n\t"
+			"sb\t$0,0x058(%0)\n\t"
+			"sb\t$0,0x05c(%0)\n\t"
+		 	"sb\t$0,0x060(%0)\n\t"
+			"sb\t$0,0x064(%0)\n\t"
+			"sb\t$0,0x068(%0)\n\t"
+			"sb\t$0,0x06c(%0)\n\t"
+		 	"sb\t$0,0x070(%0)\n\t"
+			"sb\t$0,0x074(%0)\n\t"
+			"sb\t$0,0x078(%0)\n\t"
+			"sb\t$0,0x07c(%0)\n\t"
 			: : "r" (p) );
-		p += 64;
+		p += 0x080;
 	}
 
 	restore_flags(flags);
 }
 
-static inline void flush_cache_space_all(struct cache_space *space)
+static inline unsigned long get_phys_page (unsigned long addr,
+					   struct mm_struct *mm)
 {
-	unsigned long page = KSEG0;
-	int size = space->size;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	unsigned long physpage;
 
-#ifndef DO_DCACHE_FLUSH
-	if (space == &dcache)
-		return;
-#endif
-	while(size > 0) { 
-		flush_cache_space_page(space, page);
-		page += PAGE_SIZE; size -= PAGE_SIZE;
-        }
+	pgd = pgd_offset(mm, addr);
+	pmd = pmd_offset(pgd, addr);
+	pte = pte_offset(pmd, addr);
+
+	if((physpage = pte_val(*pte)) & _PAGE_VALID)
+		return KSEG1ADDR(physpage & PAGE_MASK);
+	else
+		return 0;
 }
 
-static inline void r2300_flush_cache_all(void)
+static inline void r3k_flush_cache_all(void)
 {
-	flush_cache_space_all(&dcache);
-	flush_cache_space_all(&icache);
+	r3k_flush_icache_range(KSEG0, icache_size);
 }
  
-static void r2300_flush_cache_mm(struct mm_struct *mm)
+static void r3k_flush_cache_mm(struct mm_struct *mm)
 {
-	if(mm->context == 0) 
-		return;
+	if(mm->context != 0) {
+
 #ifdef DEBUG_CACHE
 		printk("cmm[%d]", (int)mm->context);
 #endif
-	/*
-	 *  This function is called not offen, so it looks
-	 *  enough good to flush all caches than scan mm_struct,
-	 *  count pages to flush (and, very probably, flush more
-	 *  than cache space size :-)
- */
-	flush_cache_all();
+		r3k_flush_cache_all();
+	}
 }
 
-static void r2300_flush_cache_range(struct mm_struct *mm,
+static void r3k_flush_cache_range(struct mm_struct *mm,
 				    unsigned long start,
 				    unsigned long end)
 {
-	/*
-	 *  In general, we need to flush both i- & d- caches here.
-	 *  Optimization: if cache space is less than given range,
-	 *  it is more quickly to flush all cache than all pages in range.
-	 */
-
-	unsigned long page;
-	int icache_done = 0, dcache_done = 0;
+	struct vm_area_struct *vma;
 
 	if(mm->context == 0) 
 		return;
+
+	start &= PAGE_MASK;
 #ifdef DEBUG_CACHE
-	printk("crange[%d]", (int)mm->context);
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
-	if (end - start >= icache.size) {
-		flush_cache_space_all(&icache);
-		icache_done = 1;
-	}
-	if (end - start >= dcache.size) {
-		flush_cache_space_all(&dcache);
-		dcache_done = 1;
-	}
-	if (icache_done && dcache_done)
-		return;
+	vma = find_vma(mm, start);
+	if(vma) {
+		if(mm->context != current->mm->context) {
+			flush_cache_all();
+		} else {
+			unsigned long flags, physpage;
 
-	for (page = start; page < end; page += PAGE_SIZE) {
-		unsigned long phys_page = get_phys_page(page, mm);
+			save_and_cli(flags);
+			while(start < end) {
+				if((physpage = get_phys_page(start, mm)))
+					r3k_flush_icache_range(physpage, PAGE_SIZE);
 		
-		if (phys_page) {
-			if (!icache_done) 
-				flush_cache_space_page(&icache, phys_page);
-			if (!dcache_done) 
-				flush_cache_space_page(&dcache, phys_page);
+				start += PAGE_SIZE;
+			}
+			restore_flags(flags);
 		}
 	}
 }
 
-static void r2300_flush_cache_page(struct vm_area_struct *vma,
+static void r3k_flush_cache_page(struct vm_area_struct *vma,
 				   unsigned long page)
 {
 	struct mm_struct *mm = vma->vm_mm;
 
 	if(mm->context == 0)
 		return;
+
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	/*
-	 *  User changes page, so we need to check:
-         *     is icache page flush needed ?
-	 *  It looks we don't need to flush dcache,
-	 *  due it is write-transparent on R3000
-	 */
 	if (vma->vm_flags & VM_EXEC) {
-		unsigned long phys_page = get_phys_page(page, vma->vm_mm);
-		if (phys_page)
-			flush_cache_space_page(&icache, phys_page); 
+		unsigned long physpage;
+
+		if((physpage = get_phys_page(page, vma->vm_mm)))
+			r3k_flush_icache_range(physpage, PAGE_SIZE);
+
 	}
 }
 
-static void r2300_flush_page_to_ram(unsigned long page)
+static void r3k_flush_page_to_ram(struct page * page)
 {
 	/*
-	 *  We need to flush both i- & d- caches :-(
+	 * Nothing to be done
 	 */
-	unsigned long phys_page = get_phys_page(page, NULL);
-#ifdef DEBUG_CACHE
-	printk("cram[%08lx]", page);
-#endif
-	if (phys_page) {
-		flush_cache_space_page(&icache, phys_page);
-		flush_cache_space_page(&dcache, phys_page);
-	}
 }
 
-static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
+static void r3k_flush_cache_sigtramp(unsigned long addr)
 {
-	register unsigned long i, flags;
-	register volatile unsigned char *p = (volatile unsigned char*) start;
-
-/*
- * Temporarily disabled
-	wbflush();
-	 */
+	unsigned long flags;
 
+#ifdef DEBUG_CACHE
+	printk("csigtramp[%08lx]", addr);
+#endif
 	/*
-	 * Invalidate dcache
+	 * I am assuming an 8 Byte cacheline here. HK
 	 */
-	if (size < 64)
-		size = 64;
-
-	if (size > dcache.size)
-		size = dcache.size;
+	addr &= ~7;
 
 	save_and_cli(flags);
 
-	/* isolate cache space */
-	write_32bit_cp0_register(CP0_STATUS, (ST0_DE|flags)&~ST0_IEC);
+	write_32bit_cp0_register(CP0_STATUS, (ST0_DE|ST0_CE|flags)&~ST0_IEC);
 
-	for (i = 0; i < size; i += 64) {
-		asm ( 	"sb\t$0,(%0)\n\t"
-			"sb\t$0,4(%0)\n\t"
-			"sb\t$0,8(%0)\n\t"
-			"sb\t$0,12(%0)\n\t"
-			"sb\t$0,16(%0)\n\t"
-			"sb\t$0,20(%0)\n\t"
-			"sb\t$0,24(%0)\n\t"
-			"sb\t$0,28(%0)\n\t"
- 		        "sb\t$0,32(%0)\n\t"
- 			"sb\t$0,36(%0)\n\t"
- 			"sb\t$0,40(%0)\n\t"
- 			"sb\t$0,44(%0)\n\t"
- 			"sb\t$0,48(%0)\n\t"
- 			"sb\t$0,52(%0)\n\t"
- 			"sb\t$0,56(%0)\n\t"
- 			"sb\t$0,60(%0)\n\t"
-			: : "r" (p) );
-		p += 64;
-	}
+	asm ( 	"sb\t$0,0x000(%0)\n\t"
+		"sb\t$0,0x008(%0)\n\t"
+		: : "r" (addr) );
 
 	restore_flags(flags);
 }
 
-static void r2300_flush_cache_sigtramp(unsigned long page)
+static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
 {
-	/*
-	 *  We need only flush i-cache here
-	 *
-	 *  This function receives virtual address (from signal.c),
-	 *  but this moment we have needed mm_struct in 'current'
-	 */
-	unsigned long phys_page = get_phys_page(page, current->mm);
-#ifdef DEBUG_CACHE
-		printk("csigtramp[%08lx]", page);
-#endif
-	if (phys_page)
-		flush_cache_space_page(&icache, phys_page);  
+	wbflush();
+	r3k_flush_dcache_range(start, size);
 }
 
 /* TLB operations. */
-static inline void r2300_flush_tlb_all(void)
+void flush_tlb_all(void)
 {
 	unsigned long flags;
 	unsigned long old_ctx;
@@ -456,7 +415,7 @@
 	restore_flags(flags);
 }
 
-static void r2300_flush_tlb_mm(struct mm_struct *mm)
+void flush_tlb_mm(struct mm_struct *mm)
 {
 	if(mm->context != 0) {
 		unsigned long flags;
@@ -466,16 +425,16 @@
 #endif
 		save_and_cli(flags);
 		get_new_mmu_context(mm, asid_cache);
-	if(mm == current->mm)
+		if (mm == current->active_mm)
 			set_entryhi(mm->context & 0xfc0);
 		restore_flags(flags);
 	}
 }
 
-static void r2300_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+void flush_tlb_range(struct mm_struct *mm, unsigned long start,
 				  unsigned long end)
 {
-	if(mm->context != 0) {
+	if (mm->context != 0) {
 		unsigned long flags;
 		int size;
 
@@ -508,14 +467,14 @@
 			set_entryhi(oldpid);
 		} else {
 			get_new_mmu_context(mm, asid_cache);
-	if(mm == current->mm)
+			if (mm == current->active_mm)
 				set_entryhi(mm->context & 0xfc0);
 		}
 		restore_flags(flags);
 	}
 }
 
-static void r2300_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
 	if(vma->vm_mm->context != 0) {
 		unsigned long flags;
@@ -543,15 +502,10 @@
 	}
 }
 
-/* Load a new root pointer into the TLB. */
-static void r2300_load_pgd(unsigned long pg_dir)
-{
-}
-
 /*
  * Initialize new page directory with pointers to invalid ptes
  */
-static void r2300_pgd_init(unsigned long page)
+void pgd_init(unsigned long page)
 {
 	unsigned long dummy1, dummy2;
 
@@ -580,7 +534,7 @@
 		 "1" (PAGE_SIZE/(sizeof(pmd_t)*8)));
 }
 
-static void r2300_update_mmu_cache(struct vm_area_struct * vma,
+void update_mmu_cache(struct vm_area_struct * vma,
 				   unsigned long address, pte_t pte)
 {
 	unsigned long flags;
@@ -636,7 +590,7 @@
 	restore_flags(flags);
 }
 
-static void r2300_show_regs(struct pt_regs * regs)
+void show_regs(struct pt_regs * regs)
 {
 	/*
 	 * Saved main processor registers
@@ -669,54 +623,33 @@
 	       (unsigned int) regs->cp0_cause);
 }
 
-static void r2300_add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
 				  unsigned long entryhi, unsigned long pagemask)
 {
-printk("r2300_add_wired_entry");
+printk("r3k_add_wired_entry");
         /*
 	 * FIXME, to be done
 	 */
 }
 
-static int r2300_user_mode(struct pt_regs *regs)
-{
-	return !(regs->cp0_status & ST0_KUP);
-}
-
 void __init ld_mmu_r2300(void)
 {
 	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
 
-	clear_page = r2300_clear_page;
-	copy_page = r2300_copy_page;
+	_clear_page = r3k_clear_page;
+	_copy_page = r3k_copy_page;
 
 	probe_icache();
 	probe_dcache();
 
-	flush_cache_all = r2300_flush_cache_all;
-	flush_cache_mm = r2300_flush_cache_mm;
-	flush_cache_range = r2300_flush_cache_range;
-	flush_cache_page = r2300_flush_cache_page;
-	flush_cache_sigtramp = r2300_flush_cache_sigtramp;
-	flush_page_to_ram = r2300_flush_page_to_ram;
-
-	flush_tlb_all = r2300_flush_tlb_all;
-	flush_tlb_mm = r2300_flush_tlb_mm;
-	flush_tlb_range = r2300_flush_tlb_range;
-	flush_tlb_page = r2300_flush_tlb_page;
-
-        dma_cache_wback_inv = r3k_dma_cache_wback_inv;
-
-	load_pgd = r2300_load_pgd;
-	pgd_init = r2300_pgd_init;
-	update_mmu_cache = r2300_update_mmu_cache;
-	r3000_asid_setup();
-
-	show_regs = r2300_show_regs;
-    
-        add_wired_entry = r2300_add_wired_entry;
+	_flush_cache_all = r3k_flush_cache_all;
+	_flush_cache_mm = r3k_flush_cache_mm;
+	_flush_cache_range = r3k_flush_cache_range;
+	_flush_cache_page = r3k_flush_cache_page;
+	_flush_cache_sigtramp = r3k_flush_cache_sigtramp;
+	_flush_page_to_ram = r3k_flush_page_to_ram;
 
-	user_mode = r2300_user_mode;
+        _dma_cache_wback_inv = r3k_dma_cache_wback_inv;
 
 	flush_tlb_all();
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/mm/r4xx0.c linux/arch/mips/mm/r4xx0.c
--- v2.3.47/linux/arch/mips/mm/r4xx0.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/mm/r4xx0.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: r4xx0.c,v 1.22 1999/06/17 13:25:51 ralf Exp $
+/* $Id: r4xx0.c,v 1.30 2000/02/24 01:12:37 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -22,13 +22,10 @@
 
 #include <asm/bcache.h>
 #include <asm/io.h>
-#include <asm/sgi.h>
-#include <asm/sgimc.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/bootinfo.h>
-#include <asm/sgialib.h>
 #include <asm/mmu_context.h>
 
 /* CP0 hazard avoidance. */
@@ -81,7 +78,7 @@
  *   versions of R4000 and R4400.
  */
 
-static void r4k_clear_page_d16(unsigned long page)
+static void r4k_clear_page_d16(void * page)
 {
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -112,7 +109,7 @@
 		:"$1","memory");
 }
 
-static void r4k_clear_page_d32(unsigned long page)
+static void r4k_clear_page_d32(void * page)
 {
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -169,7 +166,7 @@
  *                              nop
  *                              cache       Hit_Writeback_Invalidate_D
  */
-static void r4k_clear_page_r4600_v1(unsigned long page)
+static void r4k_clear_page_r4600_v1(void * page)
 {
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -208,7 +205,7 @@
 /*
  * And this one is for the R4600 V2.0
  */
-static void r4k_clear_page_r4600_v2(unsigned long page)
+static void r4k_clear_page_r4600_v2(void * page)
 {
 	unsigned int flags;
 
@@ -251,7 +248,7 @@
  * this the kernel crashed shortly after mounting the root filesystem.  CPU
  * bug?  Weirdo cache instruction semantics?
  */
-static void r4k_clear_page_s16(unsigned long page)
+static void r4k_clear_page_s16(void * page)
 {
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -282,7 +279,7 @@
 		:"$1","memory");
 }
 
-static void r4k_clear_page_s32(unsigned long page)
+static void r4k_clear_page_s32(void * page)
 {
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -311,7 +308,7 @@
 		:"$1","memory");
 }
 
-static void r4k_clear_page_s64(unsigned long page)
+static void r4k_clear_page_s64(void * page)
 {
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -339,7 +336,7 @@
 		:"$1","memory");
 }
 
-static void r4k_clear_page_s128(unsigned long page)
+static void r4k_clear_page_s128(void * page)
 {
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -381,7 +378,7 @@
  * virtual address where the copy will be accessed.
  */
 
-static void r4k_copy_page_d16(unsigned long to, unsigned long from)
+static void r4k_copy_page_d16(void * to, void * from)
 {
 	unsigned long dummy1, dummy2;
 	unsigned long reg1, reg2, reg3, reg4;
@@ -440,7 +437,7 @@
 		 "i" (Create_Dirty_Excl_D));
 }
 
-static void r4k_copy_page_d32(unsigned long to, unsigned long from)
+static void r4k_copy_page_d32(void * to, void * from)
 {
 	unsigned long dummy1, dummy2;
 	unsigned long reg1, reg2, reg3, reg4;
@@ -500,7 +497,7 @@
 /*
  * Again a special version for the R4600 V1.x
  */
-static void r4k_copy_page_r4600_v1(unsigned long to, unsigned long from)
+static void r4k_copy_page_r4600_v1(void * to, void * from)
 {
 	unsigned long dummy1, dummy2;
 	unsigned long reg1, reg2, reg3, reg4;
@@ -565,7 +562,7 @@
 		 "i" (Create_Dirty_Excl_D));
 }
 
-static void r4k_copy_page_r4600_v2(unsigned long to, unsigned long from)
+static void r4k_copy_page_r4600_v2(void * to, void * from)
 {
 	unsigned long dummy1, dummy2;
 	unsigned long reg1, reg2, reg3, reg4;
@@ -636,7 +633,7 @@
 /*
  * These are for R4000SC / R4400MC
  */
-static void r4k_copy_page_s16(unsigned long to, unsigned long from)
+static void r4k_copy_page_s16(void * to, void * from)
 {
 	unsigned long dummy1, dummy2;
 	unsigned long reg1, reg2, reg3, reg4;
@@ -695,7 +692,7 @@
 		 "i" (Create_Dirty_Excl_SD));
 }
 
-static void r4k_copy_page_s32(unsigned long to, unsigned long from)
+static void r4k_copy_page_s32(void * to, void * from)
 {
 	unsigned long dummy1, dummy2;
 	unsigned long reg1, reg2, reg3, reg4;
@@ -752,7 +749,7 @@
 		 "i" (Create_Dirty_Excl_SD));
 }
 
-static void r4k_copy_page_s64(unsigned long to, unsigned long from)
+static void r4k_copy_page_s64(void * to, void * from)
 {
 	unsigned long dummy1, dummy2;
 	unsigned long reg1, reg2, reg3, reg4;
@@ -808,7 +805,7 @@
 		 "i" (Create_Dirty_Excl_SD));
 }
 
-static void r4k_copy_page_s128(unsigned long to, unsigned long from)
+static void r4k_copy_page_s128(void * to, void * from)
 {
 	unsigned long dummy1, dummy2;
 	unsigned long reg1, reg2, reg3, reg4;
@@ -1742,7 +1739,7 @@
 	 * If ownes no valid ASID yet, cannot possibly have gotten
 	 * this page into the cache.
 	 */
-	if(mm->context == 0)
+	if (mm->context == 0)
 		return;
 
 #ifdef DEBUG_CACHE
@@ -1926,7 +1923,7 @@
 	 * If the page isn't marked valid, the page cannot possibly be
 	 * in the cache.
 	 */
-	if(!(pte_val(*ptep) & _PAGE_PRESENT))
+	if (!(pte_val(*ptep) & _PAGE_PRESENT))
 		goto out;
 
 	text = (vma->vm_flags & VM_EXEC);
@@ -1936,7 +1933,7 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+	if((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
 		blast_dcache32_page(page);
 		if(text)
 			blast_icache32_page(page);
@@ -1965,110 +1962,119 @@
  *    flush.
  * 3) In KSEG1, no flush necessary.
  */
-static void r4k_flush_page_to_ram_s16d16i16(unsigned long page)
+static void r4k_flush_page_to_ram_s16d16i16(struct page * page)
 {
-	page &= PAGE_MASK;
-	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
 #ifdef DEBUG_CACHE
-		printk("cram[%08lx]", page);
+		printk("cram[%08lx]", addr);
 #endif
-		blast_scache16_page(page);
+		blast_scache16_page(addr);
 	}
 }
 
-static void r4k_flush_page_to_ram_s32d16i16(unsigned long page)
+static void r4k_flush_page_to_ram_s32d16i16(struct page * page)
 {
-	page &= PAGE_MASK;
-	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
 #ifdef DEBUG_CACHE
-		printk("cram[%08lx]", page);
+		printk("cram[%08lx]", addr);
 #endif
-		blast_scache32_page(page);
+		blast_scache32_page(addr);
 	}
 }
 
-static void r4k_flush_page_to_ram_s64d16i16(unsigned long page)
+static void r4k_flush_page_to_ram_s64d16i16(struct page * page)
 {
-	page &= PAGE_MASK;
-	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
 #ifdef DEBUG_CACHE
-		printk("cram[%08lx]", page);
+		printk("cram[%08lx]", addr);
 #endif
-		blast_scache64_page(page);
+		blast_scache64_page(addr);
 	}
 }
 
-static void r4k_flush_page_to_ram_s128d16i16(unsigned long page)
+static void r4k_flush_page_to_ram_s128d16i16(struct page * page)
 {
-	page &= PAGE_MASK;
-	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
 #ifdef DEBUG_CACHE
-		printk("cram[%08lx]", page);
+		printk("cram[%08lx]", addr);
 #endif
-		blast_scache128_page(page);
+		blast_scache128_page(addr);
 	}
 }
 
-static void r4k_flush_page_to_ram_s32d32i32(unsigned long page)
+static void r4k_flush_page_to_ram_s32d32i32(struct page * page)
 {
-	page &= PAGE_MASK;
-	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
 #ifdef DEBUG_CACHE
-		printk("cram[%08lx]", page);
+		printk("cram[%08lx]", addr);
 #endif
-		blast_scache32_page(page);
+		blast_scache32_page(addr);
 	}
 }
 
-static void r4k_flush_page_to_ram_s64d32i32(unsigned long page)
+static void r4k_flush_page_to_ram_s64d32i32(struct page * page)
 {
-	page &= PAGE_MASK;
-	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
 #ifdef DEBUG_CACHE
-		printk("cram[%08lx]", page);
+		printk("cram[%08lx]", addr);
 #endif
-		blast_scache64_page(page);
+		blast_scache64_page(addr);
 	}
 }
 
-static void r4k_flush_page_to_ram_s128d32i32(unsigned long page)
+static void r4k_flush_page_to_ram_s128d32i32(struct page * page)
 {
-	page &= PAGE_MASK;
-	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
 #ifdef DEBUG_CACHE
-		printk("cram[%08lx]", page);
+		printk("cram[%08lx]", addr);
 #endif
-		blast_scache128_page(page);
+		blast_scache128_page(addr);
 	}
 }
 
-static void r4k_flush_page_to_ram_d16i16(unsigned long page)
+static void r4k_flush_page_to_ram_d16i16(struct page * page)
 {
-	page &= PAGE_MASK;
-	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
 		unsigned long flags;
 
 #ifdef DEBUG_CACHE
-		printk("cram[%08lx]", page);
+		printk("cram[%08lx]", addr);
 #endif
-		save_and_cli(flags);
-		blast_dcache16_page(page);
-		restore_flags(flags);
+		__save_and_cli(flags);
+		blast_dcache16_page(addr);
+		__restore_flags(flags);
 	}
 }
 
-static void r4k_flush_page_to_ram_d32i32(unsigned long page)
+static void r4k_flush_page_to_ram_d32i32(struct page * page)
 {
-	page &= PAGE_MASK;
-	if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
 		unsigned long flags;
 
 #ifdef DEBUG_CACHE
-		printk("cram[%08lx]", page);
+		printk("cram[%08lx]", addr);
 #endif
-		save_and_cli(flags);
-		blast_dcache32_page(page);
-		restore_flags(flags);
+		__save_and_cli(flags);
+		blast_dcache32_page(addr);
+		__restore_flags(flags);
 	}
 }
 
@@ -2202,7 +2208,7 @@
 	unsigned int flags;
 
 	daddr = addr & ~(dc_lsize - 1);
-	save_and_cli(flags);
+	__save_and_cli(flags);
 
 	/* Clear internal cache refill buffer */
 	*(volatile unsigned int *)KSEG1;
@@ -2212,7 +2218,7 @@
 	iaddr = addr & ~(ic_lsize - 1);
 	protected_flush_icache_line(iaddr);
 	protected_flush_icache_line(iaddr + ic_lsize);
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 #undef DEBUG_TLB
@@ -2222,7 +2228,7 @@
 
 #define NTLB_ENTRIES_HALF  24  /* Fixed on all R4XX0 variants... */
 
-static inline void r4k_flush_tlb_all(void)
+void flush_tlb_all(void)
 {
 	unsigned long flags;
 	unsigned long old_ctx;
@@ -2255,7 +2261,7 @@
 	restore_flags(flags);
 }
 
-static void r4k_flush_tlb_mm(struct mm_struct *mm)
+void flush_tlb_mm(struct mm_struct *mm)
 {
 	if(mm->context != 0) {
 		unsigned long flags;
@@ -2271,7 +2277,7 @@
 	}
 }
 
-static void r4k_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+void flush_tlb_range(struct mm_struct *mm, unsigned long start,
 				unsigned long end)
 {
 	if(mm->context != 0) {
@@ -2320,7 +2326,7 @@
 	}
 }
 
-static void r4k_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
 	if(vma->vm_mm->context != 0) {
 		unsigned long flags;
@@ -2354,11 +2360,11 @@
 }
 
 /* Load a new root pointer into the TLB. */
-static void r4k_load_pgd(unsigned long pg_dir)
+void load_pgd(unsigned long pg_dir)
 {
 }
 
-static void r4k_pgd_init(unsigned long page)
+void pgd_init(unsigned long page)
 {
 	unsigned long *p = (unsigned long *) page;
 	int i;
@@ -2385,7 +2391,7 @@
  * updates the TLB with the new pte(s), and another which also checks
  * for the R4k "end of page" hardware bug and does the needy.
  */
-static void r4k_update_mmu_cache(struct vm_area_struct * vma,
+void update_mmu_cache(struct vm_area_struct * vma,
 				 unsigned long address, pte_t pte)
 {
 	unsigned long flags;
@@ -2394,7 +2400,7 @@
 	pte_t *ptep;
 	int idx, pid;
 
-	pid = (get_entryhi() & 0xff);
+	pid = get_entryhi() & 0xff;
 
 #ifdef DEBUG_TLB
 	if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
@@ -2459,7 +2465,7 @@
 }
 #endif
 
-static void r4k_show_regs(struct pt_regs * regs)
+void show_regs(struct pt_regs * regs)
 {
 	/* Saved main processor registers. */
 	printk("$0 : %08lx %08lx %08lx %08lx\n",
@@ -2484,7 +2490,7 @@
 	       regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
 }
 			
-static void r4k_add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
 				      unsigned long entryhi, unsigned long pagemask)
 {
         unsigned long flags;
@@ -2630,36 +2636,36 @@
 
 	switch(dc_lsize) {
 	case 16:
-		clear_page = r4k_clear_page_d16;
-		copy_page = r4k_copy_page_d16;
-		flush_cache_all = r4k_flush_cache_all_d16i16;
-		flush_cache_mm = r4k_flush_cache_mm_d16i16;
-		flush_cache_range = r4k_flush_cache_range_d16i16;
-		flush_cache_page = r4k_flush_cache_page_d16i16;
-		flush_page_to_ram = r4k_flush_page_to_ram_d16i16;
+		_clear_page = r4k_clear_page_d16;
+		_copy_page = r4k_copy_page_d16;
+		_flush_cache_all = r4k_flush_cache_all_d16i16;
+		_flush_cache_mm = r4k_flush_cache_mm_d16i16;
+		_flush_cache_range = r4k_flush_cache_range_d16i16;
+		_flush_cache_page = r4k_flush_cache_page_d16i16;
+		_flush_page_to_ram = r4k_flush_page_to_ram_d16i16;
 		break;
 	case 32:
 		prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0;
 		if (prid == 0x2010) {			/* R4600 V1.7 */
-			clear_page = r4k_clear_page_r4600_v1;
-			copy_page = r4k_copy_page_r4600_v1;
+			_clear_page = r4k_clear_page_r4600_v1;
+			_copy_page = r4k_copy_page_r4600_v1;
 		} else if (prid == 0x2020) {		/* R4600 V2.0 */
-			clear_page = r4k_clear_page_r4600_v2;
-			copy_page = r4k_copy_page_r4600_v2;
+			_clear_page = r4k_clear_page_r4600_v2;
+			_copy_page = r4k_copy_page_r4600_v2;
 		} else {
-			clear_page = r4k_clear_page_d32;
-			copy_page = r4k_copy_page_d32;
+			_clear_page = r4k_clear_page_d32;
+			_copy_page = r4k_copy_page_d32;
 		}
-		flush_cache_all = r4k_flush_cache_all_d32i32;
-		flush_cache_mm = r4k_flush_cache_mm_d32i32;
-		flush_cache_range = r4k_flush_cache_range_d32i32;
-		flush_cache_page = r4k_flush_cache_page_d32i32;
-		flush_page_to_ram = r4k_flush_page_to_ram_d32i32;
+		_flush_cache_all = r4k_flush_cache_all_d32i32;
+		_flush_cache_mm = r4k_flush_cache_mm_d32i32;
+		_flush_cache_range = r4k_flush_cache_range_d32i32;
+		_flush_cache_page = r4k_flush_cache_page_d32i32;
+		_flush_page_to_ram = r4k_flush_page_to_ram_d32i32;
 		break;
 	}
-	dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc;
-	dma_cache_wback = r4k_dma_cache_wback;
-	dma_cache_inv = r4k_dma_cache_inv_pc;
+	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc;
+	_dma_cache_wback = r4k_dma_cache_wback;
+	_dma_cache_inv = r4k_dma_cache_inv_pc;
 }
 
 static void __init setup_scache_funcs(void)
@@ -2668,82 +2674,82 @@
 	case 16:
 		switch(dc_lsize) {
 		case 16:
-			flush_cache_all = r4k_flush_cache_all_s16d16i16;
-			flush_cache_mm = r4k_flush_cache_mm_s16d16i16;
-			flush_cache_range = r4k_flush_cache_range_s16d16i16;
-			flush_cache_page = r4k_flush_cache_page_s16d16i16;
-			flush_page_to_ram = r4k_flush_page_to_ram_s16d16i16;
+			_flush_cache_all = r4k_flush_cache_all_s16d16i16;
+			_flush_cache_mm = r4k_flush_cache_mm_s16d16i16;
+			_flush_cache_range = r4k_flush_cache_range_s16d16i16;
+			_flush_cache_page = r4k_flush_cache_page_s16d16i16;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s16d16i16;
 			break;
 		case 32:
 			panic("Invalid cache configuration detected");
 		};
-		clear_page = r4k_clear_page_s16;
-		copy_page = r4k_copy_page_s16;
+		_clear_page = r4k_clear_page_s16;
+		_copy_page = r4k_copy_page_s16;
 		break;
 	case 32:
 		switch(dc_lsize) {
 		case 16:
-			flush_cache_all = r4k_flush_cache_all_s32d16i16;
-			flush_cache_mm = r4k_flush_cache_mm_s32d16i16;
-			flush_cache_range = r4k_flush_cache_range_s32d16i16;
-			flush_cache_page = r4k_flush_cache_page_s32d16i16;
-			flush_page_to_ram = r4k_flush_page_to_ram_s32d16i16;
+			_flush_cache_all = r4k_flush_cache_all_s32d16i16;
+			_flush_cache_mm = r4k_flush_cache_mm_s32d16i16;
+			_flush_cache_range = r4k_flush_cache_range_s32d16i16;
+			_flush_cache_page = r4k_flush_cache_page_s32d16i16;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s32d16i16;
 			break;
 		case 32:
-			flush_cache_all = r4k_flush_cache_all_s32d32i32;
-			flush_cache_mm = r4k_flush_cache_mm_s32d32i32;
-			flush_cache_range = r4k_flush_cache_range_s32d32i32;
-			flush_cache_page = r4k_flush_cache_page_s32d32i32;
-			flush_page_to_ram = r4k_flush_page_to_ram_s32d32i32;
+			_flush_cache_all = r4k_flush_cache_all_s32d32i32;
+			_flush_cache_mm = r4k_flush_cache_mm_s32d32i32;
+			_flush_cache_range = r4k_flush_cache_range_s32d32i32;
+			_flush_cache_page = r4k_flush_cache_page_s32d32i32;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s32d32i32;
 			break;
 		};
-		clear_page = r4k_clear_page_s32;
-		copy_page = r4k_copy_page_s32;
+		_clear_page = r4k_clear_page_s32;
+		_copy_page = r4k_copy_page_s32;
 		break;
 	case 64:
 		switch(dc_lsize) {
 		case 16:
-			flush_cache_all = r4k_flush_cache_all_s64d16i16;
-			flush_cache_mm = r4k_flush_cache_mm_s64d16i16;
-			flush_cache_range = r4k_flush_cache_range_s64d16i16;
-			flush_cache_page = r4k_flush_cache_page_s64d16i16;
-			flush_page_to_ram = r4k_flush_page_to_ram_s64d16i16;
+			_flush_cache_all = r4k_flush_cache_all_s64d16i16;
+			_flush_cache_mm = r4k_flush_cache_mm_s64d16i16;
+			_flush_cache_range = r4k_flush_cache_range_s64d16i16;
+			_flush_cache_page = r4k_flush_cache_page_s64d16i16;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s64d16i16;
 			break;
 		case 32:
-			flush_cache_all = r4k_flush_cache_all_s64d32i32;
-			flush_cache_mm = r4k_flush_cache_mm_s64d32i32;
-			flush_cache_range = r4k_flush_cache_range_s64d32i32;
-			flush_cache_page = r4k_flush_cache_page_s64d32i32;
-			flush_page_to_ram = r4k_flush_page_to_ram_s64d32i32;
+			_flush_cache_all = r4k_flush_cache_all_s64d32i32;
+			_flush_cache_mm = r4k_flush_cache_mm_s64d32i32;
+			_flush_cache_range = r4k_flush_cache_range_s64d32i32;
+			_flush_cache_page = r4k_flush_cache_page_s64d32i32;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s64d32i32;
 			break;
 		};
-		clear_page = r4k_clear_page_s64;
-		copy_page = r4k_copy_page_s64;
+		_clear_page = r4k_clear_page_s64;
+		_copy_page = r4k_copy_page_s64;
 		break;
 	case 128:
 		switch(dc_lsize) {
 		case 16:
-			flush_cache_all = r4k_flush_cache_all_s128d16i16;
-			flush_cache_mm = r4k_flush_cache_mm_s128d16i16;
-			flush_cache_range = r4k_flush_cache_range_s128d16i16;
-			flush_cache_page = r4k_flush_cache_page_s128d16i16;
-			flush_page_to_ram = r4k_flush_page_to_ram_s128d16i16;
+			_flush_cache_all = r4k_flush_cache_all_s128d16i16;
+			_flush_cache_mm = r4k_flush_cache_mm_s128d16i16;
+			_flush_cache_range = r4k_flush_cache_range_s128d16i16;
+			_flush_cache_page = r4k_flush_cache_page_s128d16i16;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s128d16i16;
 			break;
 		case 32:
-			flush_cache_all = r4k_flush_cache_all_s128d32i32;
-			flush_cache_mm = r4k_flush_cache_mm_s128d32i32;
-			flush_cache_range = r4k_flush_cache_range_s128d32i32;
-			flush_cache_page = r4k_flush_cache_page_s128d32i32;
-			flush_page_to_ram = r4k_flush_page_to_ram_s128d32i32;
+			_flush_cache_all = r4k_flush_cache_all_s128d32i32;
+			_flush_cache_mm = r4k_flush_cache_mm_s128d32i32;
+			_flush_cache_range = r4k_flush_cache_range_s128d32i32;
+			_flush_cache_page = r4k_flush_cache_page_s128d32i32;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s128d32i32;
 			break;
 		};
-		clear_page = r4k_clear_page_s128;
-		copy_page = r4k_copy_page_s128;
+		_clear_page = r4k_clear_page_s128;
+		_copy_page = r4k_copy_page_s128;
 		break;
 	}
-	dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
-	dma_cache_wback = r4k_dma_cache_wback;
-	dma_cache_inv = r4k_dma_cache_inv_sc;
+	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
+	_dma_cache_wback = r4k_dma_cache_wback;
+	_dma_cache_inv = r4k_dma_cache_inv_sc;
 }
 
 typedef int (*probe_func_t)(unsigned long);
@@ -2765,11 +2771,6 @@
 	setup_noscache_funcs();
 }
 
-static int r4k_user_mode(struct pt_regs *regs)
-{
-	return (regs->cp0_status & ST0_KSU) == KSU_USER;
-}
-
 void __init ld_mmu_r4xx0(void)
 {
 	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
@@ -2787,29 +2788,13 @@
 	case CPU_R4700:
 	case CPU_R5000:
 	case CPU_NEVADA:
-		flush_cache_page = r4k_flush_cache_page_d32i32_r4600;
+		_flush_cache_page = r4k_flush_cache_page_d32i32_r4600;
 	}
 
-	flush_cache_sigtramp = r4k_flush_cache_sigtramp;
+	_flush_cache_sigtramp = r4k_flush_cache_sigtramp;
 	if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) {
-		flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp;
+		_flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp;
 	}
-
-	flush_tlb_all = r4k_flush_tlb_all;
-	flush_tlb_mm = r4k_flush_tlb_mm;
-	flush_tlb_range = r4k_flush_tlb_range;
-	flush_tlb_page = r4k_flush_tlb_page;
-	r4xx0_asid_setup();
-
-	load_pgd = r4k_load_pgd;
-	pgd_init = r4k_pgd_init;
-	update_mmu_cache = r4k_update_mmu_cache;
-
-	show_regs = r4k_show_regs;
-    
-        add_wired_entry = r4k_add_wired_entry;
-
-	user_mode = r4k_user_mode;
 
 	flush_cache_all();
 	write_32bit_cp0_register(CP0_WIRED, 0);
diff -u --recursive --new-file v2.3.47/linux/arch/mips/mm/r6000.c linux/arch/mips/mm/r6000.c
--- v2.3.47/linux/arch/mips/mm/r6000.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/mm/r6000.c	Wed Dec 31 16:00:00 1969
@@ -1,199 +0,0 @@
-/* $Id: r6000.c,v 1.6 1999/01/04 16:03:54 ralf Exp $
- *
- * r6000.c: MMU and cache routines for the R6000 processors.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/cacheops.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/sgialib.h>
-#include <asm/mmu_context.h>
-
-__asm__(".set mips3"); /* because we know... */
-
-/* Cache operations. XXX Write these dave... */
-static inline void r6000_flush_cache_all(void)
-{
-	/* XXX */
-}
-
-static void r6000_flush_cache_mm(struct mm_struct *mm)
-{
-	/* XXX */
-}
-
-static void r6000_flush_cache_range(struct mm_struct *mm,
-				    unsigned long start,
-				    unsigned long end)
-{
-	/* XXX */
-}
-
-static void r6000_flush_cache_page(struct vm_area_struct *vma,
-				   unsigned long page)
-{
-	/* XXX */
-}
-
-static void r6000_flush_page_to_ram(unsigned long page)
-{
-	/* XXX */
-}
-
-static void r6000_flush_cache_sigtramp(unsigned long page)
-{
-	/* XXX */
-}
-
-/* TLB operations. XXX Write these dave... */
-static inline void r6000_flush_tlb_all(void)
-{
-	/* XXX */
-}
-
-static void r6000_flush_tlb_mm(struct mm_struct *mm)
-{
-	/* XXX */
-}
-
-static void r6000_flush_tlb_range(struct mm_struct *mm, unsigned long start,
-				  unsigned long end)
-{
-	/* XXX */
-}
-
-static void r6000_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
-	/* XXX */
-}
-
-static void r6000_load_pgd(unsigned long pg_dir)
-{
-}
-
-static void r6000_pgd_init(unsigned long page)
-{
-	unsigned long dummy1, dummy2;
-
-	/*
-	 * This version is optimized for the R6000.  We generate dirty lines
-	 * in the datacache, overwrite these lines with zeros and then flush
-	 * the cache.  Sounds horribly complicated but is just a trick to
-	 * avoid unnecessary loads of from memory and uncached stores which
-	 * are very expensive.  Not tested yet as the R6000 is a rare CPU only
-	 * available in SGI machines and I don't have one.
-	 */
-	__asm__ __volatile__(
-		".set\tnoreorder\n"
-		"1:\t"
-		"cache\t%5,(%0)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%2,4(%0)\n\t"
-		"sw\t%2,8(%0)\n\t"
-		"sw\t%2,12(%0)\n\t"
-		"cache\t%5,16(%0)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%2,20(%0)\n\t"
-		"sw\t%2,24(%0)\n\t"
-		"sw\t%2,28(%0)\n\t"
-		"subu\t%1,1\n\t"
-		"bnez\t%1,1b\n\t"
-		"addiu\t%0,32\n\t"
-		".set\treorder"
-		:"=r" (dummy1),
-		 "=r" (dummy2)
-		:"r" ((unsigned long) invalid_pte_table),
-		 "0" (page),
-		 "1" (USER_PTRS_PER_PGD/8),
-		 "i" (Create_Dirty_Excl_D));
-}
-
-static void r6000_update_mmu_cache(struct vm_area_struct * vma,
-				   unsigned long address, pte_t pte)
-{
-	r6000_flush_tlb_page(vma, address);
-	/*
-	 * FIXME: We should also reload a new entry into the TLB to
-	 * avoid unnecessary exceptions.
-	 */
-}
-
-static void r6000_show_regs(struct pt_regs * regs)
-{
-	/*
-	 * Saved main processor registers
-	 */
-	printk("$0 : %08x %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-	       0, (unsigned long) regs->regs[1], (unsigned long) regs->regs[2],
-	       (unsigned long) regs->regs[3], (unsigned long) regs->regs[4],
-	       (unsigned long) regs->regs[5], (unsigned long) regs->regs[6],
-	       (unsigned long) regs->regs[7]);
-	printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-	       (unsigned long) regs->regs[8], (unsigned long) regs->regs[9],
-	       (unsigned long) regs->regs[10], (unsigned long) regs->regs[11],
-               (unsigned long) regs->regs[12], (unsigned long) regs->regs[13],
-	       (unsigned long) regs->regs[14], (unsigned long) regs->regs[15]);
-	printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-	       (unsigned long) regs->regs[16], (unsigned long) regs->regs[17],
-	       (unsigned long) regs->regs[18], (unsigned long) regs->regs[19],
-               (unsigned long) regs->regs[20], (unsigned long) regs->regs[21],
-	       (unsigned long) regs->regs[22], (unsigned long) regs->regs[23]);
-	printk("$24: %08lx %08lx                   %08lx %08lx %08lx %08lx\n",
-	       (unsigned long) regs->regs[24], (unsigned long) regs->regs[25],
-	       (unsigned long) regs->regs[28], (unsigned long) regs->regs[29],
-               (unsigned long) regs->regs[30], (unsigned long) regs->regs[31]);
-
-	/*
-	 * Saved cp0 registers
-	 */
-	printk("epc  : %08lx\nStatus: %08x\nCause : %08x\n",
-	       (unsigned long) regs->cp0_epc, (unsigned int) regs->cp0_status,
-	       (unsigned int) regs->cp0_cause);
-}
-
-static void r6000_add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
-				  unsigned long entryhi, unsigned long pagemask)
-{
-        /* XXX */
-}
-
-static int r6000_user_mode(struct pt_regs *regs)
-{
-	return !(regs->cp0_status & 0x4);
-}
-
-void __init ld_mmu_r6000(void)
-{
-	flush_cache_all = r6000_flush_cache_all;
-	flush_cache_mm = r6000_flush_cache_mm;
-	flush_cache_range = r6000_flush_cache_range;
-	flush_cache_page = r6000_flush_cache_page;
-	flush_cache_sigtramp = r6000_flush_cache_sigtramp;
-	flush_page_to_ram = r6000_flush_page_to_ram;
-
-	flush_tlb_all = r6000_flush_tlb_all;
-	flush_tlb_mm = r6000_flush_tlb_mm;
-	flush_tlb_range = r6000_flush_tlb_range;
-	flush_tlb_page = r6000_flush_tlb_page;
-	r6000_asid_setup();
-
-	load_pgd = r6000_load_pgd;
-	pgd_init = r6000_pgd_init;
-	update_mmu_cache = r6000_update_mmu_cache;
-
-	show_regs = r6000_show_regs;
-    
-        add_wired_entry = r6000_add_wired_entry;
-
-	user_mode = r6000_user_mode;
-
-	flush_cache_all();
-	flush_tlb_all();
-}
diff -u --recursive --new-file v2.3.47/linux/arch/mips/mm/tfp.c linux/arch/mips/mm/tfp.c
--- v2.3.47/linux/arch/mips/mm/tfp.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/mm/tfp.c	Wed Dec 31 16:00:00 1969
@@ -1,120 +0,0 @@
-/* $Id: tfp.c,v 1.6 1999/01/04 16:03:55 ralf Exp $
- *
- * tfp.c: MMU and cache routines specific to the r8000 (TFP).
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/sgialib.h>
-#include <asm/mmu_context.h>
-
-extern unsigned long mips_tlb_entries;
-
-/* Cache operations. XXX Write these dave... */
-static inline void tfp_flush_cache_all(void)
-{
-	/* XXX */
-}
-
-static void tfp_flush_cache_mm(struct mm_struct *mm)
-{
-	/* XXX */
-}
-
-static void tfp_flush_cache_range(struct mm_struct *mm,
-				  unsigned long start,
-				  unsigned long end)
-{
-	/* XXX */
-}
-
-static void tfp_flush_cache_page(struct vm_area_struct *vma,
-				 unsigned long page)
-{
-	/* XXX */
-}
-
-static void tfp_flush_page_to_ram(unsigned long page)
-{
-	/* XXX */
-}
-
-static void tfp_flush_cache_sigtramp(unsigned long page)
-{
-	/* XXX */
-}
-
-/* TLB operations. XXX Write these dave... */
-static inline void tfp_flush_tlb_all(void)
-{
-	/* XXX */
-}
-
-static void tfp_flush_tlb_mm(struct mm_struct *mm)
-{
-	/* XXX */
-}
-
-static void tfp_flush_tlb_range(struct mm_struct *mm, unsigned long start,
-				unsigned long end)
-{
-	/* XXX */
-}
-
-static void tfp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
-	/* XXX */
-}
-
-static void tfp_load_pgd(unsigned long pg_dir)
-{
-}
-
-static void tfp_pgd_init(unsigned long page)
-{
-}
-
-static void tfp_add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
-				unsigned long entryhi, unsigned long pagemask)
-{
-        /* XXX */
-}
-
-static int tfp_user_mode(struct pt_regs *regs)
-{
-	return (regs->cp0_status & ST0_KSU) == KSU_USER;
-}
-
-void __init ld_mmu_tfp(void)
-{
-	flush_cache_all = tfp_flush_cache_all;
-	flush_cache_mm = tfp_flush_cache_mm;
-	flush_cache_range = tfp_flush_cache_range;
-	flush_cache_page = tfp_flush_cache_page;
-	flush_cache_sigtramp = tfp_flush_cache_sigtramp;
-	flush_page_to_ram = tfp_flush_page_to_ram;
-
-	flush_tlb_all = tfp_flush_tlb_all;
-	flush_tlb_mm = tfp_flush_tlb_mm;
-	flush_tlb_range = tfp_flush_tlb_range;
-	flush_tlb_page = tfp_flush_tlb_page;
-	tfp_asid_setup();
-
-        add_wired_entry = tfp_add_wired_entry;
-
-	user_mode = tfp_user_mode;
-
-	load_pgd = tfp_load_pgd;
-	pgd_init = tfp_pgd_init;
-    
-	flush_cache_all();
-	flush_tlb_all();
-}
diff -u --recursive --new-file v2.3.47/linux/arch/mips/mm/umap.c linux/arch/mips/mm/umap.c
--- v2.3.47/linux/arch/mips/mm/umap.c	Sat Aug 16 09:51:07 1997
+++ linux/arch/mips/mm/umap.c	Thu Feb 24 22:52:30 2000
@@ -26,7 +26,7 @@
 #include <linux/swap.h>
 
 #include <asm/system.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/page.h>
 
 static inline void
@@ -114,16 +114,16 @@
 static inline void free_pte(pte_t page)
 {
 	if (pte_present(page)) {
-		unsigned long addr = pte_page(page);
-		if (MAP_NR(addr) >= max_mapnr || PageReserved(mem_map+MAP_NR(addr)))
+		unsigned long nr = pte_pagenr(page);
+		if (nr >= max_mapnr || PageReserved(mem_map+nr))
 			return;
-		free_page(addr);
+		__free_page(pte_page(page));
 		if (current->mm->rss <= 0)
 			return;
 		current->mm->rss--;
 		return;
 	}
-	swap_free(pte_val(page));
+	swap_free(pte_to_swp_entry(page));
 }
 
 static inline void forget_pte(pte_t page)
@@ -152,15 +152,15 @@
 		end = PMD_SIZE;
 	do {
 		pte_t oldpage = *pte;
-		unsigned long page;
+		struct page * page;
 		pte_clear(pte);
 
 		vdir = pgd_offset_k (vaddr);
 		vpmd = pmd_offset (vdir, vaddr);
 		vpte = pte_offset (vpmd, vaddr);
 		page = pte_page (*vpte);
-		
-		set_pte(pte, mk_pte_phys(page, PAGE_USERIO));
+
+		set_pte(pte, mk_pte(page, PAGE_USERIO));
 		forget_pte(oldpage);
 		address += PAGE_SIZE;
 		vaddr += PAGE_SIZE;
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/Makefile linux/arch/mips/sgi/kernel/Makefile
--- v2.3.47/linux/arch/mips/sgi/kernel/Makefile	Mon Dec 20 18:48:21 1999
+++ linux/arch/mips/sgi/kernel/Makefile	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.7 1999/05/07 18:00:16 ulfc Exp $
+# $Id: Makefile,v 1.8 2000/02/05 06:47:08 ralf Exp $
 # Makefile for the SGI specific kernel interface routines
 # under Linux.
 #
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/indyIRQ.S linux/arch/mips/sgi/kernel/indyIRQ.S
--- v2.3.47/linux/arch/mips/sgi/kernel/indyIRQ.S	Fri Jun 25 17:40:13 1999
+++ linux/arch/mips/sgi/kernel/indyIRQ.S	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: indyIRQ.S,v 1.3 1998/03/22 23:27:17 ralf Exp $
+/* $Id: indyIRQ.S,v 1.4 1999/08/18 23:37:45 ralf Exp $
  * indyIRQ.S: Interrupt exception dispatch code for FullHouse and
  *            Guiness.
  *
@@ -6,7 +6,6 @@
  */
 
 #include <asm/asm.h>
-#include <asm/mipsconfig.h>
 #include <asm/mipsregs.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/indy_hpc.c linux/arch/mips/sgi/kernel/indy_hpc.c
--- v2.3.47/linux/arch/mips/sgi/kernel/indy_hpc.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/sgi/kernel/indy_hpc.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: indy_hpc.c,v 1.6 1999/05/07 22:34:31 ulfc Exp $
+/* $Id: indy_hpc.c,v 1.9 1999/12/04 03:59:00 ralf Exp $
  *
  * indy_hpc.c: Routines for generic manipulation of the HPC controllers.
  *
@@ -8,8 +8,8 @@
 #include <linux/init.h>
 
 #include <asm/addrspace.h>
-#include <asm/sgihpc.h>
-#include <asm/sgint23.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
 #include <asm/sgialib.h>
 
 /* #define DEBUG_SGIHPC */
@@ -18,7 +18,7 @@
 struct hpc3_miscregs *hpc3mregs;
 
 /* We need software copies of these because they are write only. */
-unsigned long sgi_hpc_write1, sgi_hpc_write2;
+unsigned int sgi_hpc_write1, sgi_hpc_write2;
 
 /* Machine specific identifier knobs. */
 int sgi_has_ioc2 = 0;
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/indy_int.c linux/arch/mips/sgi/kernel/indy_int.c
--- v2.3.47/linux/arch/mips/sgi/kernel/indy_int.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/sgi/kernel/indy_int.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: indy_int.c,v 1.13 1999/06/12 17:26:15 ulfc Exp $
+/* $Id: indy_int.c,v 1.17 2000/02/04 07:40:23 ralf Exp $
  *
  * indy_int.c: Routines for generic manipulation of the INT[23] ASIC
  *             found on INDY workstations..
@@ -9,7 +9,9 @@
  *                    - Indigo2 changes
  *                    - Interrupt handling fixes
  */
+#include <linux/config.h>
 #include <linux/init.h>
+
 #include <linux/errno.h>
 #include <linux/kernel_stat.h>
 #include <linux/signal.h>
@@ -32,9 +34,9 @@
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
-#include <asm/sgi.h>
-#include <asm/sgihpc.h>
-#include <asm/sgint23.h>
+#include <asm/sgi/sgi.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
 #include <asm/sgialib.h>
 #include <asm/gdb-stub.h>
 
@@ -257,8 +259,6 @@
 	return len;
 }
 
-atomic_t __mips_bh_counter;
-
 /*
  * do_IRQ handles IRQ's that have been installed without the
  * SA_INTERRUPT flag: it uses the full signal-handling return
@@ -272,7 +272,7 @@
 	int do_random, cpu;
 
 	cpu = smp_processor_id();
-	hardirq_enter(cpu);
+	irq_enter(cpu);
 	kstat.irqs[0][irq]++;
 
 	printk("Got irq %d, press a key.", irq);
@@ -308,7 +308,7 @@
 			add_interrupt_randomness(irq);
 		__cli();
 	}
-	hardirq_exit(cpu);
+	irq_exit(cpu);
 
 	/* unmasking and bottom half handling is done magically for us. */
 }
@@ -451,10 +451,10 @@
 	/* if action == NULL, then we do have a handler for the irq */
 	if ( action == NULL ) { goto no_handler; }
 	
-	hardirq_enter(cpu);
+	irq_enter(cpu);
 	kstat.irqs[0][irq + 16]++;
 	action->handler(irq, action->dev_id, regs);
-	hardirq_exit(cpu);
+	irq_exit(cpu);
 	goto end;
 
 no_handler:
@@ -489,10 +489,10 @@
 	/* if action == NULL, then we do have a handler for the irq */
 	if ( action == NULL ) { goto no_handler; }
 	
-	hardirq_enter(cpu);
+	irq_enter(cpu);
 	kstat.irqs[0][irq + 24]++;
 	action->handler(irq, action->dev_id, regs);
-	hardirq_exit(cpu);
+	irq_exit(cpu);
 	goto end;
 	
 no_handler:
@@ -507,13 +507,13 @@
 	int cpu = smp_processor_id();
 	int irq = 6;
 
-	hardirq_enter(cpu);
+	irq_enter(cpu);
 	kstat.irqs[0][irq]++;
 	printk("Got a bus error IRQ, shouldn't happen yet\n");
 	show_regs(regs);
 	printk("Spinning...\n");
 	while(1);
-	hardirq_exit(cpu);
+	irq_exit(cpu);
 }
 
 /* Misc. crap just to keep the kernel linking... */
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/indy_mc.c linux/arch/mips/sgi/kernel/indy_mc.c
--- v2.3.47/linux/arch/mips/sgi/kernel/indy_mc.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/sgi/kernel/indy_mc.c	Thu Feb 24 22:52:30 2000
@@ -4,21 +4,21 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
  *
- * $Id: indy_mc.c,v 1.4 1999/05/07 22:34:32 ulfc Exp $
+ * $Id: indy_mc.c,v 1.8 1999/12/06 23:13:20 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
 
 #include <asm/addrspace.h>
 #include <asm/ptrace.h>
-#include <asm/sgimc.h>
-#include <asm/sgihpc.h>
+#include <asm/sgi/sgimc.h>
+#include <asm/sgi/sgihpc.h>
 #include <asm/sgialib.h>
 
 /* #define DEBUG_SGIMC */
 
 struct sgimc_misc_ctrl *mcmisc_regs;
-unsigned long *rpsscounter;
+u32 *rpsscounter;
 struct sgimc_dma_ctrl *dmactrlregs;
 
 static inline char *mconfig_string(unsigned long val)
@@ -52,7 +52,7 @@
 	unsigned long tmpreg;
 
 	mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000);
-	rpsscounter = (unsigned long *) (KSEG1 + 0x1fa01004);
+	rpsscounter = (unsigned int *) (KSEG1 + 0x1fa01004);
 	dmactrlregs = (struct sgimc_dma_ctrl *) (KSEG1+0x1fa02000);
 
 	printk("MC: SGI memory controller Revision %d\n",
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/indy_rtc.c linux/arch/mips/sgi/kernel/indy_rtc.c
--- v2.3.47/linux/arch/mips/sgi/kernel/indy_rtc.c	Tue Oct 20 13:52:55 1998
+++ linux/arch/mips/sgi/kernel/indy_rtc.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: indy_rtc.c,v 1.1 1998/06/25 20:19:17 ralf Exp $
+/* $Id: indy_rtc.c,v 1.2 1999/10/21 00:23:05 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -9,7 +9,7 @@
  * Copyright (C) 1998 by Ralf Baechle
  */
 #include <linux/mc146818rtc.h>
-#include <asm/sgihpc.h>
+#include <asm/sgi/sgihpc.h>
 
 static unsigned char indy_rtc_read_data(unsigned long addr)
 {
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/indy_sc.c linux/arch/mips/sgi/kernel/indy_sc.c
--- v2.3.47/linux/arch/mips/sgi/kernel/indy_sc.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/sgi/kernel/indy_sc.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: indy_sc.c,v 1.9 1999/05/12 21:57:49 ulfc Exp $
+/* $Id: indy_sc.c,v 1.13 1999/12/04 03:59:00 ralf Exp $
  *
  * indy_sc.c: Indy cache managment functions.
  *
@@ -11,8 +11,8 @@
 #include <linux/mm.h>
 
 #include <asm/bcache.h>
-#include <asm/sgi.h>
-#include <asm/sgimc.h>
+#include <asm/sgi/sgi.h>
+#include <asm/sgi/sgimc.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -221,6 +221,7 @@
 
 void __init indy_sc_init(void)
 {
+return;
 	if (indy_sc_probe()) {
 		indy_sc_enable();
 		bcops = &indy_sc_ops;
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/indy_timer.c linux/arch/mips/sgi/kernel/indy_timer.c
--- v2.3.47/linux/arch/mips/sgi/kernel/indy_timer.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/sgi/kernel/indy_timer.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: indy_timer.c,v 1.12 1999/06/13 16:30:36 ralf Exp $
+/* $Id: indy_timer.c,v 1.18 2000/02/04 07:40:23 ralf Exp $
  *
  * indy_timer.c: Setting up the clock on the INDY 8254 controller.
  *
@@ -21,10 +21,10 @@
 #include <asm/irq.h>
 #include <asm/ptrace.h>
 #include <asm/system.h>
-#include <asm/sgi.h>
 #include <asm/sgialib.h>
-#include <asm/sgihpc.h>
-#include <asm/sgint23.h>
+#include <asm/sgi/sgi.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
 
 
 /* Because of a bug in the i8254 timer we need to use the onchip r4k
@@ -33,6 +33,8 @@
 static unsigned long r4k_offset; /* Amount to increment compare reg each time */
 static unsigned long r4k_cur;    /* What counter should be at next timer irq */
 
+extern rwlock_t xtime_lock;
+
 static inline void ack_r4ktimer(unsigned long newval)
 {
 	write_32bit_cp0_register(CP0_COMPARE, newval);
@@ -85,6 +87,7 @@
 	unsigned long count;
 	int irq = 7;
 
+	write_lock(&xtime_lock);
 	/* Ack timer and compute new compare. */
 	count = read_32bit_cp0_register(CP0_COUNT);
 	/* This has races.  */
@@ -107,11 +110,14 @@
 	if ((time_status & STA_UNSYNC) == 0 &&
 	    xtime.tv_sec > last_rtc_update + 660 &&
 	    xtime.tv_usec >= 500000 - (tick >> 1) &&
-	    xtime.tv_usec <= 500000 + (tick >> 1))
-	  if (set_rtc_mmss(xtime.tv_sec) == 0)
-	    last_rtc_update = xtime.tv_sec;
-	  else
-	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	    xtime.tv_usec <= 500000 + (tick >> 1)) {
+		if (set_rtc_mmss(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			/* do it again in 60 s */
+			last_rtc_update = xtime.tv_sec - 600;
+	}
+	write_unlock(&xtime_lock);
 }
 
 static unsigned long dosample(volatile unsigned char *tcwp,
@@ -252,9 +258,10 @@
 	set_cp0_status(ST0_IM, ALLINTS);
 	sti();
 
-	/* Read time from the dallas chipset. */
-	xtime.tv_sec = get_indy_time();
+	write_lock_irq(&xtime_lock);
+	xtime.tv_sec = get_indy_time();		/* Read time from RTC. */
 	xtime.tv_usec = 0;
+	write_unlock_irq(&xtime_lock);
 }
 
 void indy_8254timer_irq(void)
@@ -262,29 +269,29 @@
 	int cpu = smp_processor_id();
 	int irq = 4;
 
-	hardirq_enter(cpu);
+	irq_enter(cpu);
 	kstat.irqs[0][irq]++;
 	printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
 	prom_getchar();
 	prom_imode();
-	hardirq_exit(cpu);
+	irq_exit(cpu);
 }
 
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	read_lock_irqsave(&xtime_lock, flags);
 	*tv = xtime;
-	restore_flags(flags);
+	read_unlock_irqrestore(&xtime_lock, flags);
 }
 
 void do_settimeofday(struct timeval *tv)
 {
-	cli();
+	write_lock_irq(&xtime_lock);
 	xtime = *tv;
 	time_state = TIME_BAD;
 	time_maxerror = MAXPHASE;
 	time_esterror = MAXPHASE;
-	sti();
+	write_unlock_irq(&xtime_lock);
 }
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/reset.c linux/arch/mips/sgi/kernel/reset.c
--- v2.3.47/linux/arch/mips/sgi/kernel/reset.c	Fri Jun 25 17:40:13 1999
+++ linux/arch/mips/sgi/kernel/reset.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: reset.c,v 1.6 1999/04/10 12:21:30 ulfc Exp $
+/* $Id: reset.c,v 1.8 1999/10/21 00:23:05 ralf Exp $
  *
  * Reset a SGI.
  *
@@ -17,8 +17,8 @@
 #include <asm/system.h>
 #include <asm/reboot.h>
 #include <asm/sgialib.h>
-#include <asm/sgihpc.h>
-#include <asm/sgint23.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
 
 /*
  * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds.
@@ -108,7 +108,7 @@
 	if (has_paniced)
 		prom_reboot();
 
-	enable_irq(9);
+	enable_irq(SGI_PANEL_IRQ);
 }
 
 static inline void power_button(void)
@@ -185,7 +185,7 @@
 	hpc3mregs->panel = 3; /* power_interrupt | power_supply_on */
 
 	if (ioc_icontrol->istat1 & 2) { /* Wait until interrupt goes away */
-		disable_irq(9);
+		disable_irq(SGI_PANEL_IRQ);
 		init_timer(&debounce_timer);
 		debounce_timer.function = debounce;
 		debounce_timer.expires = jiffies + 5;
@@ -239,7 +239,7 @@
 	_machine_halt = sgi_machine_halt;
 	_machine_power_off = sgi_machine_power_off;
 
-	request_irq(9, panel_int, 0, "Front Panel", NULL);
+	request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL);
 	init_timer(&blink_timer);
 	blink_timer.function = blink_timeout;
 	notifier_chain_register(&panic_notifier_list, &panic_block);
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/setup.c linux/arch/mips/sgi/kernel/setup.c
--- v2.3.47/linux/arch/mips/sgi/kernel/setup.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/sgi/kernel/setup.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.24 1999/06/12 17:26:15 ulfc Exp $
+/* $Id: setup.c,v 1.29 2000/01/27 01:05:23 ralf Exp $
  *
  * setup.c: SGI specific setup, including init of the feature struct.
  *
@@ -22,10 +22,9 @@
 #include <asm/irq.h>
 #include <asm/reboot.h>
 #include <asm/sgialib.h>
-#include <asm/sgi.h>
-#include <asm/sgimc.h>
-#include <asm/sgihpc.h>
-#include <asm/sgint23.h>
+#include <asm/sgi/sgimc.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
 #include <asm/gdb-stub.h>
 
 #ifdef CONFIG_REMOTE_DEBUG
@@ -34,7 +33,7 @@
 #endif
 
 #if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
-extern void console_setup(char *, int *);
+extern void console_setup(char *);
 #endif
 
 extern struct rtc_ops indy_rtc_ops;
@@ -129,6 +128,15 @@
 #endif
 }
 
+int __init page_is_ram(unsigned long pagenr)
+{
+	if (pagenr < MAP_NR(PAGE_OFFSET + 0x2000UL))
+		return 1;
+	if (pagenr > MAP_NR(PAGE_OFFSET + 0x08002000))
+		return 1;
+	return 0;
+}
+
 void __init sgi_setup(void)
 {
 #ifdef CONFIG_SERIAL_CONSOLE
@@ -161,9 +169,9 @@
 	ctype = prom_getenv("console");
 	if(*ctype == 'd') {
 		if(*(ctype+1)=='2')
-			console_setup ("ttyS1", NULL);
+			console_setup ("ttyS1");
 		else
-			console_setup ("ttyS0", NULL);
+			console_setup ("ttyS0");
 	}
 #endif
 
@@ -197,6 +205,18 @@
 #ifdef CONFIG_VT
 #ifdef CONFIG_SGI_NEWPORT_CONSOLE
 	conswitchp = &newport_con;
+
+	screen_info = (struct screen_info) {
+		0, 0,		/* orig-x, orig-y */
+		0,		/* unused */
+		0,		/* orig_video_page */
+		0,		/* orig_video_mode */
+		160,		/* orig_video_cols */
+		0, 0, 0,	/* unused, ega_bx, unused */
+		64,		/* orig_video_lines */
+		0,		/* orig_video_isVGA */
+		16		/* orig_video_points */
+	};
 #else
 	conswitchp = &dummy_con;
 #endif
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/system.c linux/arch/mips/sgi/kernel/system.c
--- v2.3.47/linux/arch/mips/sgi/kernel/system.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/sgi/kernel/system.c	Thu Feb 24 22:52:30 2000
@@ -3,14 +3,14 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: system.c,v 1.7 1998/10/18 22:55:34 tsbogend Exp $
+ * $Id: system.c,v 1.9 1999/10/21 00:23:05 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
 
-#include <asm/sgi.h>
+#include <asm/sgi/sgi.h>
 #include <asm/sgialib.h>
 #include <asm/bootinfo.h>
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/time.c linux/arch/mips/sgi/kernel/time.c
--- v2.3.47/linux/arch/mips/sgi/kernel/time.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/sgi/kernel/time.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.2 1998/04/05 11:24:00 ralf Exp $
+/* $Id: time.c,v 1.3 1999/10/09 00:00:59 ralf Exp $
  * time.c: Generic SGI time_init() code, this will dispatch to the
  *         appropriate per-architecture time/counter init code.
  *
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sni/Makefile linux/arch/mips/sni/Makefile
--- v2.3.47/linux/arch/mips/sni/Makefile	Fri Jun 25 17:40:13 1999
+++ linux/arch/mips/sni/Makefile	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.3 1999/01/04 16:03:57 ralf Exp $
+# $Id: Makefile,v 1.4 2000/02/18 00:24:30 ralf Exp $
 #
 # Makefile for the SNI specific part of the kernel
 #
@@ -14,7 +14,7 @@
 
 all: sni.o
 O_TARGET := sni.o
-O_OBJS	 := int-handler.o io.o pci.o pcimt_scache.o reset.o setup.o
+O_OBJS	 := dma.o int-handler.o io.o pci.o pcimt_scache.o reset.o setup.o
 
 int-handler.o: int-handler.S
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sni/dma.c linux/arch/mips/sni/dma.c
--- v2.3.47/linux/arch/mips/sni/dma.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sni/dma.c	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,42 @@
+/* $Id: dma.c,v 1.2 2000/02/24 00:12:41 ralf Exp $
+ *
+ * Dynamic DMA mapping support.
+ *
+ * On RM200 there is no hardware dynamic DMA address translation,
+ * so consistent alloc/free are merely page allocation/freeing.
+ * The rest of the dynamic DMA mapping interface is implemented
+ * in <asm/pci.h>.
+ *
+ * These routines assume that the RM has all it's memory at physical
+ * addresses of < 512mb.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t *dma_handle)
+{
+	void *ret;
+	int gfp = GFP_ATOMIC;
+	int order = get_order(size);
+
+	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
+		gfp |= GFP_DMA;
+	ret = (void *)__get_free_pages(gfp, order);
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_bus(ret);
+	}
+	dma_cache_wback_inv(ret, PAGE_SIZE << order);
+	return KSEG1ADDR(ret);
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	free_pages((unsigned long)vaddr, get_order(size));
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sni/int-handler.S linux/arch/mips/sni/int-handler.S
--- v2.3.47/linux/arch/mips/sni/int-handler.S	Fri Jun 25 17:40:13 1999
+++ linux/arch/mips/sni/int-handler.S	Thu Feb 24 22:52:30 2000
@@ -1,11 +1,10 @@
-/* $Id: int-handler.S,v 1.4 1999/01/04 16:03:58 ralf Exp $
+/* $Id: int-handler.S,v 1.5 1999/08/18 23:37:46 ralf Exp $
  *
  * SNI RM200 PCI specific interrupt handler code.
  *
  * Copyright (C) 1994 - 1997 by Ralf Baechle
  */
 #include <asm/asm.h>
-#include <asm/mipsconfig.h>
 #include <asm/mipsregs.h>
 #include <asm/regdef.h>
 #include <asm/sni.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sni/io.c linux/arch/mips/sni/io.c
--- v2.3.47/linux/arch/mips/sni/io.c	Fri Sep 10 23:57:27 1999
+++ linux/arch/mips/sni/io.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: io.c,v 1.3 1999/01/04 16:03:58 ralf Exp $
+/* $Id: io.c,v 1.5 1999/10/09 00:00:59 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -8,7 +8,6 @@
  */
 #include <linux/string.h>
 #include <linux/spinlock.h>
-#include <asm/mipsconfig.h>
 #include <asm/addrspace.h>
 #include <asm/system.h>
 #include <asm/sni.h>
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sni/pci.c linux/arch/mips/sni/pci.c
--- v2.3.47/linux/arch/mips/sni/pci.c	Thu Jan  6 12:57:47 2000
+++ linux/arch/mips/sni/pci.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.7 1999/01/04 16:03:58 ralf Exp $
+/* $Id: pci.c,v 1.10 2000/02/05 06:47:09 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -6,7 +6,7 @@
  *
  * SNI specific PCI support for RM200/RM300.
  *
- * Copyright (C) 1997, 1998 Ralf Baechle
+ * Copyright (C) 1997, 1998, 1999 Ralf Baechle
  */
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -17,16 +17,18 @@
 
 #ifdef CONFIG_PCI
 
-#define mkaddr(bus, dev_fn, where)                                           \
+#define mkaddr(dev, where)                                                   \
 do {                                                                         \
-	if (bus == 0 && dev_fn >= PCI_DEVFN(8, 0))                           \
+	if ((dev)->bus->number == 0)                                         \
 		return -1;                                                   \
-	*(volatile u32 *)PCIMT_CONFIG_ADDRESS = ((bus    & 0xff) << 0x10) |  \
-	                                        ((dev_fn & 0xff) << 0x08) |  \
-	                                        (where  & 0xfc);             \
+	*(volatile u32 *)PCIMT_CONFIG_ADDRESS =                              \
+		 ((dev->bus->number    & 0xff) << 0x10) |                    \
+	         ((dev->dev_fn & 0xff) << 0x08) |                            \
+	         (where  & 0xfc);                                            \
 } while(0);
 
-static void sni_rm200_pcibios_fixup (void)
+/* To do:  Bring this uptodate ...  */
+static void pcimt_pcibios_fixup (void)
 {
 	struct pci_dev *dev;
 
@@ -65,14 +67,12 @@
  * We can't address 8 and 16 bit words directly.  Instead we have to
  * read/write a 32bit word and mask/modify the data we actually want.
  */
-static int sni_rm200_pcibios_read_config_byte (unsigned char bus,
-                                               unsigned char dev_fn,
-                                               unsigned char where,
-                                               unsigned char *val)
+static int pcimt_read_config_byte (struct pci_dev *dev,
+                                   int where, unsigned char *val)
 {
 	u32 res;
 
-	mkaddr(bus, dev_fn, where);
+	mkaddr(dev, where);
 	res = *(volatile u32 *)PCIMT_CONFIG_DATA;
 	res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff;
 	*val = res;
@@ -80,16 +80,14 @@
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int sni_rm200_pcibios_read_config_word (unsigned char bus,
-                                               unsigned char dev_fn,
-                                               unsigned char where,
-                                               unsigned short *val)
+static int pcimt_read_config_word (struct pci_dev *dev,
+                                   int where, unsigned short *val)
 {
 	u32 res;
 
 	if (where & 1)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
-	mkaddr(bus, dev_fn, where);
+	mkaddr(dev, where);
 	res = *(volatile u32 *)PCIMT_CONFIG_DATA;
 	res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff;
 	*val = res;
@@ -97,16 +95,14 @@
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int sni_rm200_pcibios_read_config_dword (unsigned char bus,
-                                                unsigned char dev_fn,
-                                                unsigned char where,
-                                                unsigned int *val)
+static int pcimt_read_config_dword (struct pci_dev *dev,
+                                    int where, unsigned int *val)
 {
 	u32 res;
 
 		if (where & 3)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
-	mkaddr(bus, dev_fn, where);
+	mkaddr(dev, where);
 	res = *(volatile u32 *)PCIMT_CONFIG_DATA;
 	res = le32_to_cpu(res);
 	*val = res;
@@ -114,51 +110,44 @@
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int sni_rm200_pcibios_write_config_byte (unsigned char bus,
-                                                unsigned char dev_fn,
-                                                unsigned char where,
-                                                unsigned char val)
+static int pcimt_write_config_byte (struct pci_dev *dev,
+                                    int where, unsigned char val)
 {
-	mkaddr(bus, dev_fn, where);
+	mkaddr(dev, where);
 	*(volatile u8 *)(PCIMT_CONFIG_DATA + (where & 3)) = val;
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int sni_rm200_pcibios_write_config_word (unsigned char bus,
-                                                unsigned char dev_fn,
-                                                unsigned char where,
-                                                unsigned short val)
+static int pcimt_write_config_word (struct pci_dev *dev,
+                                    int where, unsigned short val)
 {
 	if (where & 1)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
-	mkaddr(bus, dev_fn, where);
+	mkaddr(dev, where);
 	*(volatile u16 *)(PCIMT_CONFIG_DATA + (where & 3)) = le16_to_cpu(val);
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int sni_rm200_pcibios_write_config_dword (unsigned char bus,
-                                                 unsigned char dev_fn,
-                                                 unsigned char where,
-                                                 unsigned int val)
+static int pcimt_write_config_dword (struct pci_dev *dev,
+                                     int where, unsigned int val)
 {
 	if (where & 3)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
-	mkaddr(bus, dev_fn, where);
+	mkaddr(dev, where);
 	*(volatile u32 *)PCIMT_CONFIG_DATA = le32_to_cpu(val);
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
 struct pci_ops sni_pci_ops = {
-	sni_rm200_pcibios_fixup,
-	sni_rm200_pcibios_read_config_byte,
-	sni_rm200_pcibios_read_config_word,
-	sni_rm200_pcibios_read_config_dword,
-	sni_rm200_pcibios_write_config_byte,
-	sni_rm200_pcibios_write_config_word,
-	sni_rm200_pcibios_write_config_dword
+	pcimt_read_config_byte,
+	pcimt_read_config_word,
+	pcimt_read_config_dword,
+	pcimt_write_config_byte,
+	pcimt_write_config_word,
+	pcimt_write_config_dword
 };
 
 #endif /* CONFIG_PCI */
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sni/pcimt_scache.c linux/arch/mips/sni/pcimt_scache.c
--- v2.3.47/linux/arch/mips/sni/pcimt_scache.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/mips/sni/pcimt_scache.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: pcimt_scache.c,v 1.4 1999/01/04 16:03:59 ralf Exp $
+/* $Id: pcimt_scache.c,v 1.5 1999/10/09 00:00:59 ralf Exp $
  *
  * arch/mips/sni/pcimt_scache.c
  *
diff -u --recursive --new-file v2.3.47/linux/arch/mips/sni/setup.c linux/arch/mips/sni/setup.c
--- v2.3.47/linux/arch/mips/sni/setup.c	Sat Oct  9 11:47:50 1999
+++ linux/arch/mips/sni/setup.c	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.10 1999/01/04 16:03:59 ralf Exp $
+/* $Id: setup.c,v 1.14 2000/01/27 01:05:23 ralf Exp $
  *
  * Setup pointers to hardware-dependent routines.
  *
@@ -103,6 +103,11 @@
 	printk("%s.\n", boardtype);
 }
 
+int __init page_is_ram(unsigned long pagenr)
+{
+	return 1;
+}
+
 void __init sni_rm200_pci_setup(void)
 {
 	tag *atag;
@@ -169,6 +174,19 @@
 	ide_ops = &std_ide_ops;
 #endif
 	conswitchp = &vga_con;
+
+	screen_info = (struct screen_info) {
+		0, 0,		/* orig-x, orig-y */
+		0,		/* unused */
+		52,		/* orig_video_page */
+		3,		/* orig_video_mode */
+		80,		/* orig_video_cols */
+		4626, 3, 9,	/* unused, ega_bx, unused */
+		50,		/* orig_video_lines */
+		0x22,		/* orig_video_isVGA */
+		16		/* orig_video_points */
+	};
+
 	rtc_ops = &std_rtc_ops;
 	kbd_ops = &std_kbd_ops;
 #ifdef CONFIG_PSMOUSE
diff -u --recursive --new-file v2.3.47/linux/arch/mips/tools/offset.c linux/arch/mips/tools/offset.c
--- v2.3.47/linux/arch/mips/tools/offset.c	Tue Oct 20 13:52:55 1998
+++ linux/arch/mips/tools/offset.c	Thu Feb 24 22:52:30 2000
@@ -1,9 +1,10 @@
-/* $Id: offset.c,v 1.10 1998/08/19 21:53:53 ralf Exp $
+/* $Id: offset.c,v 1.12 1999/10/09 00:00:59 ralf Exp $
  *
  * offset.c: Calculate pt_regs and task_struct offsets.
  *
  * Copyright (C) 1996 David S. Miller
- * Made portable by Ralf Baechle
+ * Copyright (C) 1997, 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
 
 #include <linux/types.h>
@@ -82,41 +83,48 @@
 	offset("#define TASK_COUNTER       ", struct task_struct, counter);
 	offset("#define TASK_PRIORITY      ", struct task_struct, priority);
 	offset("#define TASK_MM            ", struct task_struct, mm);
+	size("#define TASK_STRUCT_SIZE   ", struct task_struct);
 	linefeed;
 }
 
 void output_thread_defines(void)
 {
 	text("/* MIPS specific thread_struct offsets. */");
-	offset("#define THREAD_REG16   ", struct task_struct, tss.reg16);
-	offset("#define THREAD_REG17   ", struct task_struct, tss.reg17);
-	offset("#define THREAD_REG18   ", struct task_struct, tss.reg18);
-	offset("#define THREAD_REG19   ", struct task_struct, tss.reg19);
-	offset("#define THREAD_REG20   ", struct task_struct, tss.reg20);
-	offset("#define THREAD_REG21   ", struct task_struct, tss.reg21);
-	offset("#define THREAD_REG22   ", struct task_struct, tss.reg22);
-	offset("#define THREAD_REG23   ", struct task_struct, tss.reg23);
-	offset("#define THREAD_REG29   ", struct task_struct, tss.reg29);
-	offset("#define THREAD_REG30   ", struct task_struct, tss.reg30);
-	offset("#define THREAD_REG31   ", struct task_struct, tss.reg31);
-	offset("#define THREAD_STATUS  ", struct task_struct, tss.cp0_status);
-	offset("#define THREAD_FPU     ", struct task_struct, tss.fpu);
-	offset("#define THREAD_BVADDR  ", struct task_struct, tss.cp0_badvaddr);
-	offset("#define THREAD_BUADDR  ", struct task_struct, tss.cp0_baduaddr);
-	offset("#define THREAD_ECODE   ", struct task_struct, tss.error_code);
-	offset("#define THREAD_TRAPNO  ", struct task_struct, tss.trap_no);
-	offset("#define THREAD_PGDIR   ", struct task_struct, tss.pg_dir);
-	offset("#define THREAD_MFLAGS  ", struct task_struct, tss.mflags);
-	offset("#define THREAD_CURDS   ", struct task_struct, tss.current_ds);
-	offset("#define THREAD_TRAMP   ", struct task_struct, tss.irix_trampoline);
-	offset("#define THREAD_OLDCTX  ", struct task_struct, tss.irix_oldctx);
+	offset("#define THREAD_REG16   ", struct task_struct, thread.reg16);
+	offset("#define THREAD_REG17   ", struct task_struct, thread.reg17);
+	offset("#define THREAD_REG18   ", struct task_struct, thread.reg18);
+	offset("#define THREAD_REG19   ", struct task_struct, thread.reg19);
+	offset("#define THREAD_REG20   ", struct task_struct, thread.reg20);
+	offset("#define THREAD_REG21   ", struct task_struct, thread.reg21);
+	offset("#define THREAD_REG22   ", struct task_struct, thread.reg22);
+	offset("#define THREAD_REG23   ", struct task_struct, thread.reg23);
+	offset("#define THREAD_REG29   ", struct task_struct, thread.reg29);
+	offset("#define THREAD_REG30   ", struct task_struct, thread.reg30);
+	offset("#define THREAD_REG31   ", struct task_struct, thread.reg31);
+	offset("#define THREAD_STATUS  ", struct task_struct, \
+	       thread.cp0_status);
+	offset("#define THREAD_FPU     ", struct task_struct, thread.fpu);
+	offset("#define THREAD_BVADDR  ", struct task_struct, \
+	       thread.cp0_badvaddr);
+	offset("#define THREAD_BUADDR  ", struct task_struct, \
+	       thread.cp0_baduaddr);
+	offset("#define THREAD_ECODE   ", struct task_struct, \
+	       thread.error_code);
+	offset("#define THREAD_TRAPNO  ", struct task_struct, thread.trap_no);
+	offset("#define THREAD_MFLAGS  ", struct task_struct, thread.mflags);
+	offset("#define THREAD_CURDS   ", struct task_struct, \
+	       thread.current_ds);
+	offset("#define THREAD_TRAMP   ", struct task_struct, \
+	       thread.irix_trampoline);
+	offset("#define THREAD_OLDCTX  ", struct task_struct, \
+	       thread.irix_oldctx);
 	linefeed;
 }
 
 void output_mm_defines(void)
 {
 	text("/* Linux mm_struct offsets. */");
-	offset("#define MM_COUNT      ", struct mm_struct, count);
+	offset("#define MM_USERS      ", struct mm_struct, mm_users);
 	offset("#define MM_PGD        ", struct mm_struct, pgd);
 	offset("#define MM_CONTEXT    ", struct mm_struct, context);
 	linefeed;
@@ -125,20 +133,17 @@
 void output_sc_defines(void)
 {
 	text("/* Linux sigcontext offsets. */");
-	offset("#define SC_REGMASK    ", struct sigcontext, sc_regmask);
-	offset("#define SC_STATUS     ", struct sigcontext, sc_status);
-	offset("#define SC_PC         ", struct sigcontext, sc_pc);
 	offset("#define SC_REGS       ", struct sigcontext, sc_regs);
 	offset("#define SC_FPREGS     ", struct sigcontext, sc_fpregs);
+	offset("#define SC_MDHI       ", struct sigcontext, sc_mdhi);
+	offset("#define SC_MDLO       ", struct sigcontext, sc_mdlo);
+	offset("#define SC_PC         ", struct sigcontext, sc_pc);
+	offset("#define SC_STATUS     ", struct sigcontext, sc_status);
 	offset("#define SC_OWNEDFP    ", struct sigcontext, sc_ownedfp);
 	offset("#define SC_FPC_CSR    ", struct sigcontext, sc_fpc_csr);
 	offset("#define SC_FPC_EIR    ", struct sigcontext, sc_fpc_eir);
-	offset("#define SC_SSFLAGS    ", struct sigcontext, sc_ssflags);
-	offset("#define SC_MDHI       ", struct sigcontext, sc_mdhi);
-	offset("#define SC_MDLO       ", struct sigcontext, sc_mdlo);
 	offset("#define SC_CAUSE      ", struct sigcontext, sc_cause);
 	offset("#define SC_BADVADDR   ", struct sigcontext, sc_badvaddr);
-	offset("#define SC_SIGSET     ", struct sigcontext, sc_sigset);
 	linefeed;
 }
 
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/Makefile linux/arch/mips64/Makefile
--- v2.3.47/linux/arch/mips64/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/Makefile	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,149 @@
+# $Id: Makefile,v 1.6 2000/01/29 01:41:59 ralf Exp $
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+
+#
+# Select the object file format to substitute into the linker script.
+#
+ifdef CONFIG_CPU_LITTLE_ENDIAN
+tool-prefix	= mips64el-linux-
+else
+tool-prefix	= mips64-linux-
+endif
+
+ifdef CONFIG_CROSSCOMPILE
+CROSS_COMPILE  = $(tool-prefix)
+endif
+
+#
+# The ELF GCC uses -G0 -mabicalls -fpic as default.  We don't need PIC
+# code in the kernel since it only slows down the whole thing.  For the
+# old GCC these options are just the defaults.  At some point we might
+# make use of global pointer optimizations.
+#
+# The DECStation requires an ECOFF kernel for remote booting, other MIPS
+# machines may also.  Since BFD is incredibly buggy with respect to
+# crossformat linking we rely on the elf2ecoff tool for format conversion.
+#
+CFLAGS		+= -mabi=64 -G 0 -mno-abicalls -fno-pic -pipe
+LINKFLAGS	+= -G 0 -static # -N
+MODFLAGS	+= -mlong-calls
+
+ifdef CONFIG_REMOTE_DEBUG
+CFLAGS		:= $(CFLAGS) -g
+endif
+
+#
+# CPU-dependent compiler/assembler options for optimization.
+#
+ifdef CONFIG_CPU_R4300
+CFLAGS		:= $(CFLAGS) -mcpu=r4300 -mips3
+endif
+ifdef CONFIG_CPU_R4X00
+CFLAGS		:= $(CFLAGS) -mcpu=r4600 -mips3
+endif
+ifdef CONFIG_CPU_R5000
+CFLAGS		:= $(CFLAGS) -mcpu=r8000 -mips4
+endif
+ifdef CONFIG_CPU_NEVADA
+CFLAGS		:= $(CFLAGS) -mcpu=r8000 -mips3 -mmad
+endif
+ifdef CONFIG_CPU_R8000
+CFLAGS		:= $(CFLAGS) -mcpu=r8000 -mips4
+endif
+ifdef CONFIG_CPU_R10000
+CFLAGS		:= $(CFLAGS) -mcpu=r8000 -mips4
+endif
+
+#
+# Board-dependent options and extra files
+#
+ifdef CONFIG_SGI_IP22
+LIBS          += arch/mips64/sgi-ip22/ip22.a arch/mips64/arc/arclib.a
+SUBDIRS       += arch/mips64/sgi-ip22 arch/mips64/arc
+#
+# Set LOADADDR to >= 0x88069000 if you want to leave space for symmon,
+# 0x88004000 for production kernels.  Note that the value must be
+# 16kb aligned or the handling of the current variable will break.
+#
+LOADADDR      += 0x88004000
+endif
+
+ifdef CONFIG_SGI_IP27
+LIBS          += arch/mips64/sgi-ip27/ip27.a arch/mips64/arc/arclib.a
+SUBDIRS       += arch/mips64/sgi-ip27 arch/mips64/arc
+#
+# Set LOADADDR to >= 0xc000000000300000 if you want to leave space for
+# symmon, 0xc00000000001c000 for production kernels.  Note that the value
+# must be 16kb aligned or the handling of the current variable will break.
+#
+#LOADADDR      += 0xa80000000001c000
+LOADADDR      += 0x8001c000
+endif
+
+#
+# Some machines like the Indy need 32-bit ELF binaries for booting purposes.
+# Other need ECOFF, so we build a 32-bit ELF binary for them which we then
+# convert to ECOFF using elf2ecoff.
+#
+ifdef CONFIG_BOOT_ELF32
+CFLAGS += -Wa,-32
+LINKFLAGS += -T arch/mips64/ld.script.elf32
+endif
+#
+# The 64-bit ELF tools are pretty broken so at this time we generate 64-bit
+# ELF files from 32-bit files by conversion.
+#
+ifdef CONFIG_BOOT_ELF64
+CFLAGS += -Wa,-32
+LINKFLAGS += -T arch/mips64/ld.script.elf32
+#AS += -64
+#LD += -m elf64bmip
+#LINKFLAGS += -T arch/mips64/ld.script.elf64
+endif
+
+LINKFLAGS += -Ttext $(LOADADDR)
+
+HEAD := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o
+
+SUBDIRS := $(addprefix arch/mips64/, tools) $(SUBDIRS) $(addprefix arch/mips64/, kernel mm lib)
+CORE_FILES := arch/mips64/kernel/kernel.o arch/mips64/mm/mm.o $(CORE_FILES)
+LIBS := arch/mips64/lib/lib.a $(LIBS)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+ifdef CONFIG_CPU_LITTLE_ENDIAN
+64bit-bfd = elf64-littlemips
+else
+64bit-bfd = elf64-bigmips
+endif
+
+vmlinux.64: vmlinux
+	$(OBJCOPY) -O $(64bit-bfd) --change-addresses=0xa7ffffff80000000 $< $@
+
+zImage: vmlinux
+	@$(MAKEBOOT) zImage
+
+compressed: zImage
+
+zdisk: vmlinux
+	@$(MAKEBOOT) zdisk
+
+archclean:
+	@$(MAKEBOOT) clean
+	$(MAKE) -C arch/$(ARCH)/kernel clean
+	$(MAKE) -C arch/$(ARCH)/tools clean
+	rm -f vmlinux.64
+
+archmrproper:
+
+archdep:
+	@$(MAKEBOOT) dep
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/Makefile linux/arch/mips64/arc/Makefile
--- v2.3.47/linux/arch/mips64/arc/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/Makefile	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,14 @@
+# $Id: Makefile,v 1.3 2000/01/17 23:32:46 ralf Exp $
+#
+# Makefile for the ARC prom monitor library routines under Linux.
+#
+
+L_TARGET = arclib.a
+L_OBJS  = console.o init.o printf.o tree.o env.o cmdline.o misc.o time.o \
+	  file.o identify.o
+
+ifdef CONFIG_ARC_MEMORY
+L_OBJS += memory.o
+endif
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/cmdline.c linux/arch/mips64/arc/cmdline.c
--- v2.3.47/linux/arch/mips64/arc/cmdline.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/cmdline.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,67 @@
+/* $Id: cmdline.c,v 1.2 1999/11/19 23:29:05 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * cmdline.c: Kernel command line creation using ARCS argc/argv.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+
+/* #define DEBUG_CMDLINE */
+
+char arcs_cmdline[CL_SIZE];
+
+char * __init prom_getcmdline(void)
+{
+	return &(arcs_cmdline[0]);
+}
+
+static char *ignored[] = {
+	"ConsoleIn=",
+	"ConsoleOut=",
+	"SystemPartition=",
+	"OSLoader=",
+	"OSLoadPartition=",
+	"OSLoadFilename="
+};
+#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0])))))
+
+void __init prom_init_cmdline(void)
+{
+	char *cp;
+	int actr, i;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = &(arcs_cmdline[0]);
+	while(actr < prom_argc) {
+		for(i = 0; i < NENTS(ignored); i++) {
+			int len = strlen(ignored[i]);
+
+			if(!strncmp(prom_argv(actr), ignored[i], len))
+				goto pic_cont;
+		}
+		/* Ok, we want it. */
+		strcpy(cp, prom_argv(actr));
+		cp += strlen(prom_argv(actr));
+		*cp++ = ' ';
+
+	pic_cont:
+		actr++;
+	}
+	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+		--cp;
+	*cp = '\0';
+
+#ifdef DEBUG_CMDLINE
+	prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0]));
+#endif
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/console.c linux/arch/mips64/arc/console.c
--- v2.3.47/linux/arch/mips64/arc/console.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/console.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,30 @@
+/* $Id: console.c,v 1.3 1999/11/19 23:29:05 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * ARC console code.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@sgi.com)
+ */
+#include <linux/init.h>
+#include <asm/sgialib.h>
+
+void __init prom_putchar(char c)
+{
+	ULONG cnt;
+	CHAR it = c;
+
+	ArcWrite(1, &it, 1, &cnt);
+}
+
+char __init prom_getchar(void)
+{
+	ULONG cnt;
+	CHAR c;
+
+	ArcRead(0, &c, 1, &cnt);
+
+	return c;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/env.c linux/arch/mips64/arc/env.c
--- v2.3.47/linux/arch/mips64/arc/env.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/env.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,28 @@
+/* $Id: env.c,v 1.4 1999/11/19 23:29:05 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * env.c: ARCS environment variable routines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/arc/types.h>
+#include <asm/sgialib.h>
+
+PCHAR __init
+ArcGetEnvironmentVariable(CHAR *name)
+{
+	return (CHAR *) ARC_CALL1(get_evar, name);
+}
+
+LONG __init
+ArcSetEnvironmentVariable(PCHAR name, PCHAR value)
+{
+	return ARC_CALL2(set_evar, name, value);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/file.c linux/arch/mips64/arc/file.c
--- v2.3.47/linux/arch/mips64/arc/file.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/file.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,76 @@
+/* $Id: file.c,v 1.3 1999/11/19 23:29:05 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * ARC firmware interface.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+
+#include <asm/arc/types.h>
+#include <asm/sgialib.h>
+
+LONG __init
+ArcGetDirectoryEntry(ULONG FileID, struct linux_vdirent *Buffer,
+                     ULONG N, ULONG *Count)
+{
+	return ARC_CALL4(get_vdirent, FileID, Buffer, N, Count);
+}
+
+LONG __init
+ArcOpen(CHAR *Path, enum linux_omode OpenMode, ULONG *FileID)
+{
+	return ARC_CALL3(open, Path, OpenMode, FileID);
+}
+
+LONG __init
+ArcClose(ULONG FileID)
+{
+	return ARC_CALL1(close, FileID);
+}
+
+LONG __init
+ArcRead(ULONG FileID, VOID *Buffer, ULONG N, ULONG *Count)
+{
+	return ARC_CALL4(read, FileID, Buffer, N, Count);
+}
+
+LONG __init
+ArcGetReadStatus(ULONG FileID)
+{
+	return ARC_CALL1(get_rstatus, FileID);
+}
+
+LONG __init
+ArcWrite(ULONG FileID, PVOID Buffer, ULONG N, PULONG Count)
+{
+	return ARC_CALL4(write, FileID, Buffer, N, Count);
+}
+
+LONG __init
+ArcSeek(ULONG FileID, struct linux_bigint *Position, enum linux_seekmode SeekMode)
+{
+	return ARC_CALL3(seek, FileID, Position, SeekMode);
+}
+
+LONG __init
+ArcMount(char *name, enum linux_mountops op)
+{
+	return ARC_CALL2(mount, name, op);
+}
+
+LONG __init
+ArcGetFileInformation(ULONG FileID, struct linux_finfo *Information)
+{
+	return ARC_CALL2(get_finfo, FileID, Information);
+}
+
+LONG __init ArcSetFileInformation(ULONG FileID, ULONG AttributeFlags,
+                                  ULONG AttributeMask)
+{
+	return ARC_CALL3(set_finfo, FileID, AttributeFlags, AttributeMask);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/identify.c linux/arch/mips64/arc/identify.c
--- v2.3.47/linux/arch/mips64/arc/identify.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/identify.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,83 @@
+/* $Id: identify.c,v 1.5 2000/01/17 23:32:46 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * identify.c: identify machine by looking up system identifier
+ *
+ * Copyright (C) 1998 Thomas Bogendoerfer
+ * 
+ * This code is based on arch/mips/sgi/kernel/system.c, which is
+ * 
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+
+struct smatch {
+	char *name;
+	int group;
+	int type;
+	int flags;
+};
+
+static struct smatch mach_table[] = {
+	{ "SGI-IP22", MACH_GROUP_SGI, MACH_SGI_INDY, PROM_FLAG_ARCS },
+	{ "SGI-IP27", MACH_GROUP_SGI, MACH_SGI_IP27, PROM_FLAG_ARCS },
+	{ "Microsoft-Jazz", MACH_GROUP_JAZZ, MACH_MIPS_MAGNUM_4000, 0 },
+	{ "PICA-61", MACH_GROUP_JAZZ, MACH_ACER_PICA_61, 0 },
+	{ "RM200PCI", MACH_GROUP_SNI_RM, MACH_SNI_RM200_PCI, 0 }
+};
+
+int prom_flags;
+
+static struct smatch * __init
+string_to_mach(char *s)
+{
+	int i;
+    
+	for (i = 0; i < sizeof (mach_table); i++) {
+		if(!strcmp(s, mach_table[i].name))
+			return &mach_table[i];
+	}
+	prom_printf("\nYeee, could not determine architecture type <%s>\n", s);
+	prom_printf("press a key to reboot\n");
+	prom_getchar();
+	ArcEnterInteractiveMode();
+
+	return NULL;
+}
+
+void __init
+prom_identify_arch(void)
+{
+	pcomponent *p;
+	struct smatch *mach;
+	const char *iname;
+
+	/* The root component tells us what machine architecture we
+	   have here.  */
+	p = ArcGetChild(PROM_NULL_COMPONENT);
+	if (p == NULL) {
+#ifdef CONFIG_SGI_IP27
+		/* IP27 PROM bisbehaves, seems to not implement ARC
+		   GetChild().  So we just assume it's an IP27.  */
+		iname = "SGI-IP27";
+#endif
+	} else
+		iname = (char *) (long) p->iname;
+
+	printk("ARCH: %s\n", iname);
+	mach = string_to_mach(iname);
+
+	mips_machgroup = mach->group;
+	mips_machtype = mach->type;
+	prom_flags = mach->flags;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/init.c linux/arch/mips64/arc/init.c
--- v2.3.47/linux/arch/mips64/arc/init.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/init.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,62 @@
+/* $Id: init.c,v 1.3 1999/11/19 23:29:05 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * PROM library initialisation code.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/config.h>
+
+#include <asm/sgialib.h>
+
+#undef DEBUG_PROM_INIT
+
+/* Master romvec interface. */
+struct linux_romvec *romvec;
+PSYSTEM_PARAMETER_BLOCK sgi_pblock;
+int prom_argc;
+LONG *_prom_argv, *_prom_envp;
+unsigned short prom_vers, prom_rev;
+
+extern void prom_testtree(void);
+
+int __init
+prom_init(int argc, char **argv, char **envp)
+{
+	PSYSTEM_PARAMETER_BLOCK pb;
+
+	romvec = ROMVECTOR;
+	pb = sgi_pblock = PROMBLOCK;
+	prom_argc = argc;
+	_prom_argv = (LONG *) argv;
+	_prom_envp = (LONG *) envp;
+
+	if(pb->magic != 0x53435241) {
+		prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic);
+		while(1)
+			;
+	}
+
+	prom_init_cmdline();
+
+	prom_vers = pb->ver;
+	prom_rev = pb->rev;
+	prom_identify_arch();
+	printk("PROMLIB: ARC firmware Version %d Revision %d\n",
+		    prom_vers, prom_rev);
+	prom_meminit();
+
+#ifdef DEBUG_PROM_INIT
+	{
+		prom_printf("Press a key to reboot\n");
+		(void) prom_getchar();
+		ArcEnterInteractiveMode();
+	}
+#endif
+	return 0;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/memory.c linux/arch/mips64/arc/memory.c
--- v2.3.47/linux/arch/mips64/arc/memory.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/memory.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,248 @@
+/* $Id: memory.c,v 1.5 2000/01/27 23:21:57 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 by David S. Miller
+ * Copyright (C) 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
+ *
+ * PROM library functions for acquiring/using memory descriptors given to us
+ * from the ARCS firmware.  This is only used when CONFIG_ARC_MEMORY is set
+ * because on some machines like SGI IP27 the ARC memory configuration data
+ * completly bogus and alternate easier to use mechanisms are available.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/swap.h>
+#include <linux/config.h>
+
+#include <asm/sgialib.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/bootinfo.h>
+
+#undef DEBUG
+
+extern char _end;
+
+struct linux_mdesc * __init
+ArcGetMemoryDescriptor(struct linux_mdesc *Current)
+{
+	return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
+}
+
+#ifdef DEBUG /* convenient for debugging */
+static char *arcs_mtypes[8] = {
+	"Exception Block",
+	"ARCS Romvec Page",
+	"Free/Contig RAM",
+	"Generic Free RAM",
+	"Bad Memory",
+	"Standlong Program Pages",
+	"ARCS Temp Storage Area",
+	"ARCS Permanent Storage Area"
+};
+
+static char *arc_mtypes[8] = {
+	"Exception Block",
+	"SystemParameterBlock",
+	"FreeMemory",
+	"Bad Memory",
+	"LoadedProgram",
+	"FirmwareTemporary",
+	"FirmwarePermanent",
+	"FreeContigiuous"
+};
+#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc]
+#endif
+
+static struct prom_pmemblock pblocks[PROM_MAX_PMEMBLOCKS];
+
+#define MEMTYPE_DONTUSE   0
+#define MEMTYPE_PROM      1
+#define MEMTYPE_FREE      2
+
+static inline int memtype_classify_arcs (union linux_memtypes type)
+{
+	switch (type.arcs) {
+	case arcs_fcontig:
+	case arcs_free:
+		return MEMTYPE_FREE;
+	case arcs_atmp:
+		return MEMTYPE_PROM;
+	case arcs_eblock:
+	case arcs_rvpage:
+	case arcs_bmem:
+	case arcs_prog:
+	case arcs_aperm:
+		return MEMTYPE_DONTUSE;
+	default:
+		BUG();
+	}
+	while(1);				/* Nuke warning.  */
+}
+
+static inline int memtype_classify_arc (union linux_memtypes type)
+{
+	switch (type.arc) {
+	case arc_free:
+	case arc_fcontig:
+		return MEMTYPE_FREE;
+	case arc_atmp:
+		return MEMTYPE_PROM;
+	case arc_eblock:
+	case arc_rvpage:
+	case arc_bmem:
+	case arc_prog:
+	case arc_aperm:
+		return MEMTYPE_DONTUSE;
+	default:
+		BUG();
+	}
+	while(1);				/* Nuke warning.  */
+}
+
+static int __init prom_memtype_classify (union linux_memtypes type)
+{
+	if (prom_flags & PROM_FLAG_ARCS)	/* SGI is ``different'' ...  */
+		return memtype_classify_arcs(type);
+
+	return memtype_classify_arc(type);
+}
+
+static inline unsigned long find_max_low_pfn(void)
+{
+	struct prom_pmemblock *p, *highest;
+	unsigned long pfn;
+
+	p = pblocks;
+	highest = 0;
+	while (p->size != 0) {
+		if (!highest || p->base > highest->base)
+			highest = p;
+		p++;
+	}
+
+	pfn = (highest->base + highest->size) >> PAGE_SHIFT;
+#ifdef DEBUG
+	prom_printf("find_max_low_pfn: 0x%lx pfns.\n", pfn);
+#endif
+	return pfn;
+}
+
+static inline struct prom_pmemblock *find_largest_memblock(void)
+{
+	struct prom_pmemblock *p, *largest;
+
+	p = pblocks;
+	largest = 0;
+	while (p->size != 0) {
+		if (!largest || p->size > largest->size)
+			largest = p;
+		p++;
+	}
+
+	return largest;
+}
+
+void __init prom_meminit(void)
+{
+	struct prom_pmemblock *largest;
+	unsigned long bootmap_size;
+	struct linux_mdesc *p;
+	int totram;
+	int i = 0;
+
+#ifdef DEBUG
+	prom_printf("ARCS MEMORY DESCRIPTOR dump:\n");
+	p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
+	while(p) {
+		prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
+			    i, p, p->base, p->pages, mtypes(p->type));
+		p = ArcGetMemoryDescriptor(p);
+		i++;
+	}
+#endif
+
+	totram = 0;
+	i = 0;
+	p = PROM_NULL_MDESC;
+	while ((p = ArcGetMemoryDescriptor(p))) {
+		pblocks[i].type = prom_memtype_classify(p->type);
+		pblocks[i].base = p->base << PAGE_SHIFT;
+		pblocks[i].size = p->pages << PAGE_SHIFT;
+
+		switch (pblocks[i].type) {
+		case MEMTYPE_FREE:
+			totram += pblocks[i].size;
+#ifdef DEBUG
+			prom_printf("free_chunk[%d]: base=%08lx size=%x\n",
+				    i, pblocks[i].base,
+				    pblocks[i].size);
+#endif
+			i++;
+			break;
+		case MEMTYPE_PROM:
+#ifdef DEBUG
+			prom_printf("prom_chunk[%d]: base=%08lx size=%x\n",
+				    i, pblocks[i].base,
+				    pblocks[i].size);
+#endif
+			i++;
+			break;
+		default:
+			break;
+		}
+	}
+	pblocks[i].size = 0;
+
+	max_low_pfn = find_max_low_pfn();
+	largest = find_largest_memblock();
+	bootmap_size = init_bootmem(largest->base >> PAGE_SHIFT, max_low_pfn);
+
+	for (i = 0; pblocks[i].size; i++)
+		if (pblocks[i].type == MEMTYPE_FREE)
+			free_bootmem(pblocks[i].base, pblocks[i].size);
+
+	/* This test is simpleminded.  It will fail if the bootmem bitmap
+	   falls into multiple adjacent ARC memory areas.  */
+	if (bootmap_size > largest->size) {
+		prom_printf("CRITIAL: overwriting PROM data.\n");
+		BUG();
+	}
+	reserve_bootmem(largest->base, bootmap_size);
+
+	printk("PROMLIB: Total free ram %dK / %dMB.\n",
+	       totram >> 10, totram >> 20);
+}
+
+void __init
+prom_free_prom_memory (void)
+{
+	struct prom_pmemblock *p;
+	unsigned long freed = 0;
+	unsigned long addr, end;
+
+	for (p = pblocks; p->size != 0; p++) {
+		if (p->type != MEMTYPE_PROM)
+			continue;
+
+		addr = PAGE_OFFSET + (unsigned long) (long) p->base;
+		end = addr + (unsigned long) (long) p->size;
+		while (addr < end) {
+			ClearPageReserved(mem_map + MAP_NR(addr));
+			set_page_count(mem_map + MAP_NR(addr), 1);
+			free_page(addr);
+			addr += PAGE_SIZE;
+			freed += PAGE_SIZE;
+		}
+	}
+	printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/misc.c linux/arch/mips64/arc/misc.c
--- v2.3.47/linux/arch/mips64/arc/misc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/misc.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,105 @@
+/* $Id: misc.c,v 1.4 2000/01/17 23:32:46 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Miscellaneous ARCS PROM routines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/bcache.h>
+
+#include <asm/arc/types.h>
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+#include <asm/system.h>
+
+extern unsigned long mips_cputype;
+extern void *sgiwd93_host;
+extern void reset_wd33c93(void *instance);
+
+VOID
+ArcHalt(VOID)
+{
+	bc_disable();
+	cli();
+#if CONFIG_SCSI_SGIWD93
+	reset_wd33c93(sgiwd93_host);
+#endif
+	ARC_CALL0(halt);
+never:	goto never;
+}
+
+VOID
+ArcPowerDown(VOID)
+{
+	bc_disable();
+	cli();
+#if CONFIG_SCSI_SGIWD93
+	reset_wd33c93(sgiwd93_host);
+#endif
+	ARC_CALL0(pdown);
+never:	goto never;
+}
+
+/* XXX is this a soft reset basically? XXX */
+VOID
+ArcRestart(VOID)
+{
+	bc_disable();
+	cli();
+#if CONFIG_SCSI_SGIWD93
+	reset_wd33c93(sgiwd93_host);
+#endif
+	ARC_CALL0(restart);
+never:	goto never;
+}
+
+VOID
+ArcReboot(VOID)
+{
+	bc_disable();
+	cli();
+#if CONFIG_SCSI_SGIWD93
+	reset_wd33c93(sgiwd93_host);
+#endif
+	ARC_CALL0(reboot);
+never:	goto never;
+}
+
+VOID
+ArcEnterInteractiveMode(VOID)
+{
+	bc_disable();
+	cli();
+#if CONFIG_SCSI_SGIWD93
+	reset_wd33c93(sgiwd93_host);
+#endif
+	ARC_CALL0(imode);
+never:	goto never;
+}
+
+LONG
+ArcSaveConfiguration(VOID)
+{
+	return ARC_CALL0(cfg_save);
+}
+
+struct linux_sysid *
+ArcGetSystemId(VOID)
+{
+	return (struct linux_sysid *) ARC_CALL0(get_sysid);
+}
+
+VOID __init
+ArcFlushAllCaches(VOID)
+{
+	ARC_CALL0(cache_flush);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/printf.c linux/arch/mips64/arc/printf.c
--- v2.3.47/linux/arch/mips64/arc/printf.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/printf.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,37 @@
+/* $Id: printf.c,v 1.2 1999/11/19 23:29:05 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Putting things on the screen using SGI arcs PROM facilities.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/sgialib.h>
+
+static char ppbuf[1024];
+
+void __init prom_printf(char *fmt, ...)
+{
+	va_list args;
+	char ch, *bptr;
+	int i;
+
+	va_start(args, fmt);
+	i = vsprintf(ppbuf, fmt, args);
+
+	bptr = ppbuf;
+
+	while((ch = *(bptr++)) != 0) {
+		if(ch == '\n')
+			prom_putchar('\r');
+
+		prom_putchar(ch);
+	}
+	va_end(args);
+	return;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/salone.c linux/arch/mips64/arc/salone.c
--- v2.3.47/linux/arch/mips64/arc/salone.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/salone.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,28 @@
+/* $Id: salone.c,v 1.3 1999/11/19 23:29:05 ralf Exp $
+ *
+ * Routines to load into memory and execute stand-along program images using
+ * ARCS PROM firmware.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+#include <asm/sgialib.h>
+
+LONG __init
+ArcLoad(CHAR *Path, ULONG TopAddr, ULONG *ExecAddr, ULONG *LowAddr)
+{
+	return ARC_CALL4(load, Path, TopAddr, ExecAddr, LowAddr);
+}
+
+LONG __init
+ArcInvoke(ULONG ExecAddr, ULONG StackAddr, ULONG Argc, CHAR *Argv[],
+          CHAR *Envp[])
+{
+	return ARC_CALL5(invoke, ExecAddr, StackAddr, Argc, Argv, Envp);
+}
+
+LONG __init
+ArcExecute(CHAR *Path, LONG Argc, CHAR *Argv[], CHAR *Envp[])
+{
+	return ARC_CALL4(exec, Path, Argc, Argv, Envp);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/time.c linux/arch/mips64/arc/time.c
--- v2.3.47/linux/arch/mips64/arc/time.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/time.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,26 @@
+/* $Id: time.c,v 1.3 1999/11/19 23:29:05 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Extracting time information from ARCS prom.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+
+#include <asm/arc/types.h>
+#include <asm/sgialib.h>
+
+struct linux_tinfo * __init
+ArcGetTime(VOID)
+{
+	return (struct linux_tinfo *) ARC_CALL0(get_tinfo);
+}
+
+ULONG __init
+ArcGetRelativeTime(VOID)
+{
+	return ARC_CALL0(get_rtime);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/arc/tree.c linux/arch/mips64/arc/tree.c
--- v2.3.47/linux/arch/mips64/arc/tree.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/arc/tree.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,130 @@
+/* $Id: tree.c,v 1.4 1999/11/19 23:29:05 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * PROM component device tree code.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <asm/arc/types.h>
+#include <asm/sgialib.h>
+
+#undef DEBUG_PROM_TREE
+
+pcomponent * __init
+ArcGetPeer(pcomponent *Current)
+{
+	if (Current == PROM_NULL_COMPONENT)
+		return PROM_NULL_COMPONENT;
+
+	return (pcomponent *) ARC_CALL1(next_component, Current);
+}
+
+pcomponent * __init
+ArcGetChild(pcomponent *Current)
+{
+	return (pcomponent *) ARC_CALL1(child_component, Current);
+}
+
+pcomponent * __init
+ArcGetParent(pcomponent *Current)
+{
+	if (Current == PROM_NULL_COMPONENT)
+		return PROM_NULL_COMPONENT;
+
+	return (pcomponent *) ARC_CALL1(parent_component, Current);
+}
+
+LONG __init
+ArcGetConfigurationData(VOID *Buffer, pcomponent *Current)
+{
+	return ARC_CALL2(component_data, Buffer, Current);
+}
+
+pcomponent * __init
+ArcAddChild(pcomponent *Current, pcomponent *Template, VOID *ConfigurationData)
+{
+	return (pcomponent *)
+	       ARC_CALL3(child_add, Current, Template, ConfigurationData);
+}
+
+LONG __init
+ArcDeleteComponent(pcomponent *ComponentToDelete)
+{
+	return ARC_CALL1(comp_del, ComponentToDelete);
+}
+
+pcomponent * __init
+ArcGetComponent(CHAR *Path)
+{
+	return (pcomponent *)ARC_CALL1(component_by_path, Path);
+}
+
+#ifdef DEBUG_PROM_TREE
+
+static char *classes[] = {
+	"system", "processor", "cache", "adapter", "controller", "peripheral",
+	"memory"
+};
+
+static char *types[] = {
+	"arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache",
+	"sccache", "memdev", "eisa adapter", "tc adapter", "scsi adapter",
+	"dti adapter", "multi-func adapter", "disk controller",
+	"tp controller", "cdrom controller", "worm controller",
+	"serial controller", "net controller", "display controller",
+	"parallel controller", "pointer controller", "keyboard controller",
+	"audio controller", "misc controller", "disk peripheral",
+	"floppy peripheral", "tp peripheral", "modem peripheral",
+	"monitor peripheral", "printer peripheral", "pointer peripheral",
+	"keyboard peripheral", "terminal peripheral", "line peripheral",
+	"net peripheral", "misc peripheral", "anonymous"
+};
+
+static char *iflags[] = {
+	"bogus", "read only", "removable", "console in", "console out",
+	"input", "output"
+};
+
+static void __init
+dump_component(pcomponent *p)
+{
+	prom_printf("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>",
+		    p, classes[p->class], types[p->type],
+		    iflags[p->iflags], p->vers, p->rev);
+	prom_printf("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n",
+		    p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname);
+}
+
+static void __init
+traverse(pcomponent *p, int op)
+{
+	dump_component(p);
+	if(ArcGetChild(p))
+		traverse(ArcGetChild(p), 1);
+	if(ArcGetPeer(p) && op)
+		traverse(ArcGetPeer(p), 1);
+}
+
+void __init
+prom_testtree(void)
+{
+	pcomponent *p;
+
+	p = ArcGetChild(PROM_NULL_COMPONENT);
+	dump_component(p);
+	p = ArcGetChild(p);
+	while(p) {
+		dump_component(p);
+		p = ArcGetPeer(p);
+	}
+	prom_printf("press a key\n");
+	prom_getchar();
+}
+
+#endif /* DEBUG_PROM_TREE  */
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/boot/Makefile linux/arch/mips64/boot/Makefile
--- v2.3.47/linux/arch/mips64/boot/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/boot/Makefile	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,43 @@
+# $Id: Makefile,v 1.2 1999/12/04 03:59:00 ralf Exp $
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995, 1998, 1999 by Ralf Baechle
+#
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+#
+# Some DECstations need all possible sections of an ECOFF executable
+#
+ifdef CONFIG_DECSTATION
+  E2EFLAGS = -a
+else
+  E2EFLAGS =
+endif
+
+all: vmlinux.ecoff addinitrd
+
+vmlinux.ecoff:	$(CONFIGURE) elf2ecoff $(TOPDIR)/vmlinux
+	./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS)
+
+elf2ecoff: elf2ecoff.c
+	$(HOSTCC) -o $@ $^
+
+addinitrd: addinitrd.c
+	$(HOSTCC) -o $@ $^
+
+# Don't build dependencies, this may die if $(CC) isn't gcc
+dep:
+
+clean:
+	rm -f vmlinux.ecoff
+
+dummy:
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/config.in linux/arch/mips64/config.in
--- v2.3.47/linux/arch/mips64/config.in	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/config.in	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,224 @@
+# $Id: config.in,v 1.14 2000/02/18 11:06:20 ulfc Exp $
+#
+# For a description of the syntax of this configuration file,
+# see the Configure script.
+#
+mainmenu_name "Linux Kernel Configuration"
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+mainmenu_option next_comment
+comment 'Machine selection'
+bool 'Support for SGI IP22' CONFIG_SGI_IP22
+bool 'Support for SGI IP27' CONFIG_SGI_IP27
+if [ "$CONFIG_SGI_IP27" = "y" ]; then
+   bool '  IP27 N-Mode' CONFIG_SGI_SN0_N_MODE
+   bool '  Discontiguous Memory Support' CONFIG_DISCONTIGMEM
+   #bool '  IP27 XXL' CONFIG_SGI_SN0_XXL
+fi
+endmenu
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   bool 'Symmetric Multi-Processing support' CONFIG_SMP
+fi
+
+#
+# Select some configuration options automatically based on user selections
+#
+unset CONFIG_BOOT_ELF32
+unset CONFIG_BOOT_ELF64
+unset CONFIG_ARC32
+unset CONFIG_ARC64
+unset CONFIG_BOARD_SCACHE
+unset CONFIG_COHERENT_IO
+unset CONFIG_BINFMT_ELF32
+unset CONFIG_PCI
+
+if [ "$CONFIG_SGI_IP22" = "y" ]; then
+   define_bool CONFIG_BOOT_ELF32 y
+   define_bool CONFIG_ARC32 y
+   define_bool CONFIG_BOARD_SCACHE y
+   define_bool CONFIG_ARC_MEMORY y
+fi
+
+if [ "$CONFIG_SGI_IP27" = "y" ]; then
+   define_bool CONFIG_BOOT_ELF64 y
+   define_bool CONFIG_ARC64 y
+   define_bool CONFIG_COHERENT_IO y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_QL_ISP_A64 y
+fi
+
+mainmenu_option next_comment
+comment 'CPU selection'
+
+choice 'CPU type'				\
+	"R4300 CONFIG_CPU_R4300			\
+	 R4x00 CONFIG_CPU_R4X00			\
+	 R5000 CONFIG_CPU_R5000			\
+	 R56x0 CONFIG_CPU_NEVADA		\
+	 R8000 CONFIG_CPU_R8000			\
+	 R10000 CONFIG_CPU_R10000" R4x00
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
+
+if [ "$CONFIG_CPU_R10000" = "y" ]; then
+   bool 'Support for large 64-bit configurations' CONFIG_MIPS_INSANE_LARGE
+fi
+bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
+
+bool 'Networking support' CONFIG_NET
+
+source drivers/pci/Config.in
+source drivers/pcmcia/Config.in
+
+bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'Sysctl support' CONFIG_SYSCTL
+tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF
+bool 'Kernel support for Linux/MIPS 32-bit binary compatibility' CONFIG_MIPS32_COMPAT
+if [ "$CONFIG_MIPS32_COMPAT" = "y" ]; then
+   define_bool CONFIG_BINFMT_ELF32 y
+fi
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+
+endmenu
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
+   bool 'Kernel module loader' CONFIG_KMOD
+fi
+
+source drivers/pci/Config.in
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   bool 'Support for frame buffer devices (EXPERIMENTAL)' CONFIG_FB
+fi
+
+endmenu
+
+source drivers/block/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+fi
+
+source drivers/telephony/Config.in
+
+mainmenu_option next_comment
+comment 'SCSI support'
+
+tristate 'SCSI support' CONFIG_SCSI
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+   source drivers/scsi/Config.in
+fi
+endmenu
+
+source drivers/i2o/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Network device support'
+
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+      if [ "$CONFIG_SGI_IP22" = "y" ]; then
+	 bool 'SGI Seeq ethernet controller support' CONFIG_SGISEEQ
+      fi
+      if [ "$CONFIG_DECSTATION" = "y" ]; then
+	 bool 'DEC LANCE ethernet controller support' CONFIG_DECLANCE
+      fi
+      if [ "$CONFIG_BAGET_MIPS" = "y" ]; then
+	 tristate 'Baget AMD LANCE support' CONFIG_BAGETLANCE
+	 tristate 'Baget Backplane Shared Memory support' CONFIG_BAGETBSM
+      fi
+      if [ "$CONFIG_ATM" = "y" ]; then
+	 source drivers/atm/Config.in
+      fi
+   fi
+   endmenu
+fi
+
+source net/ax25/Config.in
+
+source net/irda/Config.in
+
+mainmenu_option next_comment
+comment 'ISDN subsystem'
+
+if [ "$CONFIG_NET" != "n" ]; then
+   tristate 'ISDN support' CONFIG_ISDN
+   if [ "$CONFIG_ISDN" != "n" ]; then
+      source drivers/isdn/Config.in
+   fi
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+
+bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+   source drivers/cdrom/Config.in
+fi
+endmenu
+
+source drivers/char/Config.in
+
+source drivers/usb/Config.in
+
+# drivers/misc has currently only i386 specific devices.
+#source drivers/misc/Config.in
+
+source fs/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Console drivers'
+   if [ "$CONFIG_SGI_IP22" = "y" ]; then
+      tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
+      if [ "$CONFIG_SGI_NEWPORT_CONSOLE" != "y" ]; then
+	 define_bool CONFIG_DUMMY_CONSOLE y
+      fi
+   fi
+  endmenu
+fi
+
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   define_bool CONFIG_KCORE_ELF y
+fi
+
+mainmenu_option next_comment
+comment 'Sound'
+
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+   source drivers/sound/Config.in
+fi
+endmenu
+
+if [ "$CONFIG_SGI_IP22" = "y" ]; then
+   source drivers/sgi/Config.in
+fi
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool ' Build fp execption handler module' CONFIG_MIPS_FPE_MODULE
+fi
+bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+endmenu
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/defconfig linux/arch/mips64/defconfig
--- v2.3.47/linux/arch/mips64/defconfig	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/defconfig	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,395 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Machine selection
+#
+# CONFIG_SGI_IP22 is not set
+CONFIG_SGI_IP27=y
+# CONFIG_SGI_SN0_N_MODE is not set
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_BOOT_ELF64=y
+CONFIG_ARC64=y
+CONFIG_COHERENT_IO=y
+CONFIG_PCI=y
+CONFIG_QL_ISP_A64=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+CONFIG_CPU_R10000=y
+
+#
+# General setup
+#
+# CONFIG_MIPS_INSANE_LARGE is not set
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_BINFMT_ELF32=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+CONFIG_PCI_NAMES=y
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_CPQ_DA is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+# (it is safe to leave these untouched)
+#
+CONFIG_SKB_LARGE=y
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+CONFIG_ST_EXTRA_DEVS=2
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+CONFIG_SCSI_QLOGIC_ISP=y
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SEAGATE is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_SGI_IOC3_ETH=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_EISA is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring driver support
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_NLS is not set
+CONFIG_KCORE_ELF=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+CONFIG_MAGIC_SYSRQ=y
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/defconfig-ip22 linux/arch/mips64/defconfig-ip22
--- v2.3.47/linux/arch/mips64/defconfig-ip22	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/defconfig-ip22	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,321 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Machine selection
+#
+CONFIG_SGI_IP22=y
+# CONFIG_SGI_IP27 is not set
+CONFIG_BOOT_ELF32=y
+CONFIG_ARC32=y
+CONFIG_BOARD_SCACHE=y
+CONFIG_ARC_MEMORY=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_NET=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+# (it is safe to leave these untouched)
+#
+CONFIG_SKB_LARGE=y
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring driver support
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_SGISEEQ=y
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Console drivers
+#
+CONFIG_SGI_NEWPORT_CONSOLE=y
+CONFIG_KCORE_ELF=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# SGI devices
+#
+# CONFIG_SGI_SERIAL is not set
+CONFIG_SGI_DS1286=y
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/defconfig-ip27 linux/arch/mips64/defconfig-ip27
--- v2.3.47/linux/arch/mips64/defconfig-ip27	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/defconfig-ip27	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,395 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Machine selection
+#
+# CONFIG_SGI_IP22 is not set
+CONFIG_SGI_IP27=y
+# CONFIG_SGI_SN0_N_MODE is not set
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_BOOT_ELF64=y
+CONFIG_ARC64=y
+CONFIG_COHERENT_IO=y
+CONFIG_PCI=y
+CONFIG_QL_ISP_A64=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+CONFIG_CPU_R10000=y
+
+#
+# General setup
+#
+# CONFIG_MIPS_INSANE_LARGE is not set
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_BINFMT_ELF32=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+CONFIG_PCI_NAMES=y
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_CPQ_DA is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+# (it is safe to leave these untouched)
+#
+CONFIG_SKB_LARGE=y
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+CONFIG_ST_EXTRA_DEVS=2
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+CONFIG_SCSI_QLOGIC_ISP=y
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SEAGATE is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_SGI_IOC3_ETH=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_EISA is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring driver support
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_NLS is not set
+CONFIG_KCORE_ELF=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+CONFIG_MAGIC_SYSRQ=y
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/Makefile linux/arch/mips64/kernel/Makefile
--- v2.3.47/linux/arch/mips64/kernel/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/Makefile	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,30 @@
+#
+# Makefile for the Linux/MIPS kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+all:	kernel.o head.o init_task.o
+
+O_TARGET := kernel.o
+O_OBJS	:= branch.o entry.o proc.o process.o ptrace.o r4k_cache.o r4k_fpu.o \
+	   r4k_genex.o r4k_switch.o r4k_tlb_debug.o r4k_tlb_glue.o scall_64.o \
+	   semaphore.o setup.o signal.o softfp.o syscall.o traps.o unaligned.o
+OX_OBJS := mips64_ksyms.o
+
+ifdef CONFIG_MIPS32_COMPAT
+O_OBJS += linux32.o scall_o32.o signal32.o
+endif
+
+ifdef CONFIG_BINFMT_ELF32
+O_OBJS += binfmt_elf32.o
+endif
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/binfmt_elf32.c linux/arch/mips64/kernel/binfmt_elf32.c
--- v2.3.47/linux/arch/mips64/kernel/binfmt_elf32.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/binfmt_elf32.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,100 @@
+/* $Id: binfmt_elf32.c,v 1.2 2000/01/17 23:32:46 ralf Exp $
+ *
+ * Support for 32-bit Linux/MIPS ELF binaries.
+ *
+ * Copyright (C) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * Heavily inspired by the 32-bit Sparc compat code which is
+ * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek   (jj@ultra.linux.cz)
+ */
+
+#define ELF_ARCH		EM_MIPS
+#define ELF_CLASS		ELFCLASS32
+#ifdef __MIPSEB__
+#define ELF_DATA		ELFDATA2MSB;
+#else /* __MIPSEL__ */
+#define ELF_DATA		ELFDATA2LSB;
+#endif
+
+/* ELF register definitions */
+#define ELF_NGREG	45
+#define ELF_NFPREG	33
+
+typedef unsigned int elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+#define elf_check_arch(x)	((x) == EM_MIPS || (x) == EM_MIPS_RS4_BE)
+
+#define TASK32_SIZE		0x80000000UL
+#undef ELF_ET_DYN_BASE
+#define ELF_ET_DYN_BASE         (2 * TASK32_SIZE / 3)
+
+#include <asm/processor.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/elfcore.h>
+
+struct timeval32
+{
+	unsigned int tv_sec, tv_usec;
+};
+
+#define elf_prstatus elf_prstatus32
+struct elf_prstatus32
+{
+	struct elf_siginfo pr_info;	/* Info associated with signal */
+	short	pr_cursig;		/* Current signal */
+	unsigned int pr_sigpend;	/* Set of pending signals */
+	unsigned int pr_sighold;	/* Set of held signals */
+	pid_t	pr_pid;
+	pid_t	pr_ppid;
+	pid_t	pr_pgrp;
+	pid_t	pr_sid;
+	struct timeval32 pr_utime;	/* User time */
+	struct timeval32 pr_stime;	/* System time */
+	struct timeval32 pr_cutime;	/* Cumulative user time */
+	struct timeval32 pr_cstime;	/* Cumulative system time */
+	elf_gregset_t pr_reg;	/* GP registers */
+	int pr_fpvalid;		/* True if math co-processor being used.  */
+};
+
+#define elf_prpsinfo elf_prpsinfo32
+struct elf_prpsinfo32
+{
+	char	pr_state;	/* numeric process state */
+	char	pr_sname;	/* char for pr_state */
+	char	pr_zomb;	/* zombie */
+	char	pr_nice;	/* nice val */
+	unsigned int pr_flag;	/* flags */
+	u16	pr_uid;
+	u16	pr_gid;
+	pid_t	pr_pid, pr_ppid, pr_pgrp, pr_sid;
+	/* Lots missing */
+	char	pr_fname[16];	/* filename of executable */
+	char	pr_psargs[ELF_PRARGSZ];	/* initial part of arg list */
+};
+
+#define elf_addr_t	u32
+#define elf_caddr_t	u32
+#define init_elf_binfmt init_elf32_binfmt
+#undef CONFIG_BINFMT_ELF
+#ifdef CONFIG_BINFMT_ELF32
+#define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32
+#endif
+#undef CONFIG_BINFMT_ELF_MODULE
+#ifdef CONFIG_BINFMT_ELF32_MODULE
+#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE
+#endif
+
+MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit Linux/MIPS binaries");
+MODULE_AUTHOR("Ralf Baechle (ralf@oss.sgi.com)");
+
+#undef MODULE_DESCRIPTION
+#undef MODULE_AUTHOR
+
+#include "../../../fs/binfmt_elf.c"
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/branch.c linux/arch/mips64/kernel/branch.c
--- v2.3.47/linux/arch/mips64/kernel/branch.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/branch.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,194 @@
+/* $Id: branch.c,v 1.1 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Branch and jump emulation.
+ *
+ * Copyright (C) 1996, 1997 by Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <asm/branch.h>
+#include <asm/inst.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+
+/*
+ * Compute the return address and do emulate branch simulation, if required.
+ */
+int __compute_return_epc(struct pt_regs *regs)
+{
+	unsigned int *addr, bit, fcr31;
+	long epc;
+	union mips_instruction insn;
+
+	epc = regs->cp0_epc;
+	if (epc & 3) {
+		printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
+		force_sig(SIGBUS, current);
+		return -EFAULT;
+	}
+
+	/*
+	 * Read the instruction
+	 */
+	addr = (unsigned int *) epc;
+	if (__get_user(insn.word, addr)) {
+		force_sig(SIGSEGV, current);
+		return -EFAULT;
+	}
+
+	regs->regs[0] = 0;
+	switch (insn.i_format.opcode) {
+	/*
+	 * jr and jalr are in r_format format.
+	 */
+	case spec_op:
+		switch (insn.r_format.func) {
+		case jalr_op:
+			regs->regs[insn.r_format.rd] = epc + 8;
+			/* Fall through */
+		case jr_op:
+			regs->cp0_epc = regs->regs[insn.r_format.rs];
+			break;
+		}
+		break;
+
+	/*
+	 * This group contains:
+	 * bltz_op, bgez_op, bltzl_op, bgezl_op,
+	 * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
+	 */
+	case bcond_op:
+		switch (insn.i_format.rt) {
+	 	case bltz_op:
+		case bltzl_op:
+			if (regs->regs[insn.i_format.rs] < 0)
+				epc = epc + 4 + (insn.i_format.simmediate << 2);
+			else
+				epc += 8;
+			regs->cp0_epc = epc;
+			break;
+
+		case bgez_op:
+		case bgezl_op:
+			if (regs->regs[insn.i_format.rs] >= 0)
+				epc = epc + 4 + (insn.i_format.simmediate << 2);
+			else
+				epc += 8;
+			regs->cp0_epc = epc;
+			break;
+
+		case bltzal_op:
+		case bltzall_op:
+			regs->regs[31] = epc + 8;
+			if (regs->regs[insn.i_format.rs] < 0)
+				epc = epc + 4 + (insn.i_format.simmediate << 2);
+			else
+				epc += 8;
+			regs->cp0_epc = epc;
+			break;
+
+		case bgezal_op:
+		case bgezall_op:
+			regs->regs[31] = epc + 8;
+			if (regs->regs[insn.i_format.rs] >= 0)
+				epc = epc + 4 + (insn.i_format.simmediate << 2);
+			else
+				epc += 8;
+			regs->cp0_epc = epc;
+			break;
+		}
+		break;
+
+	/*
+	 * These are unconditional and in j_format.
+	 */
+	case jal_op:
+		regs->regs[31] = regs->cp0_epc + 8;
+	case j_op:
+		epc += 4;
+		epc >>= 28;
+		epc <<= 28;
+		epc |= (insn.j_format.target << 2);
+		regs->cp0_epc = epc;
+		break;
+
+	/*
+	 * These are conditional and in i_format.
+	 */
+	case beq_op:
+	case beql_op:
+		if (regs->regs[insn.i_format.rs] ==
+		    regs->regs[insn.i_format.rt])
+			epc = epc + 4 + (insn.i_format.simmediate << 2);
+		else
+			epc += 8;
+		regs->cp0_epc = epc;
+		break;
+
+	case bne_op:
+	case bnel_op:
+		if (regs->regs[insn.i_format.rs] !=
+		    regs->regs[insn.i_format.rt])
+			epc = epc + 4 + (insn.i_format.simmediate << 2);
+		else
+			epc += 8;
+		regs->cp0_epc = epc;
+		break;
+
+	case blez_op: /* not really i_format */
+	case blezl_op:
+		/* rt field assumed to be zero */
+		if (regs->regs[insn.i_format.rs] <= 0)
+			epc = epc + 4 + (insn.i_format.simmediate << 2);
+		else
+			epc += 8;
+		regs->cp0_epc = epc;
+		break;
+
+	case bgtz_op:
+	case bgtzl_op:
+		/* rt field assumed to be zero */
+		if (regs->regs[insn.i_format.rs] > 0)
+			epc = epc + 4 + (insn.i_format.simmediate << 2);
+		else
+			epc += 8;
+		regs->cp0_epc = epc;
+		break;
+
+	/*
+	 * And now the FPA/cp1 branch instructions.
+	 */
+	case cop1_op:
+		asm ("cfc1\t%0,$31":"=r" (fcr31));
+		bit = (insn.i_format.rt >> 2);
+		bit += (bit != 0);
+		bit += 23;
+		switch (insn.i_format.rt) {
+		case 0:	/* bc1f */
+		case 2:	/* bc1fl */
+			if (~fcr31 & (1 << bit))
+				epc = epc + 4 + (insn.i_format.simmediate << 2);
+			else
+				epc += 8;
+			regs->cp0_epc = epc;
+			break;
+
+		case 1:	/* bc1t */
+		case 3:	/* bc1tl */
+			if (fcr31 & (1 << bit))
+				epc = epc + 4 + (insn.i_format.simmediate << 2);
+			else
+				epc += 8;
+			regs->cp0_epc = epc;
+			break;
+		}
+		break;
+	}
+
+	return 0;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/entry.S linux/arch/mips64/kernel/entry.S
--- v2.3.47/linux/arch/mips64/kernel/entry.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/entry.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,78 @@
+/* $Id: entry.S,v 1.5 2000/02/23 00:41:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Low level exception handling
+ *
+ * Copyright (C) 1994 - 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+		.text
+		.set	noreorder
+		.align 4
+FEXPORT(ret_from_fork)
+		jal	schedule_tail
+		 move	a0, v0					# prev
+		j	ret_from_sys_call
+		 nop
+FEXPORT(handle_softirq)
+		jal	do_softirq
+		 nop
+		b	9f
+		 nop
+
+reschedule:	jal	schedule 
+		 nop
+
+FEXPORT(ret_from_sys_call)
+FEXPORT(ret_from_irq)
+#ifdef __SMP__
+#error Barffff...
+#else
+		la	t1, softirq_state
+#endif
+		lw	t0, 0 (t1)
+		lw	t1, 4 (t1)		# unused delay slot
+		and	t0, t1
+		bnez	t0, handle_softirq
+9:		 ld	t0, PT_STATUS(sp)	# returning to kernel mode?
+
+		andi	t1, t0, 0x10
+		beqz	t1, return		# -> yes
+		 ld	t1, TASK_NEED_RESCHED($28)
+		bnez	t1, reschedule
+		lw	v0, TASK_SIGPENDING($28)
+		 move	a0, zero
+		beqz	v0, return
+		 nop
+		jal	do_signal
+		 move	a1, sp
+
+FEXPORT(return)	.set	noat
+		RESTORE_ALL
+		eret
+		.set	at
+
+/*
+ * Common spurious interrupt handler.
+ */
+		.text
+		.align  5
+LEAF(spurious_interrupt)
+		/*
+		 * Someone tried to fool us by sending an interrupt but we
+		 * couldn't find a cause for it.
+		 */
+		lui     t1,%hi(spurious_count)
+		lw      t0,%lo(spurious_count)(t1)
+		addiu   t0,1
+		j	ret_from_irq
+		 sw      t0,%lo(spurious_count)(t1)
+		END(spurious_interrupt)
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/head.S linux/arch/mips64/kernel/head.S
--- v2.3.47/linux/arch/mips64/kernel/head.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/head.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,85 @@
+/* $Id: head.S,v 1.4 2000/01/25 01:35:05 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Head.S contains the MIPS exception handler and startup code.
+ *
+ * Copyright (C) 1994, 1995 Waldorf Electronics
+ * Written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#define __ASSEMBLY__
+#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/processor.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+	.text
+
+EXPORT(stext)					# used for profiling
+EXPORT(_stext)
+
+	__INIT
+
+NESTED(kernel_entry, 16, sp)			# kernel entry point
+
+#ifdef CONFIG_ARC64
+	/* We get launched at a XKPHYS address but the kernel is linked to
+	   run at a KSEG0 address, so jump there.  */
+	la	t0, 1f
+	jr	t0
+1:
+#endif
+
+	ori	sp, 0xf				# align stack on 16 byte.
+	xori	sp, 0xf
+
+	/* Note that all firmware passed argument registers still
+	   have their values.  */
+	jal	prom_init			# initialize firmware
+
+	CLI					# disable interrupts
+
+	mfc0	t0, CP0_STATUS
+	li	t1, ~(ST0_CU1|ST0_CU2|ST0_CU3)
+	and	t0, t1
+	or	t0, (ST0_CU0|ST0_KX|ST0_SX)
+	mtc0	t0, CP0_STATUS
+
+	la	$28, init_task_union		# init current pointer
+	daddiu	t0, $28, KERNEL_STACK_SIZE-32
+	sd	t0, kernelsp
+	dsubu	sp, t0, 4*SZREG			# init stack pointer
+
+	jal	start_kernel
+1:	b	1b				# just in case ...
+	END(kernel_entry)
+
+	__FINIT
+
+	.comm	kernelsp, 8, 8			# current stackpointer
+	.comm	current_pgd, 8, 8		# current page tables
+
+#define PAGE_SIZE	0x1000
+
+	.macro	page name, order=0
+	.globl	\name
+	.org	. + (PAGE_SIZE << \order)
+\name:	.size	\name, (PAGE_SIZE << \order)
+	.type	\name, @object
+	.endm
+
+	.align	12
+	.data
+
+	page	swapper_pg_dir, 1
+	page	invalid_pte_table, 1
+	page	invalid_pmd_table, 1
+	page	empty_bad_page
+	page	empty_bad_page_table
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/init_task.c linux/arch/mips64/kernel/init_task.c
--- v2.3.47/linux/arch/mips64/kernel/init_task.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/init_task.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,25 @@
+#include <linux/mm.h>
+#include <linux/sched.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+static struct vm_area_struct init_mmap = INIT_MMAP;
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+/*
+ * Initial task structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by making sure
+ * the linker maps this in the .text segment right after head.S,
+ * and making head.S ensure the proper alignment.
+ *
+ * The things we do for performance..
+ */
+union task_union init_task_union
+	__attribute__((__section__(".data.init_task"))) =
+		{ INIT_TASK(init_task_union.task) };
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/linux32.c linux/arch/mips64/kernel/linux32.c
--- v2.3.47/linux/arch/mips64/kernel/linux32.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/linux32.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,10 @@
+int sys32_newstat(void) {return 0;}
+int sys32_newlstat(void) {return 0;}
+int sys32_newfstat(void) {return 0;}
+int sys_mmap2(void) {return 0;}
+int sys_truncate64(void) {return 0;}
+int sys_ftruncate64(void) {return 0;}
+int sys_stat64(void) {return 0;}
+int sys_lstat64(void) {return 0;}
+int sys_fstat64(void) {return 0;}
+
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/mips64_ksyms.c linux/arch/mips64/kernel/mips64_ksyms.c
--- v2.3.47/linux/arch/mips64/kernel/mips64_ksyms.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/mips64_ksyms.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,115 @@
+/* $Id: mips64_ksyms.c,v 1.8 2000/02/24 00:12:41 ralf Exp $
+ *
+ * Export MIPS64-specific functions needed for loadable modules.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <linux/in6.h>
+#include <linux/pci.h>
+
+#include <asm/checksum.h>
+#include <asm/dma.h>
+#include <asm/floppy.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/softirq.h>
+#include <asm/uaccess.h>
+
+extern void *__bzero(void *__s, size_t __count);
+extern long __strncpy_from_user_nocheck_asm(char *__to,
+                                            const char *__from, long __len);
+extern long __strncpy_from_user_asm(char *__to, const char *__from,
+                                    long __len);
+extern long __strlen_user_nocheck_asm(const char *s);
+extern long __strlen_user_asm(const char *s);
+extern long __strnlen_user_nocheck_asm(const char *s);
+extern long __strnlen_user_asm(const char *s);
+
+EXPORT_SYMBOL(EISA_bus);
+
+/*
+ * String functions
+ */
+EXPORT_SYMBOL_NOVERS(memcmp);
+EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memmove);
+EXPORT_SYMBOL_NOVERS(strcat);
+EXPORT_SYMBOL_NOVERS(strchr);
+EXPORT_SYMBOL_NOVERS(strlen);
+EXPORT_SYMBOL_NOVERS(strncat);
+EXPORT_SYMBOL_NOVERS(strnlen);
+EXPORT_SYMBOL_NOVERS(strrchr);
+EXPORT_SYMBOL_NOVERS(strtok);
+EXPORT_SYMBOL_NOVERS(strpbrk);
+
+EXPORT_SYMBOL(_clear_page);
+EXPORT_SYMBOL(local_bh_count);
+EXPORT_SYMBOL(local_irq_count);
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(kernel_thread);
+
+/*
+ * Userspace access stuff.
+ */
+EXPORT_SYMBOL_NOVERS(__copy_user);
+EXPORT_SYMBOL_NOVERS(__bzero);
+EXPORT_SYMBOL_NOVERS(__strncpy_from_user_nocheck_asm);
+EXPORT_SYMBOL_NOVERS(__strncpy_from_user_asm);
+EXPORT_SYMBOL_NOVERS(__strlen_user_nocheck_asm);
+EXPORT_SYMBOL_NOVERS(__strlen_user_asm);
+EXPORT_SYMBOL_NOVERS(__strnlen_user_nocheck_asm);
+EXPORT_SYMBOL_NOVERS(__strnlen_user_asm);
+
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
+
+/*
+ * Functions to control caches.
+ */
+EXPORT_SYMBOL(_flush_page_to_ram);
+EXPORT_SYMBOL(_flush_cache_all);
+EXPORT_SYMBOL(_dma_cache_wback_inv);
+EXPORT_SYMBOL(_dma_cache_inv);
+
+EXPORT_SYMBOL(invalid_pte_table);
+
+/*
+ * Base address of ports for Intel style I/O.
+ */
+EXPORT_SYMBOL(mips_io_port_base);
+
+/*
+ * Kernel hacking ...
+ */
+#include <asm/branch.h>
+#include <linux/sched.h>
+
+int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
+int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
+
+#ifdef CONFIG_MIPS_FPE_MODULE
+EXPORT_SYMBOL(__compute_return_epc);
+EXPORT_SYMBOL(register_fpe);
+EXPORT_SYMBOL(unregister_fpe);
+#endif
+
+#ifdef CONFIG_VT
+EXPORT_SYMBOL(screen_info);
+#endif
+
+EXPORT_SYMBOL(get_wchan);
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/proc.c linux/arch/mips64/kernel/proc.c
--- v2.3.47/linux/arch/mips64/kernel/proc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/proc.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,71 @@
+/* $Id: proc.c,v 1.1 1999/09/28 22:25:51 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1999 Ralf Baechle
+ *
+ * XXX Rewrite this mess.
+ */
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/processor.h>
+#include <asm/watch.h>
+
+unsigned long unaligned_instructions;
+unsigned int vced_count, vcei_count;
+
+/*
+ * BUFFER is PAGE_SIZE bytes long.
+ *
+ * Currently /proc/cpuinfo is being abused to print data about the
+ * number of date/instruction cacheflushes.
+ */
+int get_cpuinfo(char *buffer)
+{
+	char fmt [64];
+	size_t len;
+
+	len = sprintf(buffer, "cpu\t\t\t: MIPS\n");
+#if 0
+	len += sprintf(buffer + len, "cpu model\t\t: %s V%d.%d\n",
+	               cpu_name[mips_cputype <= CPU_LAST ?
+	                        mips_cputype :
+	                        CPU_UNKNOWN],
+	               (version >> 4) & 0x0f,
+	               version & 0x0f);
+	len += sprintf(buffer + len, "system type\t\t: %s %s\n",
+		       mach_group_names[mips_machgroup],
+		       mach_group_to_name[mips_machgroup][mips_machtype]);
+#endif
+	len += sprintf(buffer + len, "BogoMIPS\t\t: %lu.%02lu\n",
+		       (loops_per_sec + 2500) / 500000,
+	               ((loops_per_sec + 2500) / 5000) % 100);
+#if defined (__MIPSEB__)
+	len += sprintf(buffer + len, "byteorder\t\t: big endian\n");
+#endif
+#if defined (__MIPSEL__)
+	len += sprintf(buffer + len, "byteorder\t\t: little endian\n");
+#endif
+	len += sprintf(buffer + len, "unaligned accesses\t: %lu\n",
+		       unaligned_instructions);
+	len += sprintf(buffer + len, "wait instruction\t: %s\n",
+	               wait_available ? "yes" : "no");
+	len += sprintf(buffer + len, "microsecond timers\t: %s\n",
+	               cyclecounter_available ? "yes" : "no");
+	len += sprintf(buffer + len, "extra interrupt vector\t: %s\n",
+	               dedicated_iv_available ? "yes" : "no");
+	len += sprintf(buffer + len, "hardware watchpoint\t: %s\n",
+	               watch_available ? "yes" : "no");
+
+	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
+	        vce_available ? "%d" : "not available");
+	len += sprintf(buffer + len, fmt, 'D', vced_count);
+	len += sprintf(buffer + len, fmt, 'I', vcei_count);
+
+	return len;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/process.c linux/arch/mips64/kernel/process.c
--- v2.3.47/linux/arch/mips64/kernel/process.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/process.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,213 @@
+/* $Id: process.c,v 1.5 2000/01/29 01:41:59 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999 by Ralf Baechle and others.
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/mman.h>
+#include <linux/sys.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+
+#include <asm/bootinfo.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mipsregs.h>
+#include <asm/processor.h>
+#include <asm/stackframe.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/elf.h>
+
+asmlinkage int cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	current->priority = 0;
+	current->counter = -100;
+	while (1) {
+		while (!current->need_resched)
+			if (wait_available)
+				__asm__("wait");
+		schedule();
+		check_pgt_cache();
+	}
+}
+
+struct task_struct *last_task_used_math = NULL;
+
+asmlinkage void ret_from_fork(void);
+
+void exit_thread(void)
+{
+	/* Forget lazy fpu state */
+	if (last_task_used_math == current) {
+		set_cp0_status(ST0_CU1, ST0_CU1);
+		__asm__ __volatile__("cfc1\t$0,$31");
+		last_task_used_math = NULL;
+	}
+}
+
+void flush_thread(void)
+{
+	/* Forget lazy fpu state */
+	if (last_task_used_math == current) {
+		set_cp0_status(ST0_CU1, ST0_CU1);
+		__asm__ __volatile__("cfc1\t$0,$31");
+		last_task_used_math = NULL;
+	}
+}
+
+int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+                 struct task_struct * p, struct pt_regs * regs)
+{
+	struct pt_regs * childregs;
+	long childksp;
+
+	childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32;
+
+	if (last_task_used_math == current) {
+		set_cp0_status(ST0_CU1, ST0_CU1);
+		save_fp(p);
+	}
+	/* set up new TSS. */
+	childregs = (struct pt_regs *) childksp - 1;
+	*childregs = *regs;
+	childregs->regs[7] = 0;	/* Clear error flag */
+	if (current->personality == PER_LINUX) {
+		childregs->regs[2] = 0;	/* Child gets zero as return value */
+		regs->regs[2] = p->pid;
+	} else {
+		/* Under IRIX things are a little different. */
+		childregs->regs[2] = 0;
+		childregs->regs[3] = 1;
+		regs->regs[2] = p->pid;
+		regs->regs[3] = 0;
+	}
+	if (childregs->cp0_status & ST0_CU0) {
+		childregs->regs[28] = (unsigned long) p;
+		childregs->regs[29] = childksp;
+		p->thread.current_ds = KERNEL_DS;
+	} else {
+		childregs->regs[29] = usp;
+		p->thread.current_ds = USER_DS;
+	}
+	p->thread.reg29 = (unsigned long) childregs;
+	p->thread.reg31 = (unsigned long) ret_from_fork;
+
+	/*
+	 * New tasks loose permission to use the fpu. This accelerates context
+	 * switching for most programs since they don't use the fpu.
+	 */
+	p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) &
+                            ~(ST0_CU3|ST0_CU2|ST0_CU1|ST0_KSU);
+	childregs->cp0_status &= ~(ST0_CU3|ST0_CU2|ST0_CU1);
+
+	return 0;
+}
+
+/* Fill in the fpu structure for a core dump.. */
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
+{
+	/* We actually store the FPU info in the task->thread
+	 * area.
+	 */
+	if(regs->cp0_status & ST0_CU1) {
+		memcpy(r, &current->thread.fpu, sizeof(current->thread.fpu));
+		return 1;
+	}
+	return 0; /* Task didn't use the fpu at all. */
+}
+
+/* Fill in the user structure for a core dump.. */
+void dump_thread(struct pt_regs *regs, struct user *dump)
+{
+	dump->magic = CMAGIC;
+	dump->start_code  = current->mm->start_code;
+	dump->start_data  = current->mm->start_data;
+	dump->start_stack = regs->regs[29] & ~(PAGE_SIZE - 1);
+	dump->u_tsize = (current->mm->end_code - dump->start_code)
+	                >> PAGE_SHIFT;
+	dump->u_dsize = (current->mm->brk + (PAGE_SIZE - 1) - dump->start_data)
+	                >> PAGE_SHIFT;
+	dump->u_ssize = (current->mm->start_stack - dump->start_stack +
+	                 PAGE_SIZE - 1) >> PAGE_SHIFT;
+	memcpy(&dump->regs[0], regs, sizeof(struct pt_regs));
+	memcpy(&dump->regs[EF_SIZE/4], &current->thread.fpu,
+	       sizeof(current->thread.fpu));
+}
+
+/*
+ * Create a kernel thread
+ */
+int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+	int retval;
+
+	__asm__ __volatile__(
+		"move\t$6, $sp\n\t"
+		"move\t$4, %5\n\t"
+		"li\t$2, %1\n\t"
+		"syscall\n\t"
+		"beq\t$6, $sp, 1f\n\t"
+		"move\t$4, %3\n\t"
+		"jalr\t%4\n\t"
+		"move\t$4, $2\n\t"
+		"li\t$2, %2\n\t"
+		"syscall\n"
+		"1:\tmove\t%0, $2"
+		:"=r" (retval)
+		:"i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn),
+		 "r" (flags | CLONE_VM)
+
+		 /* The called subroutine might have destroyed any of the
+		  * at, result, argument or temporary registers ...  */
+		:"$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8",
+		 "$9","$10","$11","$12","$13","$14","$15","$24","$25");
+
+	return retval;
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long schedule_frame;
+	unsigned long pc;
+
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	pc = thread_saved_pc(&p->thread);
+	if (pc == (unsigned long) interruptible_sleep_on
+	    || pc == (unsigned long) sleep_on) {
+		schedule_frame = ((unsigned long *)p->thread.reg30)[9];
+		return ((unsigned long *)schedule_frame)[15];
+	}
+	if (pc == (unsigned long) interruptible_sleep_on_timeout
+	    || pc == (unsigned long) sleep_on_timeout) {
+		schedule_frame = ((unsigned long *)p->thread.reg30)[9];
+		return ((unsigned long *)schedule_frame)[16];
+	}
+	if (pc >= first_sched && pc < last_sched) {
+		printk(KERN_DEBUG "Bug in %s\n", __FUNCTION__);
+	}
+
+	return pc;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/ptrace.c linux/arch/mips64/kernel/ptrace.c
--- v2.3.47/linux/arch/mips64/kernel/ptrace.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/ptrace.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,37 @@
+/* $Id: ptrace.c,v 1.1 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 Ross Biro
+ * Copyright (C) Linus Torvalds
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller
+ *
+ * At this time Linux/MIPS64 only supports syscall tracing, even for 32-bit
+ * binaries.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+
+asmlinkage void syscall_trace(void)
+{
+	if ((current->flags & (PF_PTRACED|PF_TRACESYS))
+			!= (PF_PTRACED|PF_TRACESYS))
+		return;
+	current->exit_code = SIGTRAP;
+	current->state = TASK_STOPPED;
+	notify_parent(current, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/r4k_cache.S linux/arch/mips64/kernel/r4k_cache.S
--- v2.3.47/linux/arch/mips64/kernel/r4k_cache.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/r4k_cache.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,28 @@
+/* $Id: r4k_cache.S,v 1.1 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 - 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * Cache error handler
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+/*
+ * Game over.  Go to the button.  Press gently.  Swear where allowed by
+ * legislation.
+ */
+	LEAF(except_vec2_generic)
+	/* Famous last words: unreached */
+	mfc0	a1,CP0_ERROREPC
+	PRINT("Cache error exception: c0_errorepc == %08x\n")
+1:
+	j	1b
+	 nop
+	END(except_vec2_generic)
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/r4k_fpu.S linux/arch/mips64/kernel/r4k_fpu.S
--- v2.3.47/linux/arch/mips64/kernel/r4k_fpu.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/r4k_fpu.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,149 @@
+/* $Id: r4k_fpu.S,v 1.1 1999/09/28 22:25:52 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Save/restore floating point context for signal handlers.
+ *
+ * Copyright (C) 1996, 1998, 1999 by Ralf Baechle
+ *
+ * Multi-arch abstraction and asm macros for easier reading:
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/errno.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+	.macro	EX insn, reg, src
+	.set	push
+	.set	nomacro
+.ex\@:	\insn	\reg, \src
+	.set	pop
+	.section __ex_table,"a"
+	PTR	.ex\@, fault
+	.previous
+	.endm
+
+	.set	noreorder
+	/* Save floating point context */
+LEAF(save_fp_context)
+	mfc0	t1,CP0_STATUS
+	 sll	t2,t1,5
+
+	bgez	t2,1f
+	 cfc1	t1,fcr31
+	/* Store the 16 odd double precision registers */
+	EX	sdc1 $f1, SC_FPREGS+8(a0)
+	EX	sdc1 $f3, SC_FPREGS+24(a0)
+	EX	sdc1 $f5, SC_FPREGS+40(a0)
+	EX	sdc1 $f7, SC_FPREGS+56(a0)
+	EX	sdc1 $f9, SC_FPREGS+72(a0)
+	EX	sdc1 $f11, SC_FPREGS+88(a0)
+	EX	sdc1 $f13, SC_FPREGS+104(a0)
+	EX	sdc1 $f15, SC_FPREGS+120(a0)
+	EX	sdc1 $f17, SC_FPREGS+136(a0)
+	EX	sdc1 $f19, SC_FPREGS+152(a0)
+	EX	sdc1 $f21, SC_FPREGS+168(a0)
+	EX	sdc1 $f23, SC_FPREGS+184(a0)
+	EX	sdc1 $f25, SC_FPREGS+200(a0)
+	EX	sdc1 $f27, SC_FPREGS+216(a0)
+	EX	sdc1 $f29, SC_FPREGS+232(a0)
+	EX	sdc1 $f31, SC_FPREGS+248(a0)
+
+	/* Store the 16 even double precision registers */
+1:
+	EX	sdc1 $f0, SC_FPREGS+0(a0)
+	EX	sdc1 $f2, SC_FPREGS+16(a0)
+	EX	sdc1 $f4, SC_FPREGS+32(a0)
+	EX	sdc1 $f6, SC_FPREGS+48(a0)
+	EX	sdc1 $f8, SC_FPREGS+64(a0)
+	EX	sdc1 $f10, SC_FPREGS+80(a0)
+	EX	sdc1 $f12, SC_FPREGS+96(a0)
+	EX	sdc1 $f14, SC_FPREGS+112(a0)
+	EX	sdc1 $f16, SC_FPREGS+128(a0)
+	EX	sdc1 $f18, SC_FPREGS+144(a0)
+	EX	sdc1 $f20, SC_FPREGS+160(a0)
+	EX	sdc1 $f22, SC_FPREGS+176(a0)
+	EX	sdc1 $f24, SC_FPREGS+192(a0)
+	EX	sdc1 $f26, SC_FPREGS+208(a0)
+	EX	sdc1 $f28, SC_FPREGS+224(a0)
+	EX	sdc1 $f30, SC_FPREGS+240(a0)
+	EX	sw t1, SC_FPC_CSR(a0)
+	cfc1	t0,$0				# implementation/version
+	EX	sw t0,SC_FPC_EIR(a0)
+
+	jr	ra
+	 li	v0, 0					# success
+	END(save_fp_context)
+
+/*
+ * Restore FPU state:
+ *  - fp gp registers
+ *  - cp1 status/control register
+ *
+ * We base the decision which registers to restore from the signal stack
+ * frame on the current content of c0_status, not on the content of the
+ * stack frame which might have been changed by the user.
+ */
+LEAF(restore_fp_context)
+	mfc0	t1, CP0_STATUS
+	sll	t0,t1,5
+	bgez	t0,1f
+	 EX	lw t0, SC_FPC_CSR(a0)
+
+	/* Restore the 16 odd double precision registers only
+	 * when enabled in the cp0 status register.
+	 */
+	EX	ldc1 $f1, SC_FPREGS+8(a0)
+	EX	ldc1 $f3, SC_FPREGS+24(a0)
+	EX	ldc1 $f5, SC_FPREGS+40(a0)
+	EX	ldc1 $f7, SC_FPREGS+56(a0)
+	EX	ldc1 $f9, SC_FPREGS+72(a0)
+	EX	ldc1 $f11, SC_FPREGS+88(a0)
+	EX	ldc1 $f13, SC_FPREGS+104(a0)
+	EX	ldc1 $f15, SC_FPREGS+120(a0)
+	EX	ldc1 $f17, SC_FPREGS+136(a0)
+	EX	ldc1 $f19, SC_FPREGS+152(a0)
+	EX	ldc1 $f21, SC_FPREGS+168(a0)
+	EX	ldc1 $f23, SC_FPREGS+184(a0)
+	EX	ldc1 $f25, SC_FPREGS+200(a0)
+	EX	ldc1 $f27, SC_FPREGS+216(a0)
+	EX	ldc1 $f29, SC_FPREGS+232(a0)
+	EX	ldc1 $f31, SC_FPREGS+248(a0)
+
+	/*
+	 * Restore the 16 even double precision registers
+	 * when cp1 was enabled in the cp0 status register.
+	 */
+1:	EX	ldc1 $f0, SC_FPREGS+0(a0)
+	EX	ldc1 $f2, SC_FPREGS+16(a0)
+	EX	ldc1 $f4, SC_FPREGS+32(a0)
+	EX	ldc1 $f6, SC_FPREGS+48(a0)
+	EX	ldc1 $f8, SC_FPREGS+64(a0)
+	EX	ldc1 $f10, SC_FPREGS+80(a0)
+	EX	ldc1 $f12, SC_FPREGS+96(a0)
+	EX	ldc1 $f14, SC_FPREGS+112(a0)
+	EX	ldc1 $f16, SC_FPREGS+128(a0)
+	EX	ldc1 $f18, SC_FPREGS+144(a0)
+	EX	ldc1 $f20, SC_FPREGS+160(a0)
+	EX	ldc1 $f22, SC_FPREGS+176(a0)
+	EX	ldc1 $f24, SC_FPREGS+192(a0)
+	EX	ldc1 $f26, SC_FPREGS+208(a0)
+	EX	ldc1 $f28, SC_FPREGS+224(a0)
+	EX	ldc1 $f30, SC_FPREGS+240(a0)
+	ctc1	t0,fcr31
+	jr	ra
+	 li	v0, 0					# success
+	END(restore_fp_context)
+
+	.type	fault@function
+	.ent	fault
+fault:	li	v0, -EFAULT
+	jr	ra
+	.end	fault
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/r4k_genex.S linux/arch/mips64/kernel/r4k_genex.S
--- v2.3.47/linux/arch/mips64/kernel/r4k_genex.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/r4k_genex.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,168 @@
+/* $Id: r4k_genex.S,v 1.3 2000/01/20 23:32:21 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics
+ *
+ * Low level exception handling
+ */
+#define __ASSEMBLY__
+#include <linux/init.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/r4kcacheops.h>
+
+	.macro	__build_clear_none
+	.endm
+
+	.macro	__build_clear_sti
+	STI
+	.endm
+
+	.macro	__build_clear_cli
+	CLI
+	.endm
+
+	.macro	__build_clear_fpe
+	cfc1	a1, fcr31
+	li	a2, ~(0x3f << 13)
+	and	a2, a1
+	ctc1	a2, fcr31
+	STI
+	.endm
+
+	.macro	__build_clear_ade
+	dmfc0	t0, CP0_BADVADDR
+	sd	t0, PT_BVADDR(sp)
+	KMODE
+	.endm
+
+	.macro	__BUILD_silent exception
+	.endm
+
+	/* Gas tries to parse the PRINT argument as a string containing
+	   string escapes and emits bogus warnings if it believes to
+	   recognize an unknown escape code.  So make the arguments
+	   start with an n and gas will believe \n is ok ...  */
+	.macro	__BUILD_verbose	nexception
+	ld	a1, PT_EPC(sp)
+	PRINT("Got \nexception at %016lx\012")
+	.endm
+
+	.macro	__BUILD_count exception
+	.set	reorder
+	ld	t0,exception_count_\exception
+	daddiu	t0, 1
+	sd	t0,exception_count_\exception
+	.set	noreorder
+	.comm	exception_count\exception, 8, 8
+	.endm
+
+	.macro	BUILD_HANDLER exception handler clear verbose
+	.align	5
+	NESTED(handle_\exception, PT_SIZE, sp)
+	.set	noat
+	SAVE_ALL
+	__BUILD_clear_\clear
+	.set	at
+	__BUILD_\verbose \exception
+	move	a0, sp
+	jal	do_\handler
+	j	ret_from_sys_call
+	 nop
+	END(handle_\exception)
+	.endm
+
+	BUILD_HANDLER adel ade ade silent		/* #4  */
+	BUILD_HANDLER ades ade ade silent		/* #5  */
+	BUILD_HANDLER ibe ibe cli silent		/* #6  */
+	BUILD_HANDLER dbe dbe cli silent		/* #7  */
+	BUILD_HANDLER bp bp sti silent			/* #9  */
+	BUILD_HANDLER ri ri sti silent			/* #10 */
+	BUILD_HANDLER cpu cpu sti silent		/* #11 */
+	BUILD_HANDLER ov ov sti silent			/* #12 */
+	BUILD_HANDLER tr tr sti silent			/* #13 */
+	BUILD_HANDLER fpe fpe fpe silent		/* #15 */
+	BUILD_HANDLER watch watch sti verbose		/* #23 */
+	BUILD_HANDLER reserved reserved sti verbose	/* others */
+
+	__INIT
+
+/* General exception handler for CPUs with virtual coherency exception.
+ *
+ * Be careful when changing this, it has to be at most 128 bytes to fit
+ * into space reserved for the exception handler.
+ */
+	NESTED(except_vec3_r4000, 0, sp)
+	.set	noat
+	mfc0	k1, CP0_CAUSE
+	andi	k1, k1, 0x7c
+	li	k0, 31<<2
+	beq	k1, k0, handle_vced
+	 li	k0, 14<<2
+	beq	k1, k0, handle_vcei
+	 dsll	k1, k1, 1
+	ld	k0, exception_handlers(k1)
+	jr	k0
+
+/*
+ * Big shit, we now may have two dirty primary cache lines for the same
+ * physical address.  We can savely invalidate the line pointed to by
+ * c0_badvaddr because after return from this exception handler the load /
+ * store will be re-executed.
+ */
+handle_vced:
+	mfc0	k0, CP0_BADVADDR
+	li	k1, -4					# Is this ...
+	and	k0, k1					# ... really needed?
+	mtc0	zero, CP0_TAGLO
+	cache	Index_Store_Tag_D,(k0)
+	cache	Hit_Writeback_Inv_SD,(k0)
+	lui	k0, %hi(vced_count)
+	lw	k1, %lo(vced_count)(k0)
+	addiu	k1, 1
+	sw	k1, %lo(vced_count)(k0)
+	eret
+
+handle_vcei:
+	mfc0	k0, CP0_BADVADDR
+	cache	Hit_Writeback_Inv_SD,(k0)		# also cleans pi
+	lui	k0, %hi(vcei_count)
+	lw	k1, %lo(vcei_count)(k0)
+	addiu	k1, 1
+	sw	k1, %lo(vcei_count)(k0)
+	eret
+
+	END(except_vec3_r4000)
+	.set	at
+
+	/* General exception vector for all other CPUs. */
+	NESTED(except_vec3_generic, 0, sp)
+	.set	noat
+	mfc0	k1, CP0_CAUSE
+	andi	k1, k1, 0x7c
+	dsll	k1, k1, 1
+	ld	k0, exception_handlers(k1)
+	jr	k0
+	 nop
+	END(except_vec3_generic)
+	.set	at
+
+/*
+ * Special interrupt vector for embedded MIPS.  This is a dedicated interrupt
+ * vector which reduces interrupt processing overhead.  The jump instruction
+ * will be inserted here at initialization time.  This handler may only be 8
+ * bytes in size!
+ */
+NESTED(except_vec4, 0, sp)
+1:	j	1b			/* Dummy, will be replaced */
+	 nop
+	END(except_vec4)
+
+	__FINIT
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/r4k_switch.S linux/arch/mips64/kernel/r4k_switch.S
--- v2.3.47/linux/arch/mips64/kernel/r4k_switch.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/r4k_switch.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,170 @@
+/* $Id: r4k_switch.S,v 1.1 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1994, 1995, 1996, by Andreas Busse
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/current.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/offset.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#include <asm/asmmacro.h>
+
+	.set	mips3
+
+/*
+ * task_struct *resume(task_struct *prev, task_struct *next)
+ */
+	.set	noreorder
+	.align	5
+	LEAF(resume)
+	mfc0	t1, CP0_STATUS
+	sd	t1, THREAD_STATUS(a0)
+	cpu_save_nonscratch a0
+	sd	ra, THREAD_REG31(a0)
+
+	/*
+	 * The order of restoring the registers takes care of the race
+	 * updating $28, $29 and kernelsp without disabling ints.
+	 */
+	move	$28, a1
+	cpu_restore_nonscratch $28
+	daddiu	t0, $28, KERNEL_STACK_SIZE-32
+	sd	t0, kernelsp
+	mfc0	t1, CP0_STATUS		/* Do we really need this? */
+	li	a3, 0xff00
+	and	t1, a3
+	ld	a2, THREAD_STATUS($28)
+	nor	a3, $0, a3
+	and	a2, a3
+	or	a2, t1
+	mtc0	a2, CP0_STATUS
+	jr	ra
+	 move	v0, a0
+	END(resume)
+
+/*
+ * Do lazy fpu context switch.  Saves FPU context to the process in a0
+ * and loads the new context of the current process.
+ */
+
+#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS)
+
+LEAF(lazy_fpu_switch)
+	mfc0	t0, CP0_STATUS			# enable cp1
+	li	t3, 0x20000000
+	or	t0, t3
+	mtc0	t0, CP0_STATUS
+
+	beqz	a0, 2f				# Save floating point state
+	 nor	t3, zero, t3
+
+	lw	t1, ST_OFF(a0)			# last thread looses fpu
+	and	t1, t3
+	sd	t1, ST_OFF(a0)
+	sll	t2, t1, 5
+	bgez	t2, 1f
+	 sdc1	$f0, (THREAD_FPU + 0x00)(a0)
+	fpu_save_16odd a0
+1:
+	fpu_save_16even a0 t1			# clobbers t1
+2:
+
+	sll	t0, t0, 5			# load new fp state
+	bgez	t0, 1f
+	 ldc1	$f0, (THREAD_FPU + 0x00)($28)
+	fpu_restore_16odd $28
+1:
+	.set	reorder
+	fpu_restore_16even $28, t0		# clobbers t0
+	jr	ra
+	END(lazy_fpu_switch)
+
+/*
+ * Save a thread's fp context.
+ */
+	.set	noreorder
+LEAF(save_fp)
+	mfc0	t0, CP0_STATUS
+	sll	t1, t0, 5
+	bgez	t1, 1f				# 16 register mode?
+	 nop
+	fpu_save_16odd a0
+1:
+	fpu_save_16even a0 t1			# clobbers t1
+	jr	ra
+	 sdc1	$f0, (THREAD_FPU + 0x00)(a0)
+	END(save_fp)
+
+/*
+ * Load the FPU with signalling NANS.  This bit pattern we're using has
+ * the property that no matter whether considered as single or as double
+ * precision represents signaling NANS.
+ *
+ * We initialize fcr31 to rounding to nearest, no exceptions.
+ */
+
+#define FPU_DEFAULT  0x00000000
+
+LEAF(init_fpu)
+	mfc0	t0, CP0_STATUS
+	li	t1, 0x20000000
+	or	t0, t1
+	mtc0	t0, CP0_STATUS
+	sll	t0, t0, 5
+
+	li	t1, FPU_DEFAULT
+	ctc1	t1, fcr31
+
+	bgez	t0, 1f				# 16 / 32 register mode?
+	 li	t0, -1
+
+	dmtc1	t0, $f1
+	dmtc1	t0, $f3
+	dmtc1	t0, $f5
+	dmtc1	t0, $f7
+	dmtc1	t0, $f9
+	dmtc1	t0, $f11
+	dmtc1	t0, $f13
+	dmtc1	t0, $f15
+	dmtc1	t0, $f17
+	dmtc1	t0, $f19
+	dmtc1	t0, $f21
+	dmtc1	t0, $f23
+	dmtc1	t0, $f25
+	dmtc1	t0, $f27
+	dmtc1	t0, $f29
+	dmtc1	t0, $f31
+
+1:	dmtc1	t0, $f0
+	dmtc1	t0, $f2
+	dmtc1	t0, $f4
+	dmtc1	t0, $f6
+	dmtc1	t0, $f8
+	dmtc1	t0, $f10
+	dmtc1	t0, $f12
+	dmtc1	t0, $f14
+	dmtc1	t0, $f16
+	dmtc1	t0, $f18
+	dmtc1	t0, $f20
+	dmtc1	t0, $f22
+	dmtc1	t0, $f24
+	dmtc1	t0, $f26
+	dmtc1	t0, $f28
+	jr	ra
+	 dmtc1	t0, $f30
+	END(init_fpu)
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/r4k_tlb_debug.c linux/arch/mips64/kernel/r4k_tlb_debug.c
--- v2.3.47/linux/arch/mips64/kernel/r4k_tlb_debug.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/r4k_tlb_debug.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,72 @@
+/* $Id: r4k_tlb_debug.c,v 1.3 2000/01/29 01:41:59 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * TLB debugging routines.  These perform horribly slow but can easily be
+ * modified for debugging purposes.
+ */
+#include <linux/linkage.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
+                              unsigned long address);
+
+asmlinkage void tlb_refill_debug(struct pt_regs regs)
+{
+	show_regs(&regs);
+	panic(__FUNCTION__ " called.  This Does Not Happen (TM).");
+}
+
+asmlinkage void xtlb_refill_debug(struct pt_regs *regs)
+{
+	unsigned long addr;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	addr = regs->cp0_badvaddr & ~((PAGE_SIZE << 1) - 1);
+	pgd = pgd_offset(current->active_mm, addr);
+	pmd = pmd_offset(pgd, addr);
+	pte = pte_offset(pmd, addr);
+
+	set_entrylo0(pte_val(pte[0]) >> 6);
+	set_entrylo1(pte_val(pte[1]) >> 6);
+	__asm__ __volatile__("nop;nop;nop");
+
+	tlb_write_random();
+}
+
+asmlinkage void xtlb_mod_debug(struct pt_regs *regs)
+{
+	unsigned long addr;
+
+	addr = regs->cp0_badvaddr;
+	do_page_fault(regs, 1, addr);
+}
+
+asmlinkage void xtlb_tlbl_debug(struct pt_regs *regs)
+{
+	unsigned long addr;
+
+	addr = regs->cp0_badvaddr;
+	do_page_fault(regs, 0, addr);
+}
+
+asmlinkage void xtlb_tlbs_debug(struct pt_regs *regs)
+{
+	unsigned long addr;
+
+	addr = regs->cp0_badvaddr;
+	do_page_fault(regs, 1, addr);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/r4k_tlb_glue.S linux/arch/mips64/kernel/r4k_tlb_glue.S
--- v2.3.47/linux/arch/mips64/kernel/r4k_tlb_glue.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/r4k_tlb_glue.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,42 @@
+/* $Id: r4k_tlb_glue.S,v 1.2 2000/01/17 23:32:46 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#define __ASSEMBLY__
+#include <linux/init.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	__INIT
+NESTED(__xtlb_refill_debug_tramp, PT_SIZE, sp)
+	j	__xtlb_refill_debug
+	END(__xtlb_refill_debug_tramp)
+
+NESTED(__tlb_refill_debug_tramp, PT_SIZE, sp)
+	j	__tlb_refill_debug
+	END(__tlb_refill_debug_tramp)
+	__FINIT
+
+	.macro	tlb_handler name
+	NESTED(__\name, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	dmfc0	t0, CP0_BADVADDR
+	sd	t0, PT_BVADDR(sp)
+	move	a0, sp
+	jal	\name
+	j	return
+	END(__\name)
+	.endm
+
+	tlb_handler	tlb_refill_debug
+	tlb_handler	xtlb_refill_debug
+	tlb_handler	xtlb_mod_debug
+	tlb_handler	xtlb_tlbl_debug
+	tlb_handler	xtlb_tlbs_debug
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/scall_64.S linux/arch/mips64/kernel/scall_64.S
--- v2.3.47/linux/arch/mips64/kernel/scall_64.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/scall_64.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,347 @@
+/* $Id: scall_64.S,v 1.7 2000/02/23 00:41:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <asm/asm.h>
+#include <linux/errno.h>
+#include <asm/current.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/unistd.h>
+
+/* This duplicates the definition from <linux/sched.h> */
+#define PF_TRACESYS	0x00000020	/* tracing system calls */
+
+/* This duplicates the definition from <asm/signal.h> */
+#define SIGILL		4		/* Illegal instruction (ANSI).  */
+
+/* Highest syscall handled here.  */
+#define MAX_SYSCALL_NO	__NR_Linux + __NR_Linux_syscalls
+
+#ifndef CONFIG_MIPS32_COMPAT
+#define handle_sys64 handle_sys
+#endif
+
+	.align  5
+NESTED(handle_sys64, PT_SIZE, sp)
+/* When 32-bit compatibility is configured scall_o32.S already did this.  */
+#ifndef CONFIG_MIPS32_COMPAT
+	.set	noat
+	SAVE_SOME
+	.set	at
+#endif
+	ld	t1, PT_EPC(sp)		# skip syscall on return
+
+	sltiu	t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
+	daddiu	t1, 4			# skip to next instruction
+	beqz	t0, illegal_syscall
+	sd	t1, PT_EPC(sp)
+
+	dsll	t0, v0, 3
+	ld	t2, (sys_call_table - (__NR_Linux * 8))(t0) # syscall routine
+	beqz	t2, illegal_syscall;
+
+	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
+
+	ld	t0, TASK_FLAGS($28)	# syscall tracing enabled?
+	andi	t0, PF_TRACESYS
+	bnez	t0, trace_a_syscall
+
+	jalr	t2			# Do The Real Thing (TM)
+
+	li	t0, -EMAXERRNO - 1	# error?
+	sltu	t0, t0, v0
+	sd	t0, PT_R7(sp)		# set error flag
+	beqz	t0, 1f
+
+	negu	v0			# error
+	sd	v0, PT_R0(sp)		# set flag for syscall restarting
+1:	sd	v0, PT_R2(sp)		# result
+
+FEXPORT(ret_from_sys_call_64)
+	lw	t0, softirq_state
+	lw	t1, softirq_state+4	# unused delay slot
+	and	t0, t1
+	bnez	t0, handle_softirq_64
+
+9:	ld	t0, PT_STATUS(sp)	# returning to kernel mode?
+	andi	t1, t0, 0x10
+	ld	t2, TASK_NEED_RESCHED($28)
+	beqz	t1, return_64		# -> yes
+	bnez	t2, reschedule_64
+	lw	v0, TASK_SIGPENDING($28)
+	move	a0, zero
+	beqz	v0, return_64
+	move	a1, sp
+	SAVE_STATIC
+	jal	do_signal
+
+return_64:
+	RESTORE_SOME
+	RESTORE_SP
+	.set	mips3
+	eret
+	.set	mips0
+
+handle_softirq_64:
+	jal	do_softirq
+	b	9b
+reschedule_64:
+	SAVE_STATIC
+	jal	schedule
+	b	ret_from_sys_call_64
+
+/* ------------------------------------------------------------------------ */
+
+trace_a_syscall:
+	SAVE_STATIC
+	sd	t2,PT_R1(sp)
+	jal	syscall_trace
+	ld	t2,PT_R1(sp)
+
+	ld	a0, PT_R4(sp)		# Restore argument registers
+	ld	a1, PT_R5(sp)
+	ld	a2, PT_R6(sp)
+	ld	a3, PT_R7(sp)
+	jalr	t2
+
+	li	t0, -EMAXERRNO - 1	# error?
+	sltu	t0, t0, v0
+	sd	t0, PT_R7(sp)		# set error flag
+	beqz	t0, 1f
+
+	negu	v0			# error
+	sd	v0, PT_R0(sp)		# set flag for syscall restarting
+1:	sd	v0, PT_R2(sp)		# result
+
+	jal	syscall_trace
+	j	ret_from_sys_call
+
+illegal_syscall:
+	/* This also isn't a 64-bit syscall, throw an error.  */
+	li	v0, ENOSYS			# error
+	sd	v0, PT_R2(sp)
+	li	t0, 1				# set error flag
+	sd	t0, PT_R7(sp)
+	j	ret_from_sys_call
+	END(handle_sys64)
+
+sys_call_table:
+	PTR	sys_syscall				/* 4000 */
+	PTR	sys_exit
+	PTR	sys_fork
+	PTR	sys_read
+	PTR	sys_write
+	PTR	sys_open				/* 4005 */
+	PTR	sys_close
+	PTR	sys_waitpid
+	PTR	sys_creat
+	PTR	sys_link
+	PTR	sys_unlink				/* 4010 */
+	PTR	sys_execve
+	PTR	sys_chdir
+	PTR	sys_time
+	PTR	sys_mknod
+	PTR	sys_chmod				/* 4015 */
+	PTR	sys_lchown
+	PTR	sys_ni_syscall
+	PTR	sys_stat
+	PTR	sys_lseek
+	PTR	sys_getpid				/* 4020 */
+	PTR	sys_mount
+	PTR	sys_oldumount
+	PTR	sys_setuid
+	PTR	sys_getuid
+	PTR	sys_stime				/* 4025 */
+	PTR	sys_ni_syscall		/* ptrace */
+	PTR	sys_alarm
+	PTR	sys_fstat
+	PTR	sys_ni_syscall
+	PTR	sys_utime				/* 4030 */
+	PTR	sys_ni_syscall
+	PTR	sys_ni_syscall
+	PTR	sys_access
+	PTR	sys_nice
+	PTR	sys_ni_syscall				/* 4035 */
+	PTR	sys_sync
+	PTR	sys_kill
+	PTR	sys_rename
+	PTR	sys_mkdir
+	PTR	sys_rmdir				/* 4040 */
+	PTR	sys_dup
+	PTR	sys_pipe
+	PTR	sys_times
+	PTR	sys_ni_syscall
+	PTR	sys_brk					/* 4045 */
+	PTR	sys_setgid
+	PTR	sys_getgid
+	PTR	sys_ni_syscall		/* was signal	2 */
+	PTR	sys_geteuid
+	PTR	sys_getegid				/* 4050 */
+	PTR	sys_acct
+	PTR	sys_umount
+	PTR	sys_ni_syscall
+	PTR	sys_ioctl
+	PTR	sys_fcntl				/* 4055 */
+	PTR	sys_ni_syscall
+	PTR	sys_setpgid
+	PTR	sys_ni_syscall
+	PTR	sys_olduname
+	PTR	sys_umask				/* 4060 */
+	PTR	sys_chroot
+	PTR	sys_ustat
+	PTR	sys_dup2
+	PTR	sys_getppid
+	PTR	sys_getpgrp				/* 4065 */
+	PTR	sys_setsid
+	PTR	sys_sigaction
+	PTR	sys_sgetmask
+	PTR	sys_ssetmask
+	PTR	sys_setreuid				/* 4070 */
+	PTR	sys_setregid
+	PTR	sys_sigsuspend
+	PTR	sys_sigpending
+	PTR	sys_sethostname
+	PTR	sys_setrlimit				/* 4075 */
+	PTR	sys_getrlimit
+	PTR	sys_getrusage
+	PTR	sys_gettimeofday
+	PTR	sys_settimeofday
+	PTR	sys_getgroups				/* 4080 */
+	PTR	sys_setgroups
+	PTR	sys_ni_syscall			/* old_select */
+	PTR	sys_symlink
+	PTR	sys_lstat
+	PTR	sys_readlink				/* 4085 */
+	PTR	sys_uselib
+	PTR	sys_swapon
+	PTR	sys_reboot
+	PTR	old_readdir
+	PTR	sys_mmap				/* 4090 */
+	PTR	sys_munmap
+	PTR	sys_truncate
+	PTR	sys_ftruncate
+	PTR	sys_fchmod
+	PTR	sys_fchown				/* 4095 */
+	PTR	sys_getpriority
+	PTR	sys_setpriority
+	PTR	sys_ni_syscall
+	PTR	sys_statfs
+	PTR	sys_fstatfs				/* 4100 */
+	PTR	sys_ni_syscall		/* sys_ioperm */
+	PTR	sys_socketcall
+	PTR	sys_syslog
+	PTR	sys_setitimer
+	PTR	sys_getitimer				/* 4105 */
+	PTR	sys_newstat
+	PTR	sys_newlstat
+	PTR	sys_newfstat
+	PTR	sys_uname
+	PTR	sys_ni_syscall		/* sys_ioperm  *//* 4110 */
+	PTR	sys_vhangup
+	PTR	sys_ni_syscall		/* was sys_idle	 */
+	PTR	sys_ni_syscall		/* sys_vm86 */
+	PTR	sys_wait4
+	PTR	sys_swapoff				/* 4115 */
+	PTR	sys_sysinfo
+	PTR	sys_ipc
+	PTR	sys_fsync
+	PTR	sys_sigreturn
+	PTR	sys_clone				/* 4120 */
+	PTR	sys_setdomainname
+	PTR	sys_newuname
+	PTR	sys_ni_syscall		/* sys_modify_ldt */
+	PTR	sys_adjtimex
+	PTR	sys_mprotect				/* 4125 */
+	PTR	sys_sigprocmask
+	PTR	sys_create_module
+	PTR	sys_init_module
+	PTR	sys_delete_module
+	PTR	sys_get_kernel_syms 			/* 4130 */
+	PTR	sys_quotactl
+	PTR	sys_getpgid
+	PTR	sys_fchdir
+	PTR	sys_bdflush
+	PTR	sys_sysfs				/* 4135 */
+	PTR	sys_personality
+	PTR	sys_ni_syscall		/* for afs_syscall */
+	PTR	sys_setfsuid
+	PTR	sys_setfsgid
+	PTR	sys_llseek				/* 4140 */
+	PTR	sys_getdents
+	PTR	sys_select
+	PTR	sys_flock
+	PTR	sys_msync
+	PTR	sys_readv				/* 4145 */
+	PTR	sys_writev
+	PTR	sys_cacheflush
+	PTR	sys_cachectl
+	PTR	sys_sysmips
+	PTR	sys_ni_syscall				/* 4150 */
+	PTR	sys_getsid
+	PTR	sys_fdatasync
+	PTR	sys_sysctl
+	PTR	sys_mlock
+	PTR	sys_munlock				/* 4155 */
+	PTR	sys_mlockall
+	PTR	sys_munlockall
+	PTR	sys_sched_setparam
+	PTR	sys_sched_getparam
+	PTR	sys_sched_setscheduler			/* 4160 */
+	PTR	sys_sched_getscheduler
+	PTR	sys_sched_yield
+	PTR	sys_sched_get_priority_max
+	PTR	sys_sched_get_priority_min
+	PTR	sys_sched_rr_get_interval		/* 4165 */
+	PTR	sys_nanosleep
+	PTR	sys_mremap
+	PTR	sys_accept
+	PTR	sys_bind
+	PTR	sys_connect				/* 4170 */
+	PTR	sys_getpeername
+	PTR	sys_getsockname
+	PTR	sys_getsockopt
+	PTR	sys_listen
+	PTR	sys_recv				/* 4175 */
+	PTR	sys_recvfrom
+	PTR	sys_recvmsg
+	PTR	sys_send
+	PTR	sys_sendmsg
+	PTR	sys_sendto				/* 4180 */
+	PTR	sys_setsockopt
+	PTR	sys_shutdown
+	PTR	sys_socket
+	PTR	sys_socketpair
+	PTR	sys_setresuid				/* 4185 */
+	PTR	sys_getresuid
+	PTR	sys_query_module
+	PTR	sys_poll
+	PTR	sys_nfsservctl
+	PTR	sys_setresgid				/* 4190 */
+	PTR	sys_getresgid
+	PTR	sys_prctl
+	PTR	sys_rt_sigreturn
+	PTR	sys_rt_sigaction
+	PTR	sys_rt_sigprocmask 			/* 4195 */
+	PTR	sys_rt_sigpending
+	PTR	sys_rt_sigtimedwait
+	PTR	sys_rt_sigqueueinfo
+	PTR	sys_rt_sigsuspend
+	PTR	sys_pread				/* 4200 */
+	PTR	sys_pwrite
+	PTR	sys_chown
+	PTR	sys_getcwd
+	PTR	sys_capget
+	PTR	sys_capset				/* 4205 */
+	PTR	sys_sigaltstack
+	PTR	sys_sendfile
+	PTR	sys_ni_syscall
+	PTR	sys_ni_syscall
+	PTR	sys_pivot_root				/* 4210 */
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/scall_o32.S linux/arch/mips64/kernel/scall_o32.S
--- v2.3.47/linux/arch/mips64/kernel/scall_o32.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/scall_o32.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,425 @@
+/* $Id: scall_o32.S,v 1.8 2000/02/23 00:41:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * Hairy, the userspace application uses a different argument passing
+ * convention than the kernel, so we have to translate things from o32
+ * to ABI64 calling convention.  64-bit syscalls are also processed
+ * here for now.
+ */
+#include <asm/asm.h>
+#include <linux/errno.h>
+#include <asm/current.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/unistd.h>
+
+/* This duplicates the definition from <linux/sched.h> */
+#define PF_TRACESYS	0x00000020	/* tracing system calls */
+
+/* This duplicates the definition from <asm/signal.h> */
+#define SIGILL		4		/* Illegal instruction (ANSI).  */
+
+/* Highest syscall used of any syscall flavour */
+#define MAX_SYSCALL_NO	__NR_Linux32 + __NR_Linux32_syscalls
+
+	.align  5
+NESTED(handle_sys, PT_SIZE, sp)
+	.set	noat
+	SAVE_SOME
+	STI
+	.set	at
+ SAVE_ALL
+ ld	a1, PT_R2(sp)
+ PRINT("Got syscall %d\n")
+ RESTORE_ALL
+
+	ld	t1, PT_EPC(sp)		# skip syscall on return
+
+	sltiu	t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
+	daddiu	t1, 4			# skip to next instruction
+	beqz	t0, not_o32_scall
+	sd	t1, PT_EPC(sp)
+
+	/* XXX Put both in one cacheline, should save a bit. */
+	dsll	t0, v0, 3
+	ld	t2, (sys_call_table - (__NR_Linux32 * 8))(t0) # syscall routine
+	lbu	t3, (sys_narg_table - __NR_Linux32)(v0)	# number of arguments
+	beqz	t2, illegal_syscall;
+
+	subu	t0, t3, 5		# 5 or more arguments?
+	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
+	bgez	t0, stackargs
+
+stack_done:
+	ld	t0, TASK_FLAGS($28)	# syscall tracing enabled?
+	andi	t0, PF_TRACESYS
+	bnez	t0, trace_a_syscall
+
+	jalr	t2			# Do The Real Thing (TM)
+
+	li	t0, -EMAXERRNO - 1	# error?
+	sltu	t0, t0, v0
+	sd	t0, PT_R7(sp)		# set error flag
+	beqz	t0, 1f
+
+	negu	v0			# error
+	sd	v0, PT_R0(sp)		# set flag for syscall restarting
+1:	sd	v0, PT_R2(sp)		# result
+
+FEXPORT(o32_ret_from_sys_call)
+	lw	t0, softirq_state
+	lw	t1, softirq_state+4	# unused delay slot
+	and	t0, t1
+	bnez	t0, o32_handle_softirq
+
+9:	ld	t0,PT_STATUS(sp)	# returning to kernel mode?
+	andi	t1, t0, 0x10
+	ld	t2, TASK_NEED_RESCHED($28)
+	beqz	t1, o32_return		# -> yes
+	bnez	t2, o32_reschedule
+	lw	v0, TASK_SIGPENDING($28)
+	move	a0, zero
+	beqz	v0, o32_return
+	move	a1, sp
+	SAVE_STATIC
+	jal	do_signal
+
+o32_return:
+	RESTORE_SOME
+	RESTORE_SP
+	.set	mips3
+	eret
+	.set	mips0
+
+o32_handle_softirq:
+	jal	do_softirq
+	b	9b
+o32_reschedule:
+	SAVE_STATIC
+	jal	schedule
+	b	o32_ret_from_sys_call
+
+/* ------------------------------------------------------------------------ */
+
+trace_a_syscall:
+	SAVE_STATIC
+	sd	t2,PT_R1(sp)
+	jal	syscall_trace
+	ld	t2,PT_R1(sp)
+
+	ld	a0, PT_R4(sp)		# Restore argument registers
+	ld	a1, PT_R5(sp)
+	ld	a2, PT_R6(sp)
+	ld	a3, PT_R7(sp)
+	jalr	t2
+
+	li	t0, -EMAXERRNO - 1	# error?
+	sltu	t0, t0, v0
+	sd	t0, PT_R7(sp)		# set error flag
+	beqz	t0, 1f
+
+	negu	v0			# error
+	sd	v0, PT_R0(sp)		# set flag for syscall restarting
+1:	sd	v0, PT_R2(sp)		# result
+
+	jal	syscall_trace
+	j	ret_from_sys_call
+
+/* ------------------------------------------------------------------------ */
+
+	/*
+	 * More than four arguments.  Try to deal with it by copying the
+	 * stack arguments from the user stack to the kernel stack.
+	 * This Sucks (TM).
+	 */
+stackargs:
+	ld	t0, PT_R29(sp)		# get old user stack pointer
+	subu	t3, 4
+	sll	t1, t3, 2		# stack valid?
+
+	addu	t1, t0			# end address
+	or	t0, t1
+	bltz	t0, bad_stack		# -> sp is bad
+
+	ld	t0, PT_R29(sp)		# get old user stack pointer
+	la	t1, 3f			# copy 1 to 2 arguments
+	sll	t3, t3, 2
+	subu	t1, t3
+	jr	t1
+
+	/* Ok, copy the args from the luser stack to the kernel stack */
+1:	lw	a5, 20(t0)		# argument #6 from usp
+2:	lw	a4, 16(t0)		# argument #5 from usp
+
+3:	j	stack_done		# go back
+
+	.section __ex_table,"a"
+	PTR	1b, bad_stack
+	PTR	2b, bad_stack
+	.previous
+
+	/*
+	 * The stackpointer for a call with more than 4 arguments is bad.
+	 */
+bad_stack:
+	negu	v0				# error
+	sd	v0, PT_R0(sp)
+	sd	v0, PT_R2(sp)
+	li	t0, 1				# set error flag
+	sd	t0, PT_R7(sp)
+	j	ret_from_sys_call
+
+not_o32_scall:
+	/* This is not an 32-bit compatibility syscall, pass it on to
+	   the 64-bit syscall handlers.  */
+	j	handle_sys64
+
+illegal_syscall:
+	/* This also isn't a 64-bit syscall, throw an error.  */
+	li	v0, ENOSYS			# error
+	sd	v0, PT_R2(sp)
+	li	t0, 1				# set error flag
+	sd	t0, PT_R7(sp)
+	j	ret_from_sys_call
+	END(handle_sys)
+
+	.macro	syscalltable
+	sys	sys_syscall	0			/* 4000 */
+	sys	sys_exit	1
+	sys	sys_fork	0
+	sys	sys_read	3
+	sys	sys_write	3
+	sys	sys_open	3			/* 4005 */
+	sys	sys_close	3
+	sys	sys_waitpid	3
+	sys	sys_creat	2
+	sys	sys_link	2
+	sys	sys_unlink	1			/* 4010 */
+	sys	sys_execve	0
+	sys	sys_chdir	1
+	sys	sys_time	1
+	sys	sys_mknod	3
+	sys	sys_chmod	2			/* 4015 */
+	sys	sys_lchown	3
+	sys	sys_ni_syscall	0
+	sys	sys_stat	2
+	sys	sys_lseek	3
+	sys	sys_getpid	0			/* 4020 */
+	sys	sys_mount	5
+	sys	sys_oldumount	1
+	sys	sys_setuid	1
+	sys	sys_getuid	0
+	sys	sys_stime	1			/* 4025 */
+	sys	sys_ni_syscall	0	/* ptrace */
+	sys	sys_alarm	1
+	sys	sys_fstat	2
+	sys	sys_ni_syscall	0
+	sys	sys_utime	2			/* 4030 */
+	sys	sys_ni_syscall	0
+	sys	sys_ni_syscall	0
+	sys	sys_access	2
+	sys	sys_nice	1
+	sys	sys_ni_syscall	0			/* 4035 */
+	sys	sys_sync	0
+	sys	sys_kill	2
+	sys	sys_rename	2
+	sys	sys_mkdir	2
+	sys	sys_rmdir	1			/* 4040 */
+	sys	sys_dup		1
+	sys	sys_pipe	0
+	sys	sys_times	1
+	sys	sys_ni_syscall	0
+	sys	sys_brk		1			/* 4045 */
+	sys	sys_setgid	1
+	sys	sys_getgid	0
+	sys	sys_ni_syscall	0	/* was signal	2 */
+	sys	sys_geteuid	0
+	sys	sys_getegid	0			/* 4050 */
+	sys	sys_acct	0
+	sys	sys_umount	2
+	sys	sys_ni_syscall	0
+	sys	sys_ioctl	3
+	sys	sys_fcntl	3			/* 4055 */
+	sys	sys_ni_syscall	2
+	sys	sys_setpgid	2
+	sys	sys_ni_syscall, 0
+	sys	sys_olduname	1
+	sys	sys_umask	1			/* 4060 */
+	sys	sys_chroot	1
+	sys	sys_ustat	2
+	sys	sys_dup2	2
+	sys	sys_getppid	0
+	sys	sys_getpgrp	0			/* 4065 */
+	sys	sys_setsid	0
+	sys	sys32_sigaction	3
+	sys	sys_sgetmask	0
+	sys	sys_ssetmask	1
+	sys	sys_setreuid	2			/* 4070 */
+	sys	sys_setregid	2
+	sys	sys32_sigsuspend	0
+	sys	sys32_sigpending	1
+	sys	sys_sethostname	2
+	sys	sys_setrlimit	2			/* 4075 */
+	sys	sys_old_getrlimit	2
+	sys	sys_getrusage	2
+	sys	sys_gettimeofday 2
+	sys	sys_settimeofday 2
+	sys	sys_getgroups	2			/* 4080 */
+	sys	sys_setgroups	2
+	sys	sys_ni_syscall	0 /* old_select */
+	sys	sys_symlink	2
+	sys	sys_lstat	2
+	sys	sys_readlink	3			/* 4085 */
+	sys	sys_uselib	1
+	sys	sys_swapon	2
+	sys	sys_reboot	3
+	sys	old_readdir	3
+	sys	sys_mmap	6			/* 4090 */
+	sys	sys_munmap	2
+	sys	sys_truncate	2
+	sys	sys_ftruncate	2
+	sys	sys_fchmod	2
+	sys	sys_fchown	3			/* 4095 */
+	sys	sys_getpriority	2
+	sys	sys_setpriority	3
+	sys	sys_ni_syscall	0
+	sys	sys_statfs	2
+	sys	sys_fstatfs	2			/* 4100 */
+	sys	sys_ni_syscall	0	/* sys_ioperm */
+	sys	sys_socketcall	2
+	sys	sys_syslog	3
+	sys	sys_setitimer	3
+	sys	sys_getitimer	2			/* 4105 */
+	sys	sys32_newstat	2
+	sys	sys32_newlstat	2
+	sys	sys32_newfstat	2
+	sys	sys_uname	1
+	sys	sys_ni_syscall	0	/* sys_ioperm  *//* 4110 */
+	sys	sys_vhangup	0
+	sys	sys_ni_syscall	0	/* was sys_idle	 */
+	sys	sys_ni_syscall	0	/* sys_vm86 */
+	sys	sys_wait4	4
+	sys	sys_swapoff	1			/* 4115 */
+	sys	sys_sysinfo	1
+	sys	sys_ipc		6
+	sys	sys_fsync	1
+	sys	sys32_sigreturn	0
+	sys	sys_clone	0			/* 4120 */
+	sys	sys_setdomainname 2
+	sys	sys_newuname	1
+	sys	sys_ni_syscall	0	/* sys_modify_ldt */
+	sys	sys_adjtimex	1
+	sys	sys_mprotect	3			/* 4125 */
+	sys	sys_sigprocmask	3
+	sys	sys_create_module 2
+	sys	sys_init_module	5
+	sys	sys_delete_module 1
+	sys	sys_get_kernel_syms 1			/* 4130 */
+	sys	sys_quotactl	0
+	sys	sys_getpgid	1
+	sys	sys_fchdir	1
+	sys	sys_bdflush	2
+	sys	sys_sysfs	3			/* 4135 */
+	sys	sys_personality	1
+	sys	sys_ni_syscall	0 /* for afs_syscall */
+	sys	sys_setfsuid	1
+	sys	sys_setfsgid	1
+	sys	sys_llseek	5			/* 4140 */
+	sys	sys_getdents	3
+	sys	sys_select	5
+	sys	sys_flock	2
+	sys	sys_msync	3
+	sys	sys_readv	3			/* 4145 */
+	sys	sys_writev	3
+	sys	sys_cacheflush	3
+	sys	sys_cachectl	3
+	sys	sys_sysmips	4
+	sys	sys_ni_syscall	0			/* 4150 */
+	sys	sys_getsid	1
+	sys	sys_fdatasync	0
+	sys	sys_sysctl	1
+	sys	sys_mlock	2
+	sys	sys_munlock	2			/* 4155 */
+	sys	sys_mlockall	1
+	sys	sys_munlockall	0
+	sys	sys_sched_setparam 2
+	sys	sys_sched_getparam 2
+	sys	sys_sched_setscheduler 3		/* 4160 */
+	sys	sys_sched_getscheduler 1
+	sys	sys_sched_yield	0
+	sys	sys_sched_get_priority_max 1
+	sys	sys_sched_get_priority_min 1
+	sys	sys_sched_rr_get_interval 2		/* 4165 */
+	sys	sys_nanosleep	2
+	sys	sys_mremap	4
+	sys	sys_accept	3
+	sys	sys_bind	3
+	sys	sys_connect	3			/* 4170 */
+	sys	sys_getpeername	3
+	sys	sys_getsockname	3
+	sys	sys_getsockopt	5
+	sys	sys_listen	2
+	sys	sys_recv	4			/* 4175 */
+	sys	sys_recvfrom	6
+	sys	sys_recvmsg	3
+	sys	sys_send	4
+	sys	sys_sendmsg	3
+	sys	sys_sendto	6			/* 4180 */
+	sys	sys_setsockopt	5
+	sys	sys_shutdown	2
+	sys	sys_socket	3
+	sys	sys_socketpair	4
+	sys	sys_setresuid	3			/* 4185 */
+	sys	sys_getresuid	3
+	sys	sys_query_module 5
+	sys	sys_poll	3
+	sys	sys_nfsservctl	3
+	sys	sys_setresgid	3			/* 4190 */
+	sys	sys_getresgid	3
+	sys	sys_prctl	5
+	sys	sys32_rt_sigreturn 0
+	sys	sys32_rt_sigaction 4
+	sys	sys32_rt_sigprocmask 4			/* 4195 */
+	sys	sys32_rt_sigpending 2
+	sys	sys32_rt_sigtimedwait 4
+	sys	sys32_rt_sigqueueinfo 3
+	sys	sys32_rt_sigsuspend 0
+	sys	sys_pread	4			/* 4200 */
+	sys	sys_pwrite	4
+	sys	sys_chown	3
+	sys	sys_getcwd	2
+	sys	sys_capget	2
+	sys	sys_capset	2			/* 4205 */
+	sys	sys32_sigaltstack	0
+	sys	sys_sendfile	3
+	sys	sys_ni_syscall	0
+	sys	sys_ni_syscall	0
+	sys	sys_mmap2	6			/* 4210 */
+	sys	sys_truncate64	2
+	sys	sys_ftruncate64	2
+	sys	sys_stat64	3
+	sys	sys_lstat64	3
+	sys	sys_fstat64	3			/* 4210 */
+	sys	sys_pivot_root	2
+	.endm
+
+	.macro	sys function, nargs
+	PTR	\function
+	.endm
+
+sys_call_table:
+	syscalltable
+
+	.macro	sys function, nargs
+	.byte	\nargs
+	.endm
+
+sys_narg_table:
+	syscalltable
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/semaphore.c linux/arch/mips64/kernel/semaphore.c
--- v2.3.47/linux/arch/mips64/kernel/semaphore.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/semaphore.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,240 @@
+/*
+ *  Generic semaphore code. Buyer beware. Do your own
+ * specific changes in <asm/semaphore-helper.h>
+ */
+
+#include <linux/sched.h>
+#include <asm/semaphore-helper.h>
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to sleep, while the "waking" variable is
+ * incremented when the "up()" code goes to wake up waiting
+ * processes.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * waking_non_zero() (from asm/semaphore.h) must execute
+ * atomically.
+ *
+ * When __up() is called, the count was negative before
+ * incrementing it, and we need to wake up somebody.
+ *
+ * This routine adds one to the count of processes that need to
+ * wake up and exit.  ALL waiting processes actually wake up but
+ * only the one that gets to the "waking" field first will gate
+ * through and acquire the semaphore.  The others will go back
+ * to sleep.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+void __up(struct semaphore *sem)
+{
+	wake_one_more(sem);
+	wake_up(&sem->wait);
+}
+
+/*
+ * Perform the "down" function.  Return zero for semaphore acquired,
+ * return negative for signalled out of the function.
+ *
+ * If called from __down, the return is ignored and the wait loop is
+ * not interruptible.  This means that a task waiting on a semaphore
+ * using "down()" cannot be killed until someone does an "up()" on
+ * the semaphore.
+ *
+ * If called from __down_interruptible, the return value gets checked
+ * upon return.  If the return value is negative then the task continues
+ * with the negative value in the return register (it can be tested by
+ * the caller).
+ *
+ * Either form may be used in conjunction with "up()".
+ *
+ */
+
+#define DOWN_VAR				\
+	struct task_struct *tsk = current;	\
+	wait_queue_t wait;			\
+	init_waitqueue_entry(&wait, tsk);
+
+#define DOWN_HEAD(task_state)						\
+									\
+									\
+	tsk->state = (task_state);					\
+	add_wait_queue(&sem->wait, &wait);				\
+									\
+	/*								\
+	 * Ok, we're set up.  sem->count is known to be less than zero	\
+	 * so we must wait.						\
+	 *								\
+	 * We can let go the lock for purposes of waiting.		\
+	 * We re-acquire it after awaking so as to protect		\
+	 * all semaphore operations.					\
+	 *								\
+	 * If "up()" is called before we call waking_non_zero() then	\
+	 * we will catch it right away.  If it is called later then	\
+	 * we will have to go through a wakeup cycle to catch it.	\
+	 *								\
+	 * Multiple waiters contend for the semaphore lock to see	\
+	 * who gets to gate through and who has to wait some more.	\
+	 */								\
+	for (;;) {
+
+#define DOWN_TAIL(task_state)			\
+		tsk->state = (task_state);	\
+	}					\
+	tsk->state = TASK_RUNNING;		\
+	remove_wait_queue(&sem->wait, &wait);
+
+void __down(struct semaphore * sem)
+{
+	DOWN_VAR
+	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+	if (waking_non_zero(sem))
+		break;
+	schedule();
+	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+	DOWN_VAR
+	DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+	ret = waking_non_zero_interruptible(sem, tsk);
+	if (ret)
+	{
+		if (ret == 1)
+			/* ret != 0 only if we get interrupted -arca */
+			ret = 0;
+		break;
+	}
+	schedule();
+	DOWN_TAIL(TASK_INTERRUPTIBLE)
+	return ret;
+}
+
+int __down_trylock(struct semaphore * sem)
+{
+	return waking_non_zero_trylock(sem);
+}
+
+/*
+ * RW Semaphores
+ */
+void
+__down_read(struct rw_semaphore *sem, int count)
+{
+	DOWN_VAR;
+
+ retry_down:
+	if (count < 0) {
+		/* Wait for the lock to become unbiased.  Readers
+		   are non-exclusive.  */
+		
+		/* This takes care of granting the lock.  */
+		up_read(sem);
+
+		add_wait_queue(&sem->wait, &wait);
+		while (atomic_read(&sem->count) < 0) {
+			set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+			if (atomic_read(&sem->count) >= 0)
+				break;
+			schedule();
+		}
+
+		remove_wait_queue(&sem->wait, &wait);
+		tsk->state = TASK_RUNNING;
+
+		mb();
+		count = atomic_dec_return(&sem->count);
+		if (count <= 0)
+			goto retry_down;
+	} else {
+		add_wait_queue(&sem->wait, &wait);
+
+		while (1) {
+			if (test_and_clear_bit(0, &sem->granted))
+				break;
+			set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+			if ((sem->granted & 1) == 0)
+				schedule();
+		}
+
+		remove_wait_queue(&sem->wait, &wait);
+		tsk->state = TASK_RUNNING;
+	}
+}
+
+void
+__down_write(struct rw_semaphore *sem, int count)
+{
+	DOWN_VAR;
+
+ retry_down:
+	if (count + RW_LOCK_BIAS < 0) {
+		up_write(sem);
+
+		add_wait_queue_exclusive(&sem->wait, &wait);
+	
+		while (atomic_read(&sem->count) < 0) {
+			set_task_state(tsk, (TASK_UNINTERRUPTIBLE
+					     | TASK_EXCLUSIVE));
+			if (atomic_read(&sem->count) >= RW_LOCK_BIAS)
+				break;
+			schedule();
+		}
+
+		remove_wait_queue(&sem->wait, &wait);
+		tsk->state = TASK_RUNNING;
+
+		mb();
+		count = atomic_sub_return(RW_LOCK_BIAS, &sem->count);
+		if (count != 0)
+			goto retry_down;
+	} else {
+		/* Put ourselves at the end of the list.  */
+		add_wait_queue_exclusive(&sem->write_bias_wait, &wait);
+
+		while (1) {
+			if (test_and_clear_bit(1, &sem->granted))
+				break;
+			set_task_state(tsk, (TASK_UNINTERRUPTIBLE
+					     | TASK_EXCLUSIVE));
+			if ((sem->granted & 2) == 0)
+				schedule();
+		}
+
+		remove_wait_queue(&sem->write_bias_wait, &wait);
+		tsk->state = TASK_RUNNING;
+
+		/* If the lock is currently unbiased, awaken the sleepers.
+		   FIXME: This wakes up the readers early in a bit of a
+		   stampede -> bad!  */
+		if (atomic_read(&sem->count) >= 0)
+			wake_up(&sem->wait);
+	}
+}
+
+void
+__rwsem_wake(struct rw_semaphore *sem, unsigned long readers)
+{
+	if (readers) {
+		if (test_and_set_bit(0, &sem->granted))
+			BUG();
+		wake_up(&sem->wait);
+	} else {
+		if (test_and_set_bit(1, &sem->granted))
+			BUG();
+		wake_up(&sem->write_bias_wait);
+	}
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/setup.c linux/arch/mips64/kernel/setup.c
--- v2.3.47/linux/arch/mips64/kernel/setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/setup.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,186 @@
+/* $Id: setup.c,v 1.7 2000/02/04 07:40:24 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 Linus Torvalds
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Ralf Baechle
+ * Copyright (C) 1996 Stoned Elipot
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/user.h>
+#include <linux/utsname.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
+
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/stackframe.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_SGI_IP27
+#include <asm/sn/sn0/addrs.h>
+#endif
+
+struct mips_cpuinfo boot_cpu_data;
+
+#ifdef CONFIG_VT
+struct screen_info screen_info;
+#endif
+
+/*
+ * Not all of the MIPS CPUs have the "wait" instruction available.  This
+ * is set to true if it is available.  The wait instruction stops the
+ * pipeline and reduces the power consumption of the CPU very much.
+ */
+char wait_available;
+
+/*
+ * Do we have a cyclecounter available?
+ */
+char cyclecounter_available;
+
+/*
+ * Set if box has EISA slots.
+ */
+int EISA_bus = 0;
+
+#ifdef CONFIG_BLK_DEV_FD
+extern struct fd_ops no_fd_ops;
+struct fd_ops *fd_ops;
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+extern struct ide_ops no_ide_ops;
+struct ide_ops *ide_ops;
+#endif
+
+extern struct rtc_ops no_rtc_ops;
+struct rtc_ops *rtc_ops;
+
+extern struct kbd_ops no_kbd_ops;
+struct kbd_ops *kbd_ops;
+
+/*
+ * Setup information
+ *
+ * These are initialized so they are in the .data section
+ */
+unsigned long mips_memory_upper = KSEG0;
+unsigned long mips_cputype = CPU_UNKNOWN;
+unsigned long mips_machtype = MACH_UNKNOWN;
+unsigned long mips_machgroup = MACH_GROUP_UNKNOWN;
+
+unsigned char aux_device_present;
+extern int _end;
+
+extern void load_mmu(void);
+
+static char command_line[CL_SIZE] = { 0, };
+       char saved_command_line[CL_SIZE];
+extern char arcs_cmdline[CL_SIZE];
+
+/*
+ * mips_io_port_base is the begin of the address space to which x86 style
+ * I/O ports are mapped.
+ */
+unsigned long mips_io_port_base = IO_BASE;
+
+extern void ip22_setup(void);
+extern void ip27_setup(void);
+
+static inline void cpu_probe(void)
+{
+	unsigned int prid = read_32bit_cp0_register(CP0_PRID);
+
+	switch(prid & 0xff00) {
+	case PRID_IMP_R4000:
+		if((prid & 0xff) == PRID_REV_R4400)
+			mips_cputype = CPU_R4400SC;
+		else
+			mips_cputype = CPU_R4000SC;
+		break;
+	case PRID_IMP_R4600:
+		mips_cputype = CPU_R4600;
+		break;
+	case PRID_IMP_R4700:
+		mips_cputype = CPU_R4700;
+		break;
+	case PRID_IMP_R5000:
+		mips_cputype = CPU_R5000;
+		break;
+	case PRID_IMP_NEVADA:
+		mips_cputype = CPU_NEVADA;
+		break;
+	case PRID_IMP_R8000:
+		mips_cputype = CPU_R8000;
+		break;
+	case PRID_IMP_R10000:
+		mips_cputype = CPU_R10000;
+		break;
+	default:
+		mips_cputype = CPU_UNKNOWN;
+	}
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	unsigned long tmp;
+	unsigned long *initrd_header;
+#endif
+
+	cpu_probe();
+	load_mmu();
+
+#ifdef CONFIG_SGI_IP22
+	ip22_setup();
+#endif
+#ifdef CONFIG_SGI_IP27
+	ip27_setup();
+#endif
+
+	strncpy (command_line, arcs_cmdline, CL_SIZE);
+	memcpy(saved_command_line, command_line, CL_SIZE);
+	saved_command_line[CL_SIZE-1] = '\0';
+
+	*cmdline_p = command_line;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#error "Initrd is broken, please fit it."
+	tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
+	if (tmp < (unsigned long)&_end)
+		tmp += PAGE_SIZE;
+	initrd_header = (unsigned long *)tmp;
+	if (initrd_header[0] == 0x494E5244) {
+		initrd_start = (unsigned long)&initrd_header[2];
+		initrd_end = initrd_start + initrd_header[1];
+		initrd_below_start_ok = 1;
+		if (initrd_end > memory_end) {
+			printk("initrd extends beyond end of memory "
+			       "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+			       initrd_end,memory_end);
+			initrd_start = 0;
+		} else
+			*memory_start_p = initrd_end;
+	}
+#endif
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/signal.c linux/arch/mips64/kernel/signal.c
--- v2.3.47/linux/arch/mips64/kernel/signal.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/signal.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,657 @@
+/* $Id: signal.c,v 1.5 2000/02/04 07:40:24 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1991, 1992  Linus Torvalds
+ * Copyright (C) 1994 - 1999  Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+
+#include <asm/asm.h>
+#include <asm/bitops.h>
+#include <asm/pgalloc.h>
+#include <asm/stackframe.h>
+#include <asm/uaccess.h>
+#include <asm/ucontext.h>
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+extern asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
+                         int options, unsigned long *ru);
+extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+extern asmlinkage int save_fp_context(struct sigcontext *sc);
+extern asmlinkage int restore_fp_context(struct sigcontext *sc);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage inline int
+sys_sigsuspend(abi64_no_regargs, struct pt_regs regs)
+{
+	sigset_t *uset, saveset, newset;
+
+	save_static(&regs);
+	uset = (sigset_t *) regs.regs[4];
+	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs.regs[2] = EINTR;
+	regs.regs[7] = 1;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, &regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+sys_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs)
+{
+	sigset_t *unewset, saveset, newset;
+        size_t sigsetsize;
+
+	save_static(&regs);
+
+	/* XXX Don't preclude handling different sized sigset_t's.  */
+	sigsetsize = regs.regs[5];
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	unewset = (sigset_t *) regs.regs[4];
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+        recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs.regs[2] = EINTR;
+	regs.regs[7] = 1;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, &regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+	int err = 0;
+
+	if (act) {
+		old_sigset_t mask;
+
+		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+			return -EFAULT;
+		err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler);
+		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		err |= __get_user(mask, &act->sa_mask.sig[0]);
+		err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer);
+		if (err)
+			return -EFAULT;
+
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+                        return -EFAULT;
+		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
+		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
+                err |= __put_user(0, &oact->sa_mask.sig[1]);
+                err |= __put_user(0, &oact->sa_mask.sig[2]);
+                err |= __put_user(0, &oact->sa_mask.sig[3]);
+		err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer);
+                if (err)
+			return -EFAULT;
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(abi64_no_regargs, struct pt_regs regs)
+{
+	const stack_t *uss = (const stack_t *) regs.regs[4];
+	stack_t *uoss = (stack_t *) regs.regs[5];
+	unsigned long usp = regs.regs[29];
+
+	return do_sigaltstack(uss, uoss, usp);
+}
+
+asmlinkage int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	int owned_fp;
+	int err = 0;
+
+	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __get_user(regs->hi, &sc->sc_mdhi);
+	err |= __get_user(regs->lo, &sc->sc_mdlo);
+
+#define restore_gp_reg(i) do {						\
+	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
+} while(0)
+	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
+	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
+	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
+	restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
+	restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
+	restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
+	restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
+	restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
+	restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
+	restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
+	restore_gp_reg(31);
+#undef restore_gp_reg
+
+	err |= __get_user(owned_fp, &sc->sc_ownedfp);
+	if (owned_fp) {
+		err |= restore_fp_context(sc);
+		last_task_used_math = current;
+	}
+
+	return err;
+}
+
+struct sigframe {
+	u32 sf_ass[4];			/* argument save space for o32 */
+	u32 sf_code[2];			/* signal trampoline */
+	struct sigcontext sf_sc;
+	sigset_t sf_mask;
+};
+
+struct rt_sigframe {
+	u32 rs_ass[4];			/* argument save space for o32 */
+	u32 rs_code[2];			/* signal trampoline */
+	struct siginfo rs_info;
+	struct ucontext rs_uc;
+};
+
+asmlinkage void
+sys_sigreturn(abi64_no_regargs, struct pt_regs regs)
+{
+	struct sigframe *frame;
+	sigset_t blocked;
+
+	frame = (struct sigframe *) regs.regs[29];
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
+		goto badframe;
+
+	sigdelsetmask(&blocked, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = blocked;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(&regs, &frame->sf_sc))
+		goto badframe;
+
+	/*
+	 * Don't let your children do this ...
+	 */
+	__asm__ __volatile__(
+		"move\t$29, %0\n\t"
+		"j\tret_from_sys_call"
+		:/* no outputs */
+		:"r" (&regs));
+	/* Unreached */
+
+badframe:
+	force_sig(SIGSEGV, current);
+}
+
+asmlinkage void
+sys_rt_sigreturn(abi64_no_regargs, struct pt_regs regs)
+{
+	struct rt_sigframe *frame;
+	sigset_t set;
+	stack_t st;
+
+	frame = (struct rt_sigframe *) regs.regs[29];
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
+		goto badframe;
+
+	if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
+		goto badframe;
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, regs.regs[29]);
+
+	/*
+	 * Don't let your children do this ...
+	 */
+	__asm__ __volatile__(
+		"move\t$29, %0\n\t"
+		"j\tret_from_sys_call"
+		:/* no outputs */
+		:"r" (&regs));
+	/* Unreached */
+
+badframe:
+	force_sig(SIGSEGV, current);
+}
+
+static int inline
+setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	int owned_fp;
+	int err = 0;
+
+	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __put_user(regs->cp0_status, &sc->sc_status);
+
+#define save_gp_reg(i) {						\
+	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
+} while(0)
+	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
+	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
+	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
+	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
+	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
+	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
+	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
+	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
+	save_gp_reg(31);
+#undef save_gp_reg
+
+	err |= __put_user(regs->hi, &sc->sc_mdhi);
+	err |= __put_user(regs->lo, &sc->sc_mdlo);
+	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
+	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
+
+	owned_fp = (current == last_task_used_math);
+	err |= __put_user(owned_fp, &sc->sc_ownedfp);
+
+	if (current->used_math) {	/* fp is active.  */
+		set_cp0_status(ST0_CU1, ST0_CU1);
+		err |= save_fp_context(sc);
+		last_task_used_math = NULL;
+		regs->cp0_status &= ~ST0_CU1;
+		current->used_math = 0;
+	}
+
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long sp;
+
+	/* Default to using normal stack */
+	sp = regs->regs[29];
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	return (void *)((sp - frame_size) & ALMASK);
+}
+
+static void inline
+setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+            int signr, sigset_t *set)
+{
+	struct sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub already
+	   in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER)
+		regs->regs[31] = (unsigned long) ka->sa.sa_restorer;
+	else {
+		/*
+		 * Set up the return code ...
+		 *
+		 *         li      v0, __NR_sigreturn
+		 *         syscall
+		 */
+		err |= __put_user(0x24020000 + __NR_sigreturn,
+		                  frame->sf_code + 0);
+		err |= __put_user(0x0000000c                 ,
+		                  frame->sf_code + 1);
+		flush_cache_sigtramp((unsigned long) frame->sf_code);
+	}
+
+	err |= setup_sigcontext(regs, &frame->sf_sc);
+	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Arguments to signal handler:
+	 *
+	 *   a0 = signal number
+	 *   a1 = 0 (should be cause)
+	 *   a2 = pointer to struct sigcontext
+	 *
+	 * $25 and c0_epc point to the signal handler, $29 points to the
+	 * struct sigframe.
+	 */
+	regs->regs[ 4] = signr;
+	regs->regs[ 5] = 0;
+	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
+	regs->regs[29] = (unsigned long) frame;
+	regs->regs[31] = (unsigned long) frame->sf_code;
+	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
+	       current->comm, current->pid, frame, regs->cp0_epc, frame->code);
+#endif
+        return;
+
+give_sigsegv:
+	if (signr == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void inline
+setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+               int signr, sigset_t *set, siginfo_t *info)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub already
+	   in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER)
+		regs->regs[31] = (unsigned long) ka->sa.sa_restorer;
+	else {
+		/*
+		 * Set up the return code ...
+		 *
+		 *         li      v0, __NR_sigreturn
+		 *         syscall
+		 */
+		err |= __put_user(0x24020000 + __NR_sigreturn,
+		                  frame->rs_code + 0);
+		err |= __put_user(0x0000000c                 ,
+		                  frame->rs_code + 1);
+		flush_cache_sigtramp((unsigned long) frame->rs_code);
+	}
+
+	/* Create siginfo.  */
+	err |= __copy_to_user(&frame->rs_info, info, sizeof(*info));
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->rs_uc.uc_flags);
+	err |= __put_user(0, &frame->rs_uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+	                  &frame->rs_uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->regs[29]),
+	                  &frame->rs_uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size,
+	                  &frame->rs_uc.uc_stack.ss_size);
+	err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
+	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Arguments to signal handler:
+	 *
+	 *   a0 = signal number
+	 *   a1 = 0 (should be cause)
+	 *   a2 = pointer to ucontext
+	 *
+	 * $25 and c0_epc point to the signal handler, $29 points to
+	 * the struct rt_sigframe.
+	 */
+	regs->regs[ 4] = signr;
+	regs->regs[ 5] = (unsigned long) &frame->rs_info;
+	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
+	regs->regs[29] = (unsigned long) frame;
+	regs->regs[31] = (unsigned long) frame->rs_code;
+	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
+	       current->comm, current->pid, frame, regs->cp0_epc, frame->code);
+#endif
+	return;
+
+give_sigsegv:
+	if (signr == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static inline void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+	siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
+{
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(ka, regs, sig, oldset, info);
+	else
+		setup_frame(ka, regs, sig, oldset);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+}
+
+static inline void
+syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
+{
+	switch(regs->regs[0]) {
+	case ERESTARTNOHAND:
+		regs->regs[2] = EINTR;
+		break;
+	case ERESTARTSYS:
+		if(!(ka->sa.sa_flags & SA_RESTART)) {
+			regs->regs[2] = EINTR;
+			break;
+		}
+	/* fallthrough */
+	case ERESTARTNOINTR:		/* Userland will reload $v0.  */
+		regs->regs[7] = regs->regs[26];
+		regs->cp0_epc -= 8;
+	}
+
+	regs->regs[0] = 0;		/* Don't deal with this again.  */
+}
+
+extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
+extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	struct k_sigaction *ka;
+	siginfo_t info;
+
+#ifdef CONFIG_BINFMT_ELF32
+	if (current->thread.mflags & MF_32BIT) {
+		return do_signal32(oldset, regs);
+	}
+#endif
+
+#ifdef CONFIG_BINFMT_IRIX
+	if (current->personality != PER_LINUX)
+		return do_irix_signal(oldset, regs);
+#endif
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		unsigned long signr;
+
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+
+		if (!signr)
+			break;
+
+		if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+			/* Let the debugger run.  */
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code))
+				continue;
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				continue;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			/* Init gets no signals it doesn't want.  */
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGABRT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				lock_kernel();
+				sigaddset(&current->signal, signr);
+				recalc_sigpending(current);
+				current->flags |= PF_SIGNALED;
+				do_exit(exit_code);
+				/* NOTREACHED */
+			}
+		}
+
+		if (regs->regs[0])
+			syscall_restart(regs, ka);
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/*
+	 * Who's code doesn't conform to the restartable syscall convention
+	 * dies here!!!  The li instruction, a single machine instruction,
+	 * must directly be followed by the syscall instruction.
+	 */
+	if (regs->regs[0]) {
+		if (regs->regs[2] == ERESTARTNOHAND ||
+		    regs->regs[2] == ERESTARTSYS ||
+		    regs->regs[2] == ERESTARTNOINTR) {
+			regs->regs[7] = regs->regs[26];
+			regs->cp0_epc -= 8;
+		}
+	}
+	return 0;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/signal32.c linux/arch/mips64/kernel/signal32.c
--- v2.3.47/linux/arch/mips64/kernel/signal32.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/signal32.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,688 @@
+/* $Id: signal32.c,v 1.2 2000/02/18 00:03:48 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1991, 1992  Linus Torvalds
+ * Copyright (C) 1994 - 1999  Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+
+#include <asm/asm.h>
+#include <asm/bitops.h>
+#include <asm/pgalloc.h>
+#include <asm/stackframe.h>
+#include <asm/uaccess.h>
+#include <asm/ucontext.h>
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+extern asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
+                         int options, unsigned long *ru);
+extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+extern asmlinkage int save_fp_context(struct sigcontext *sc);
+extern asmlinkage int restore_fp_context(struct sigcontext *sc);
+
+/* 32-bit compatibility types */
+
+#define _NSIG32		128
+#define _NSIG32_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef struct {
+	unsigned int sig[_NSIG_WORDS];
+} sigset32_t;
+
+typedef unsigned int __sighandler32_t;
+typedef void (*vfptr_t)(void);
+
+struct sigaction32 {
+	unsigned int		sa_flags;
+	__sighandler32_t	sa_handler;
+	sigset32_t		sa_mask;
+	unsigned int		sa_restorer;
+	int			sa_resv[1];     /* reserved */
+};
+
+/* IRIX compatible stack_t  */
+typedef struct sigaltstack32 {
+	void *ss_sp;
+	size_t ss_size;
+	int ss_flags;
+} stack32_t;
+
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage inline int
+sys32_sigsuspend(abi64_no_regargs, struct pt_regs regs)
+{
+	sigset_t *uset, saveset, newset;
+
+	save_static(&regs);
+printk("%s called.\n", __FUNCTION__);
+	uset = (sigset_t *) regs.regs[4];
+	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs.regs[2] = EINTR;
+	regs.regs[7] = 1;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal32(&saveset, &regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+sys32_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs)
+{
+	sigset_t *unewset, saveset, newset;
+        size_t sigsetsize;
+
+	save_static(&regs);
+printk("%s called.\n", __FUNCTION__);
+
+	/* XXX Don't preclude handling different sized sigset_t's.  */
+	sigsetsize = regs.regs[5];
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	unewset = (sigset_t *) regs.regs[4];
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+        recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs.regs[2] = EINTR;
+	regs.regs[7] = 1;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal32(&saveset, &regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
+                               struct sigaction32 *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+	int err = 0;
+
+	if (act) {
+		old_sigset_t mask;
+
+		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+			return -EFAULT;
+		err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler);
+		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		err |= __get_user(mask, &act->sa_mask.sig[0]);
+		err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer);
+		if (err)
+			return -EFAULT;
+
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+                        return -EFAULT;
+		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
+		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
+                err |= __put_user(0, &oact->sa_mask.sig[1]);
+                err |= __put_user(0, &oact->sa_mask.sig[2]);
+                err |= __put_user(0, &oact->sa_mask.sig[3]);
+		err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer);
+                if (err)
+			return -EFAULT;
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys32_sigaltstack(abi64_no_regargs, struct pt_regs regs)
+{
+	const stack_t *uss = (const stack_t *) regs.regs[4];
+	stack_t *uoss = (stack_t *) regs.regs[5];
+	unsigned long usp = regs.regs[29];
+printk("%s called.\n", __FUNCTION__);
+
+	return do_sigaltstack(uss, uoss, usp);
+}
+
+static asmlinkage int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	int owned_fp;
+	int err = 0;
+
+	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __get_user(regs->hi, &sc->sc_mdhi);
+	err |= __get_user(regs->lo, &sc->sc_mdlo);
+
+#define restore_gp_reg(i) do {						\
+	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
+} while(0)
+	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
+	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
+	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
+	restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
+	restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
+	restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
+	restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
+	restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
+	restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
+	restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
+	restore_gp_reg(31);
+#undef restore_gp_reg
+
+	err |= __get_user(owned_fp, &sc->sc_ownedfp);
+	if (owned_fp) {
+		err |= restore_fp_context(sc);
+		last_task_used_math = current;
+	}
+
+	return err;
+}
+
+struct sigframe {
+	u32 sf_ass[4];			/* argument save space for o32 */
+	u32 sf_code[2];			/* signal trampoline */
+	struct sigcontext sf_sc;
+	sigset_t sf_mask;
+};
+
+struct rt_sigframe {
+	u32 rs_ass[4];			/* argument save space for o32 */
+	u32 rs_code[2];			/* signal trampoline */
+	struct siginfo rs_info;
+	struct ucontext rs_uc;
+};
+
+asmlinkage void
+sys32_sigreturn(abi64_no_regargs, struct pt_regs regs)
+{
+	struct sigframe *frame;
+	sigset_t blocked;
+printk("%s called.\n", __FUNCTION__);
+
+	frame = (struct sigframe *) regs.regs[29];
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
+		goto badframe;
+
+	sigdelsetmask(&blocked, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = blocked;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(&regs, &frame->sf_sc))
+		goto badframe;
+
+	/*
+	 * Don't let your children do this ...
+	 */
+	__asm__ __volatile__(
+		"move\t$29, %0\n\t"
+		"j\tret_from_sys_call"
+		:/* no outputs */
+		:"r" (&regs));
+	/* Unreached */
+
+badframe:
+	force_sig(SIGSEGV, current);
+}
+
+asmlinkage void
+sys32_rt_sigreturn(abi64_no_regargs, struct pt_regs regs)
+{
+	struct rt_sigframe *frame;
+	sigset_t set;
+	stack_t st;
+printk("%s called.\n", __FUNCTION__);
+
+	frame = (struct rt_sigframe *) regs.regs[29];
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
+		goto badframe;
+
+	if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
+		goto badframe;
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, regs.regs[29]);
+
+	/*
+	 * Don't let your children do this ...
+	 */
+	__asm__ __volatile__(
+		"move\t$29, %0\n\t"
+		"j\tret_from_sys_call"
+		:/* no outputs */
+		:"r" (&regs));
+	/* Unreached */
+
+badframe:
+	force_sig(SIGSEGV, current);
+}
+
+static int inline
+setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	int owned_fp;
+	int err = 0;
+
+	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __put_user(regs->cp0_status, &sc->sc_status);
+
+#define save_gp_reg(i) {						\
+	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
+} while(0)
+	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
+	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
+	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
+	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
+	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
+	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
+	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
+	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
+	save_gp_reg(31);
+#undef save_gp_reg
+
+	err |= __put_user(regs->hi, &sc->sc_mdhi);
+	err |= __put_user(regs->lo, &sc->sc_mdlo);
+	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
+	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
+
+	owned_fp = (current == last_task_used_math);
+	err |= __put_user(owned_fp, &sc->sc_ownedfp);
+
+	if (current->used_math) {	/* fp is active.  */
+		set_cp0_status(ST0_CU1, ST0_CU1);
+		err |= save_fp_context(sc);
+		last_task_used_math = NULL;
+		regs->cp0_status &= ~ST0_CU1;
+		current->used_math = 0;
+	}
+
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long sp;
+
+	/* Default to using normal stack */
+	sp = regs->regs[29];
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	return (void *)((sp - frame_size) & ALMASK);
+}
+
+static void inline
+setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+            int signr, sigset_t *set)
+{
+	struct sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub already
+	   in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER)
+		regs->regs[31] = (unsigned long) ka->sa.sa_restorer;
+	else {
+		/*
+		 * Set up the return code ...
+		 *
+		 *         li      v0, __NR_sigreturn
+		 *         syscall
+		 */
+		err |= __put_user(0x24020000 + __NR_sigreturn,
+		                  frame->sf_code + 0);
+		err |= __put_user(0x0000000c                 ,
+		                  frame->sf_code + 1);
+		flush_cache_sigtramp((unsigned long) frame->sf_code);
+	}
+
+	err |= setup_sigcontext(regs, &frame->sf_sc);
+	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Arguments to signal handler:
+	 *
+	 *   a0 = signal number
+	 *   a1 = 0 (should be cause)
+	 *   a2 = pointer to struct sigcontext
+	 *
+	 * $25 and c0_epc point to the signal handler, $29 points to the
+	 * struct sigframe.
+	 */
+	regs->regs[ 4] = signr;
+	regs->regs[ 5] = 0;
+	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
+	regs->regs[29] = (unsigned long) frame;
+	regs->regs[31] = (unsigned long) frame->sf_code;
+	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
+	       current->comm, current->pid, frame, regs->cp0_epc, frame->code);
+#endif
+        return;
+
+give_sigsegv:
+	if (signr == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void inline
+setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+               int signr, sigset_t *set, siginfo_t *info)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub already
+	   in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER)
+		regs->regs[31] = (unsigned long) ka->sa.sa_restorer;
+	else {
+		/*
+		 * Set up the return code ...
+		 *
+		 *         li      v0, __NR_sigreturn
+		 *         syscall
+		 */
+		err |= __put_user(0x24020000 + __NR_sigreturn,
+		                  frame->rs_code + 0);
+		err |= __put_user(0x0000000c                 ,
+		                  frame->rs_code + 1);
+		flush_cache_sigtramp((unsigned long) frame->rs_code);
+	}
+
+	/* Create siginfo.  */
+	err |= __copy_to_user(&frame->rs_info, info, sizeof(*info));
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->rs_uc.uc_flags);
+	err |= __put_user(0, &frame->rs_uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+	                  &frame->rs_uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->regs[29]),
+	                  &frame->rs_uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size,
+	                  &frame->rs_uc.uc_stack.ss_size);
+	err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
+	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Arguments to signal handler:
+	 *
+	 *   a0 = signal number
+	 *   a1 = 0 (should be cause)
+	 *   a2 = pointer to ucontext
+	 *
+	 * $25 and c0_epc point to the signal handler, $29 points to
+	 * the struct rt_sigframe.
+	 */
+	regs->regs[ 4] = signr;
+	regs->regs[ 5] = (unsigned long) &frame->rs_info;
+	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
+	regs->regs[29] = (unsigned long) frame;
+	regs->regs[31] = (unsigned long) frame->rs_code;
+	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
+	       current->comm, current->pid, frame, regs->cp0_epc, frame->code);
+#endif
+	return;
+
+give_sigsegv:
+	if (signr == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static inline void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+	siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
+{
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(ka, regs, sig, oldset, info);
+	else
+		setup_frame(ka, regs, sig, oldset);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+}
+
+static inline void
+syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
+{
+	switch(regs->regs[0]) {
+	case ERESTARTNOHAND:
+		regs->regs[2] = EINTR;
+		break;
+	case ERESTARTSYS:
+		if(!(ka->sa.sa_flags & SA_RESTART)) {
+			regs->regs[2] = EINTR;
+			break;
+		}
+	/* fallthrough */
+	case ERESTARTNOINTR:		/* Userland will reload $v0.  */
+		regs->regs[7] = regs->regs[26];
+		regs->cp0_epc -= 8;
+	}
+
+	regs->regs[0] = 0;		/* Don't deal with this again.  */
+}
+
+asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs)
+{
+	struct k_sigaction *ka;
+	siginfo_t info;
+printk("%s: delivering signal.\n", current->comm);
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		unsigned long signr;
+
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+
+		if (!signr)
+			break;
+
+		if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+			/* Let the debugger run.  */
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code))
+				continue;
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				continue;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			/* Init gets no signals it doesn't want.  */
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGABRT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				lock_kernel();
+				sigaddset(&current->signal, signr);
+				recalc_sigpending(current);
+				current->flags |= PF_SIGNALED;
+				do_exit(exit_code);
+				/* NOTREACHED */
+			}
+		}
+
+		if (regs->regs[0])
+			syscall_restart(regs, ka);
+		/* Whee!  Actually deliver the signal.  */
+printk("%s: delivering signal.\n", __FUNCTION__);
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/*
+	 * Who's code doesn't conform to the restartable syscall convention
+	 * dies here!!!  The li instruction, a single machine instruction,
+	 * must directly be followed by the syscall instruction.
+	 */
+	if (regs->regs[0]) {
+		if (regs->regs[2] == ERESTARTNOHAND ||
+		    regs->regs[2] == ERESTARTSYS ||
+		    regs->regs[2] == ERESTARTNOINTR) {
+			regs->regs[7] = regs->regs[26];
+			regs->cp0_epc -= 8;
+		}
+	}
+	return 0;
+}
+
+/* Dummies ... */
+
+asmlinkage void sys32_sigpending(void) { panic(__FUNCTION__ " called."); }
+asmlinkage void sys32_rt_sigaction(void) { panic(__FUNCTION__ " called."); }
+asmlinkage void sys32_rt_sigprocmask(void) { panic(__FUNCTION__ " called."); }
+asmlinkage void sys32_rt_sigpending(void) { panic(__FUNCTION__ " called."); }
+asmlinkage void sys32_rt_sigtimedwait(void) { panic(__FUNCTION__ " called."); }
+asmlinkage void sys32_rt_sigqueueinfo(void) { panic(__FUNCTION__ " called."); }
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/softfp.S linux/arch/mips64/kernel/softfp.S
--- v2.3.47/linux/arch/mips64/kernel/softfp.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/softfp.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,668 @@
+/* $Id: softfp.S,v 1.1 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ *
+ * For now it's just a crude hack good enough to run certain fp programs like
+ * Mozilla.
+ * XXX: Handle MIPS II/III/IV/V enhancements, exceptions, ...
+ */
+#include <asm/regdef.h>
+#include <asm/asm.h>
+
+#ifndef __KERNEL__
+#define printk printf
+#endif
+
+#define LOCK_KERNEL
+#define UNLOCK_KERNEL
+
+/*
+ * This duplicates definitions from <linux/kernel.h>.
+ */
+#define KERN_EMERG      "<0>"   /* system is unusable                   */
+#define KERN_ALERT      "<1>"   /* action must be taken immediately     */
+#define KERN_CRIT       "<2>"   /* critical conditions                  */
+#define KERN_ERR        "<3>"   /* error conditions                     */
+#define KERN_WARNING    "<4>"   /* warning conditions                   */
+#define KERN_NOTICE     "<5>"   /* normal but significant condition     */
+#define KERN_INFO       "<6>"   /* informational                        */
+#define KERN_DEBUG      "<7>"   /* debug-level messages                 */
+
+/*
+ * This duplicates definitions from <asm/signal.h>
+ */
+#define SIGILL           4      /* Illegal instruction (ANSI).  */
+
+/*
+ * Definitions about the instruction format
+ */
+#define fd_shift	6
+#define fr_shift	21
+#define fs_shift	11
+#define ft_shift	16
+
+/*
+ * NaNs as use by the MIPS architecture
+ */
+#define S_QNaN		0x7fbfffff
+#define D_QNaN		0x7ff7ffffffffffff
+#define W_QNaN		0x7fffffff
+#define L_QNaN		0x7fffffffffffffff
+
+/*
+ * Checking for NaNs
+ */
+#define S_is_QNaN(reg,res)						\
+	sll	res, reg, S_F_size - S_F_bits
+#define D_is_QNaN(reg1,reg2,res)					\
+	sll	res, reg1, (D_F_size - 32) - (D_F_bits - 32);		\
+	or	res, reg2
+
+/*
+ * Checking for Denorms
+ */
+#define S_is_Denorm(reg,res)						\
+	li	res, 1 << (S_F_bits - 1);				\
+	and	reg, res
+
+/*
+ * Some constants that define the properties of single precission numbers.
+ */
+#define S_M_prec	24
+#define S_E_max		127
+#define S_E_min		-126
+#define S_E_bias	127
+#define S_E_bits	8
+#define S_F_bits	23
+#define S_F_size	32
+
+/* Set temp0, if exponent of reg is S_E_max + 1.  */
+#define S_is_E_max(reg,temp0,temp1)					\
+	li	temp0, (S_E_max + 1 + S_E_bias) << S_F_bits;		\
+	and	temp1, temp0, reg;					\
+	seq	temp0, temp1			/* temp0 != 0 if NaN */
+
+/* Clear temp0, if exponent of reg is S_E_min - 1.  */
+#define S_is_E_min(reg,temp0)						\
+	li	temp0, (S_E_min - 1 + S_E_bias) << S_F_bits;		\
+	and	temp0, reg	/* temp0 == 0 if denorm or zero */
+
+/* Set temp0 if reg is a NaN assuming S_is_E_max is true  */
+#define S_get_F(reg,temp0)						\
+	li	temp0, (1 << S_F_bits) - 1;				\
+	and	temp0, reg			/* temp0 != 0 if NaN */
+
+/* Set res if fraction of reg is != 0.  */
+#define S_is_Inf(reg,res)						\
+	li	res, (1 << S_F_bits) - 1;				\
+	and	res, reg			/* temp0 == 0 if Inf */
+
+
+/*
+ * Some constants that define the properties of double precission numbers.
+ */
+#define D_M_prec	53
+#define D_E_max		1023
+#define D_E_min		-1022
+#define D_E_bias	1023
+#define D_E_bits	8
+#define D_F_bits	52
+#define D_F_size	64
+
+/* Set temp0, if exponent of reg1/reg2 is D_E_max.  */
+#define D_is_E_max(reg1,reg2,temp0,temp1)				\
+	li	temp0, (D_E_max + 1 + D_E_bias) << (D_F_bits - 32);	\
+	and	temp1, temp0, reg1;					\
+	seq	temp0, temp1			/* temp0 != 0 if NaN */
+
+/* Clear temp0, if exponent of reg is D_E_min.  */
+#define D_is_E_min(reg1,reg2,res)					\
+	li	res, (D_E_min + 1 + D_E_bias) << (D_F_bits - 32);	\
+	and	res, reg1	/* temp0 == 0 if NaN or zero */
+
+/* Set res if reg is a NaN assuming S_is_E_max is true  */
+#define D_get_F(reg1,reg2,res)						\
+	li	res, (1 << (D_F_bits - 32)) - 1;			\
+	and	res, reg1			/* temp0 != 0 if NaN */
+
+/* Set temp0 if reg1/reg2 is a NaN  */
+#define D_is_NAN(reg1,reg2,temp0,temp1)					\
+	li	temp0, (1 << (D_F_bits - 32) - 1;			\
+	and	temp0, reg1;						\
+	or	temp0, reg2;						\
+	sne	temp0, zero, temp0		/* temp0 != 0 if NaN */
+
+/* Set res if fraction of reg1/reg2 is != 0.  */
+#define D_is_Inf(reg1,reg2,res)						\
+	li	res, (1 << (D_F_bits - 32)) - 1;			\
+	and	res, reg1;						\
+	or	res, reg2			/* temp0 == 0 if Inf */
+
+/* Complain about yet unhandled instruction.  */
+#define BITCH(insn)							\
+insn:	LOCK_KERNEL;							\
+	la	a1, 8f;							\
+	TEXT(#insn);							\
+	la	a1, nosim;						\
+	UNLOCK_KERNEL;							\
+	j	done
+
+	.data
+nosim: .asciz	KERN_DEBUG "Don't know how to simulate %s instruction\n"
+	.previous
+
+/*
+ * When we come here, we've saved some of the integer registers and
+ * reenabled interrupts.
+ */
+LEAF(simfp)
+	.set	noreorder
+	.cpload	$25
+	.set	reorder
+
+	subu	sp, 16
+	.cprestore 20
+	sw	ra, 16(sp)
+
+	/* For now we assume that we get the opcode to simulate passed in as
+	   an argument.  */
+	move	ta0, a0
+
+	/*
+	 * First table lookup using insn[5:0]
+	 */
+	la	ta1, lowtab
+	andi	ta2, ta0, 0x3f
+	sll	ta2, ta2, 2
+	addu	ta1, ta2
+	lw	ta1, (ta1)
+	jr	ta1
+	END(simfp)
+
+/*
+ * We only decode the lower 3 of the 5 bit in the fmt field.  That way we
+ * can keep the jump table significantly shorter.
+ */
+#define FMT_switch(insn,opc,temp0,temp1)				\
+insn:	srl	temp0, opc, 19;						\
+	andi	temp0, 0x1c;						\
+	la	temp1, insn ## .tab;					\
+	addu	temp0, temp1;						\
+	lw	temp0, (temp0);						\
+	jr	temp0;							\
+									\
+	.data;								\
+insn ## .tab:								\
+	.word	insn ## .s, insn ## .d, unimp, unimp;			\
+	.word	insn ## .w, insn ## .l, unimp, unimp;			\
+	.previous
+
+	BITCH(add)
+	BITCH(sub)
+	BITCH(mul)
+	BITCH(div)
+	BITCH(sqrt)
+	BITCH(abs)
+	BITCH(mov)
+	BITCH(neg)
+	BITCH(round.l)
+	BITCH(trunc.l)
+	BITCH(ceil.l)
+	BITCH(floor.l)
+	BITCH(round.w)
+	BITCH(trunc.w)
+	BITCH(ceil.w)
+	BITCH(floor.w)
+	BITCH(cvt.s)
+	BITCH(cvt.d)
+
+/* ------------------------------------------------------------------------ */
+
+FMT_switch(cvt.w,ta0,ta1,ta2)
+
+/* Convert a single fp to a fixed point integer.  */
+cvt.w.s:
+	srl	ta1, ta0, fs_shift	# Get source register
+	andi	ta1, 31
+	jal	s_get_fpreg
+
+	S_is_E_max(ta1,ta2,ta3)
+	beqz	ta2, 3f
+	/* Might be a NaN or Inf.  */
+	S_get_F(ta1,ta2)
+	beqz	ta2, 2f
+
+	/* It's a NaN.  IEEE says undefined.  */
+	/* Is it a QNaN?  Then the result is a QNaN as well.  */
+	S_is_QNaN(ta1,ta2)
+	bltz	ta2, 1f
+
+	/* XXX Ok, it's a SNaN.  Signal invalid exception, if enabled.
+	   For now we don't signal and supply a QNaN for result.  */
+
+1:	li	ta2, W_QNaN
+	srl	ta1, ta0, fd_shift	# Put result register
+	andi	ta1, 31
+	jal	s_put_fpreg
+	j	done
+2:
+
+	S_is_Inf(ta1,ta2)
+	bnez	ta2, 2f
+
+	/* It's +/- Inf.  Set register to +/- max. integer.  */
+	/* XXX Send invalid operation exception instead, if enabled.  */
+	srl	ta1, ta1, 31		# Extract sign bit
+	li	ta2, 0x7fffffff
+	addu	ta2, ta1
+
+	srl	ta1, ta0, fd_shift	# Put result register
+	andi	ta1, 31
+	jal	s_put_fpreg
+	j	done
+2:
+3:	
+
+	/* But then it might be a denorm or zero?  */
+	S_is_E_min(ta1,ta2)
+	bnez	ta2, 2f
+
+	/* Ok, it's a denorm or zero.  */
+	S_get_F(ta1,ta2)
+	beqz	ta2, 1f
+
+	/* It's a denorm.  */
+	/* XXX Should be signaling inexact exception, if enabled.  */
+	/* Fall through.  */
+1:
+	/* Yes, it is a denorm or zero.  Supply a zero as result.  */
+	move	ta2, zero
+	srl	ta1, ta0, fd_shift	# Put result register
+	andi	ta1, 31
+	jal	s_put_fpreg
+	j	done
+2:
+
+	/* XXX Ok, it's a normal number.  We don't handle that case yet.
+	   If we have fp hardware this case is unreached.  Add this for
+	   full fp simulation.  */
+
+	/* Done, return.  */
+	lw	ra, 16(sp)
+	addu	sp, 16
+	jr	ra
+
+/* Convert a double fp to a fixed point integer.  */
+cvt.w.d:
+	srl	ta1, ta0, fs_shift	# Get source register
+	andi	ta1, 31
+	jal	d_get_fpreg
+
+	D_is_E_max(ta1,ta2,ta3,t0)
+	beqz	ta3, 3f
+
+	/* Might be a NaN or Inf.  */
+	D_get_F(ta1,ta2,ta3)
+	or	ta3, ta2
+	beqz	ta3, 2f
+
+	/* It's a NaN.  IEEE says undefined.  */
+	/* Is it a QNaN?  Then the result is a QNaN as well.  */
+	D_is_QNaN(ta1,ta2,ta3)
+	bltz	ta3, 1f
+
+	/* XXX Ok, it's a SNaN.  Signal invalid exception, if enabled.
+	   For now we don't signal and supply a QNaN for result.  */
+
+1:	li	ta2, W_QNaN
+	srl	ta1, ta0, fd_shift	# Put result register
+	andi	ta1, 31
+	jal	s_put_fpreg
+	j	done
+2:
+
+	D_is_Inf(ta1,ta2,ta3)
+	bnez	ta3, 2f
+
+	/* It's +/- Inf.  Set register to +/- max. integer.  */
+	/* XXX Send invalid operation exception instead, if enabled.  */
+	srl	ta1, ta1, 31		# Extract sign bit
+	li	ta2, 0x7fffffff
+	addu	ta2, ta1
+
+	srl	ta1, ta0, fd_shift	# Put result register
+	andi	ta1, 31
+	jal	s_put_fpreg
+	j	done
+2:
+3:	
+
+	/* But then it might be a denorm or zero?  */
+	D_is_E_min(ta1,ta2,ta3)
+	bnez	ta3, 2f
+
+	/* Ok, it's a denorm or zero.  */
+	D_get_F(ta1,ta2,ta3)
+	or	ta3, ta2
+	beqz	ta3, 1f
+
+	/* It's a denorm.  */
+	/* XXX Should be signaling inexact exception, if enabled.  */
+	/* Fall through.  */
+1:
+	/* Yes, it is a denorm or zero.  Supply a zero as result.  */
+	move	ta2, zero
+	srl	ta1, ta0, fd_shift	# Put result register
+	andi	ta1, 31
+	jal	s_put_fpreg
+	j	done
+2:
+
+	/* XXX Ok, it's a normal number.  We don't handle that case yet.
+	   If we have fp hardware this case is only reached if the value
+	   of the source register exceeds the range which is representable
+	   in a single precission register.  For now we kludge by returning
+	   +/- maxint and don't signal overflow. */
+
+	srl	ta1, ta1, 31		# Extract sign bit
+	li	ta2, 0x7fffffff
+	addu	ta2, ta1
+
+	srl	ta1, ta0, fd_shift	# Put result register
+	andi	ta1, 31
+	jal	s_put_fpreg
+
+	/* Done, return.  */
+	lw	ra, 16(sp)
+	addu	sp, 16
+	jr	ra
+
+cvt.w.w = unimp				# undefined result
+cvt.w.l = unimp				# undefined result
+
+/* MIPS III extension, no need to handle for 32bit OS.  */
+cvt.l = unimp
+
+/* ------------------------------------------------------------------------ */
+
+	BITCH(c.f)
+	BITCH(c.un)
+	BITCH(c.eq)
+	BITCH(c.ueq)
+	BITCH(c.olt)
+	BITCH(c.ult)
+	BITCH(c.ole)
+	BITCH(c.ule)
+	BITCH(c.sf)
+	BITCH(c.ngle)
+	BITCH(c.seq)
+	BITCH(c.ngl)
+	BITCH(c.lt)
+	BITCH(c.nge)
+	BITCH(c.le)
+	BITCH(c.ngt)
+
+/* Get the single precission register which's number is in ta1.  */
+s_get_fpreg:
+	.set	noat
+	sll	AT, ta1, 2
+	sll	ta1, 3
+	addu	ta1, AT
+	la	AT, 1f
+	addu	AT, ta1
+	jr	AT
+	.set	at
+
+1:	mfc1	ta1, $0
+	jr	ra
+	mfc1	ta1, $1
+	jr	ra
+	mfc1	ta1, $2
+	jr	ra
+	mfc1	ta1, $3
+	jr	ra
+	mfc1	ta1, $4
+	jr	ra
+	mfc1	ta1, $5
+	jr	ra
+	mfc1	ta1, $6
+	jr	ra
+	mfc1	ta1, $7
+	jr	ra
+	mfc1	ta1, $8
+	jr	ra
+	mfc1	ta1, $9
+	jr	ra
+	mfc1	ta1, $10
+	jr	ra
+	mfc1	ta1, $11
+	jr	ra
+	mfc1	ta1, $12
+	jr	ra
+	mfc1	ta1, $13
+	jr	ra
+	mfc1	ta1, $14
+	jr	ra
+	mfc1	ta1, $15
+	jr	ra
+	mfc1	ta1, $16
+	jr	ra
+	mfc1	ta1, $17
+	jr	ra
+	mfc1	ta1, $18
+	jr	ra
+	mfc1	ta1, $19
+	jr	ra
+	mfc1	ta1, $20
+	jr	ra
+	mfc1	ta1, $21
+	jr	ra
+	mfc1	ta1, $22
+	jr	ra
+	mfc1	ta1, $23
+	jr	ra
+	mfc1	ta1, $24
+	jr	ra
+	mfc1	ta1, $25
+	jr	ra
+	mfc1	ta1, $26
+	jr	ra
+	mfc1	ta1, $27
+	jr	ra
+	mfc1	ta1, $28
+	jr	ra
+	mfc1	ta1, $29
+	jr	ra
+	mfc1	ta1, $30
+	jr	ra
+	mfc1	ta1, $31
+	jr	ra
+
+/*
+ * Put the value in ta2 into the single precission register which's number
+ * is in ta1.
+ */
+s_put_fpreg:
+	.set	noat
+	sll	AT, ta1, 2
+	sll	ta1, 3
+	addu	ta1, AT
+	la	AT, 1f
+	addu	AT, ta1
+	jr	AT
+	.set	at
+	
+1:	mtc1	ta2, $0
+	jr	ra
+	mtc1	ta2, $1
+	jr	ra
+	mtc1	ta2, $2
+	jr	ra
+	mtc1	ta2, $3
+	jr	ra
+	mtc1	ta2, $4
+	jr	ra
+	mtc1	ta2, $5
+	jr	ra
+	mtc1	ta2, $6
+	jr	ra
+	mtc1	ta2, $7
+	jr	ra
+	mtc1	ta2, $8
+	jr	ra
+	mtc1	ta2, $9
+	jr	ra
+	mtc1	ta2, $10
+	jr	ra
+	mtc1	ta2, $11
+	jr	ra
+	mtc1	ta2, $12
+	jr	ra
+	mtc1	ta2, $13
+	jr	ra
+	mtc1	ta2, $14
+	jr	ra
+	mtc1	ta2, $15
+	jr	ra
+	mtc1	ta2, $16
+	jr	ra
+	mtc1	ta2, $17
+	jr	ra
+	mtc1	ta2, $18
+	jr	ra
+	mtc1	ta2, $19
+	jr	ra
+	mtc1	ta2, $20
+	jr	ra
+	mtc1	ta2, $21
+	jr	ra
+	mtc1	ta2, $22
+	jr	ra
+	mtc1	ta2, $23
+	jr	ra
+	mtc1	ta2, $24
+	jr	ra
+	mtc1	ta2, $25
+	jr	ra
+	mtc1	ta2, $26
+	jr	ra
+	mtc1	ta2, $27
+	jr	ra
+	mtc1	ta2, $28
+	jr	ra
+	mtc1	ta2, $29
+	jr	ra
+	mtc1	ta2, $30
+	jr	ra
+	mtc1	ta2, $31
+	jr	ra
+
+/* Get the double precission register which's number is in ta1 into ta1/ta2.  */
+d_get_fpreg:
+	.set	noat
+	sll	ta1, 3
+	la	AT, 1f
+	addu	AT, ta1
+	jr	AT
+	.set	at
+
+1:	mfc1	ta1, $0
+	mfc1	ta2, $1
+	jr	ra
+	mfc1	ta1, $2
+	mfc1	ta2, $3
+	jr	ra
+	mfc1	ta1, $4
+	mfc1	ta2, $5
+	jr	ra
+	mfc1	ta1, $6
+	mfc1	ta2, $7
+	jr	ra
+	mfc1	ta1, $8
+	mfc1	ta2, $9
+	jr	ra
+	mfc1	ta1, $10
+	mfc1	ta2, $11
+	jr	ra
+	mfc1	ta1, $12
+	mfc1	ta2, $13
+	jr	ra
+	mfc1	ta1, $14
+	mfc1	ta2, $15
+	jr	ra
+	mfc1	ta1, $16
+	mfc1	ta2, $17
+	jr	ra
+	mfc1	ta1, $18
+	mfc1	ta2, $19
+	jr	ra
+	mfc1	ta1, $20
+	mfc1	ta2, $21
+	jr	ra
+	mfc1	ta1, $22
+	mfc1	ta2, $23
+	jr	ra
+	mfc1	ta1, $24
+	mfc1	ta2, $25
+	jr	ra
+	mfc1	ta1, $26
+	mfc1	ta2, $27
+	jr	ra
+	mfc1	ta1, $28
+	mfc1	ta2, $29
+	jr	ra
+	mfc1	ta1, $30
+	mfc1	ta2, $31
+	jr	ra
+
+/*
+ * Send an invalid operation exception.
+ */
+invalid:
+	lw	ra, 16(sp)
+	addu	sp, 16
+	jr	ra
+
+/*
+ * Done, just skip over the current instruction
+ */
+done:
+	lw	ra, 16(sp)
+	addu	sp, 16
+	jr	ra
+
+unimp:
+	/* We've run into an yet unknown instruction.  This happens either
+	   on new, yet unsupported CPU types or when the faulting instruction
+	   is being executed for cache but has been overwritten in memory.  */
+	LOCK_KERNEL
+	move	a0, ta0
+	PRINT(KERN_DEBUG "FP support: unknown fp op %08lx, ")
+	PRINT("please mail to ralf@gnu.org.\n")
+	UNLOCK_KERNEL
+
+	li	a0, SIGILL			# Die, sucker ...
+	move	a1, $28
+	jal	force_sig
+
+	lw	ra, 16(sp)
+	addu	sp, 16
+	jr	ra
+
+/*
+ * Jump table for the lowest 6 bits of a cp1 instruction.
+ */
+	.data
+lowtab:	.word	add,   sub,   mul,   div,   sqrt,  abs,   mov,   neg
+	.word	round.l,trunc.l,ceil.l,floor.l,round.w,trunc.w,ceil.w,floor.w
+	.word	unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp
+	.word	unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp
+	.word	cvt.s, cvt.d, unimp, unimp, cvt.w, cvt.l, unimp, unimp
+	.word	unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp
+	.word	c.f,   c.un,  c.eq,  c.ueq, c.olt, c.ult, c.ole, c.ule
+	.word	c.sf,  c.ngle,c.seq, c.ngl, c.lt,  c.nge, c.le, c.ngt
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/syscall.c linux/arch/mips64/kernel/syscall.c
--- v2.3.47/linux/arch/mips64/kernel/syscall.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/syscall.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,326 @@
+/* $Id: syscall.c,v 1.3 2000/02/04 07:40:24 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 - 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/mman.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+#include <linux/unistd.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <asm/ipc.h>
+#include <asm/cachectl.h>
+#include <asm/offset.h>
+#include <asm/pgalloc.h>
+#include <asm/ptrace.h>
+#include <asm/signal.h>
+#include <asm/stackframe.h>
+#include <asm/sysmips.h>
+#include <asm/uaccess.h>
+
+asmlinkage int sys_pipe(abi64_no_regargs, struct pt_regs regs)
+{
+	int fd[2];
+	int error, res;
+
+	lock_kernel();
+	error = do_pipe(fd);
+	if (error) {
+		res = error;
+		goto out;
+	}
+	regs.regs[3] = fd[1];
+	res = fd[0];
+out:
+	unlock_kernel();
+	return res;
+}
+
+asmlinkage unsigned long
+sys_mmap(unsigned long addr, size_t len, unsigned long prot,
+         unsigned long flags, unsigned long fd, off_t offset)
+{
+	struct file * file = NULL;
+	unsigned long error = -EFAULT;
+
+	down(&current->mm->mmap_sem);
+	lock_kernel();
+	if (!(flags & MAP_ANONYMOUS)) {
+		error = -EBADF;
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+        error = do_mmap(file, addr, len, prot, flags, offset);
+        if (file)
+                fput(file);
+out:
+	unlock_kernel();
+	up(&current->mm->mmap_sem);
+
+	return error;
+}
+
+asmlinkage int sys_fork(abi64_no_regargs, struct pt_regs regs)
+{
+	int res;
+
+	save_static(&regs);
+	res = do_fork(SIGCHLD, regs.regs[29], &regs);
+	return res;
+}
+
+asmlinkage int sys_clone(abi64_no_regargs, struct pt_regs regs)
+{
+	unsigned long clone_flags;
+	unsigned long newsp;
+	int res;
+
+	save_static(&regs);
+	clone_flags = regs.regs[4];
+	newsp = regs.regs[5];
+	if (!newsp)
+		newsp = regs.regs[29];
+	res = do_fork(clone_flags, newsp, &regs);
+	return res;
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(abi64_no_regargs, struct pt_regs regs)
+{
+	int error;
+	char * filename;
+
+	lock_kernel();
+	filename = getname((char *) (long)regs.regs[4]);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename, (char **) (long)regs.regs[5],
+	                  (char **) (long)regs.regs[6], &regs);
+	putname(filename);
+
+out:
+	unlock_kernel();
+	return error;
+}
+
+/*
+ * Compacrapability ...
+ */
+asmlinkage int sys_uname(struct old_utsname * name)
+{
+	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
+		return 0;
+	return -EFAULT;
+}
+
+/*
+ * Compacrapability ...
+ */
+asmlinkage int sys_olduname(struct oldold_utsname * name)
+{
+	int error;
+
+	if (!name)
+		return -EFAULT;
+	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
+		return -EFAULT;
+  
+	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
+	error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
+	error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+	error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
+	error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+	error -= __put_user(0,name->release+__OLD_UTS_LEN);
+	error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+	error -= __put_user(0,name->version+__OLD_UTS_LEN);
+	error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
+	error = __put_user(0,name->machine+__OLD_UTS_LEN);
+	error = error ? -EFAULT : 0;
+
+	return error;
+}
+
+/*
+ * Do the indirect syscall syscall.
+ *
+ * XXX This is borken.
+ */
+asmlinkage int sys_syscall(abi64_no_regargs, struct pt_regs regs)
+{
+	return -ENOSYS;
+}
+
+asmlinkage int
+sys_sysmips(int cmd, long arg1, int arg2, int arg3)
+{
+	int	*p;
+	char	*name;
+	int	flags, tmp, len, errno;
+
+	switch(cmd)
+	{
+	case SETNAME:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		name = (char *) arg1;
+		len = strlen_user(name);
+
+		if (len == 0 || len > __NEW_UTS_LEN)
+			return -EINVAL;
+		down(&uts_sem);
+		errno = -EFAULT;
+		if (!copy_from_user(system_utsname.nodename, name, len)) {
+			system_utsname.nodename[len] = '\0';
+			errno = 0;
+		}
+		up(&uts_sem);
+		return errno;
+
+	case MIPS_ATOMIC_SET:
+		/* This is broken in case of page faults and SMP ...
+		   Risc/OS fauls after maximum 20 tries with EAGAIN.  */
+		p = (int *) arg1;
+		errno = verify_area(VERIFY_WRITE, p, sizeof(*p));
+		if (errno)
+			return errno;
+		save_and_cli(flags);
+		errno = *p;
+		*p = arg2;
+		restore_flags(flags);
+
+		return errno;		/* This is broken ...  */
+
+	case MIPS_FIXADE:
+		tmp = current->thread.mflags & ~3;
+		current->thread.mflags = tmp | (arg1 & 3);
+		return 0;
+
+	case FLUSH_CACHE:
+		flush_cache_all();
+		return 0;
+
+	case MIPS_RDNVRAM:
+		return -EIO;
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage int sys_ipc (uint call, int first, int second,
+			int third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		return sys_semop (first, (struct sembuf *)ptr, second);
+	case SEMGET:
+		return sys_semget (first, second, third);
+	case SEMCTL: {
+		union semun fourth;
+		if (!ptr)
+			return -EINVAL;
+		if (get_user(fourth.__pad, (void **) ptr))
+			return -EFAULT;
+		return sys_semctl (first, second, third, fourth);
+	}
+
+	case MSGSND:
+		return sys_msgsnd (first, (struct msgbuf *) ptr, 
+				   second, third);
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+			if (!ptr)
+				return -EINVAL;
+			
+			if (copy_from_user(&tmp,
+					   (struct ipc_kludge *) ptr, 
+					   sizeof (tmp)))
+				return -EFAULT;
+			return sys_msgrcv (first, tmp.msgp, second,
+					   tmp.msgtyp, third);
+		}
+		default:
+			return sys_msgrcv (first,
+					   (struct msgbuf *) ptr,
+					   second, fifth, third);
+		}
+	case MSGGET:
+		return sys_msgget ((key_t) first, second);
+	case MSGCTL:
+		return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+			ret = sys_shmat (first, (char *) ptr, second, &raddr);
+			if (ret)
+				return ret;
+			return put_user (raddr, (ulong *) third);
+		}
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				return -EINVAL;
+			return sys_shmat (first, (char *) ptr, second, (ulong *) third);
+		}
+	case SHMDT: 
+		return sys_shmdt ((char *)ptr);
+	case SHMGET:
+		return sys_shmget (first, second, third);
+	case SHMCTL:
+		return sys_shmctl (first, second,
+				   (struct shmid_ds *) ptr);
+	default:
+		return -EINVAL;
+	}
+}
+
+/*
+ * No implemented yet ...
+ */
+asmlinkage int
+sys_cachectl(char *addr, int nbytes, int op)
+{
+	return -ENOSYS;
+}
+
+/*
+ * If we ever come here the user sp is bad.  Zap the process right away.
+ * Due to the bad stack signaling wouldn't work.
+ */
+asmlinkage void bad_stack(void)
+{
+	do_exit(SIGSEGV);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/traps.c linux/arch/mips64/kernel/traps.c
--- v2.3.47/linux/arch/mips64/kernel/traps.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/traps.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,565 @@
+/* $Id: traps.c,v 1.5 2000/02/24 00:12:41 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999 by Ralf Baechle
+ * Copyright (C) 1995, 1996 Paul M. Antoine
+ * Copyright (C) 1998 Ulf Carlsson
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+
+#include <asm/branch.h>
+#include <asm/cachectl.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/ptrace.h>
+#include <asm/watch.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/mmu_context.h>
+
+extern int console_loglevel;
+
+static inline void console_silent(void)
+{
+	console_loglevel = 0;
+}
+
+static inline void console_verbose(void)
+{
+	if (console_loglevel)
+		console_loglevel = 15;
+}
+
+extern asmlinkage void __xtlb_mod_debug(void);
+extern asmlinkage void __xtlb_tlbl_debug(void);
+extern asmlinkage void __xtlb_tlbs_debug(void);
+extern asmlinkage void handle_adel(void);
+extern asmlinkage void handle_ades(void);
+extern asmlinkage void handle_ibe(void);
+extern asmlinkage void handle_dbe(void);
+extern asmlinkage void handle_sys(void);
+extern asmlinkage void handle_bp(void);
+extern asmlinkage void handle_ri(void);
+extern asmlinkage void handle_cpu(void);
+extern asmlinkage void handle_ov(void);
+extern asmlinkage void handle_tr(void);
+extern asmlinkage void handle_fpe(void);
+extern asmlinkage void handle_watch(void);
+extern asmlinkage void handle_reserved(void);
+
+static char *cpu_names[] = CPU_NAMES;
+
+char watch_available = 0;
+char dedicated_iv_available = 0;
+char vce_available = 0;
+char mips4_available = 0;
+
+int kstack_depth_to_print = 24;
+
+/*
+ * These constant is for searching for possible module text segments.
+ * MODULE_RANGE is a guess of how much space is likely to be vmalloced.
+ */
+#define MODULE_RANGE (8*1024*1024)
+
+/*
+ * This routine abuses get_user()/put_user() to reference pointers
+ * with at least a bit of error checking ...
+ */
+void show_stack(unsigned int *sp)
+{
+	int i;
+	unsigned int *stack;
+
+	stack = sp;
+	i = 0;
+
+	printk("Stack:");
+	while ((unsigned long) stack & (PAGE_SIZE - 1)) {
+		unsigned long stackdata;
+
+		if (__get_user(stackdata, stack++)) {
+			printk(" (Bad stack address)");
+			break;
+		}
+
+		printk(" %08lx", stackdata);
+
+		if (++i > 40) {
+			printk(" ...");
+			break;
+		}
+
+		if (i % 8 == 0)
+			printk("\n      ");
+	}
+}
+
+void show_trace(unsigned int *sp)
+{
+	int i;
+	unsigned int *stack;
+	unsigned long kernel_start, kernel_end;
+	unsigned long module_start, module_end;
+	extern char _stext, _etext;
+
+	stack = sp;
+	i = 0;
+
+	kernel_start = (unsigned long) &_stext;
+	kernel_end = (unsigned long) &_etext;
+	module_start = VMALLOC_START;
+	module_end = module_start + MODULE_RANGE;
+
+	printk("\nCall Trace:");
+
+	while ((unsigned long) stack & (PAGE_SIZE -1)) {
+		unsigned long addr;
+
+		if (__get_user(addr, stack++)) {
+			printk(" (Bad stack address)\n");
+			break;
+		}
+
+		/*
+		 * If the address is either in the text segment of the
+		 * kernel, or in the region which contains vmalloc'ed
+		 * memory, it *may* be the address of a calling
+		 * routine; if so, print it so that someone tracing
+		 * down the cause of the crash will be able to figure
+		 * out the call path that was taken.
+		 */
+
+		if ((addr >= kernel_start && addr < kernel_end) ||
+		    (addr >= module_start && addr < module_end)) { 
+
+			printk(" [<%08lx>]", addr);
+			if (++i > 40) {
+				printk(" ...");
+				break;
+			}
+		}
+	}
+}
+
+void show_code(unsigned int *pc)
+{
+	long i;
+
+	printk("\nCode:");
+
+	for(i = -3 ; i < 6 ; i++) {
+		unsigned long insn;
+		if (__get_user(insn, pc + i)) {
+			printk(" (Bad address in epc)\n");
+			break;
+		}
+		printk("%c%08lx%c",(i?' ':'<'),insn,(i?' ':'>'));
+	}
+}
+
+spinlock_t die_lock;
+
+void die(const char * str, struct pt_regs * regs, unsigned long err)
+{
+	if (user_mode(regs))	/* Just return if in user mode.  */
+		return;
+
+	console_verbose();
+	spin_lock_irq(&die_lock);
+	printk("%s: %04lx\n", str, err & 0xffff);
+	show_regs(regs);
+	printk("Process %s (pid: %ld, stackpage=%08lx)\n",
+		current->comm, current->pid, (unsigned long) current);
+	show_stack((unsigned int *) regs->regs[29]);
+	show_trace((unsigned int *) regs->regs[29]);
+	show_code((unsigned int *) regs->cp0_epc);
+	printk("\n");
+	spin_unlock_irq(&die_lock);
+	do_exit(SIGSEGV);
+}
+
+void die_if_kernel(const char * str, struct pt_regs * regs, unsigned long err)
+{
+	if (!user_mode(regs))
+		die(str, regs, err);
+}
+
+void do_ov(struct pt_regs *regs)
+{
+	if (compute_return_epc(regs))
+		return;
+	force_sig(SIGFPE, current);
+}
+
+#ifdef CONFIG_MIPS_FPE_MODULE
+static void (*fpe_handler)(struct pt_regs *regs, unsigned int fcr31);
+
+/*
+ * Register_fpe/unregister_fpe are for debugging purposes only.  To make
+ * this hack work a bit better there is no error checking.
+ */
+int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31))
+{
+	fpe_handler = handler;
+	return 0;
+}
+
+int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31))
+{
+	fpe_handler = NULL;
+	return 0;
+}
+#endif
+
+/*
+ * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
+ */
+void do_fpe(struct pt_regs *regs, unsigned long fcr31)
+{
+	unsigned long pc;
+	unsigned int insn;
+
+#ifdef CONFIG_MIPS_FPE_MODULE
+	if (fpe_handler != NULL) {
+		fpe_handler(regs, fcr31);
+		return;
+	}
+#endif
+	lock_kernel();
+	if (fcr31 & 0x20000) {
+		/* Retry instruction with flush to zero ...  */
+		if (!(fcr31 & (1<<24))) {
+			printk("Setting flush to zero for %s.\n",
+			       current->comm);
+			fcr31 &= ~0x20000;
+			fcr31 |= (1<<24);
+			__asm__ __volatile__(
+				"ctc1\t%0,$31"
+				: /* No outputs */
+				: "r" (fcr31));
+			goto out;
+		}
+		pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0);
+		if (get_user(insn, (unsigned int *)pc)) {
+			/* XXX Can this happen?  */
+			force_sig(SIGSEGV, current);
+		}
+
+		printk(KERN_DEBUG "Unimplemented exception for insn %08x at 0x%08lx in %s.\n",
+		       insn, regs->cp0_epc, current->comm);
+		simfp(insn);
+	}
+
+	if (compute_return_epc(regs))
+		goto out;
+	//force_sig(SIGFPE, current);
+	printk(KERN_DEBUG "Should send SIGFPE to %s\n", current->comm);
+
+out:
+	unlock_kernel();
+}
+
+static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
+{
+	unsigned int *epc;
+
+	epc = (unsigned int *) (unsigned long) regs->cp0_epc;
+	if (regs->cp0_cause & CAUSEF_BD)
+		epc += 4;
+
+	if (verify_area(VERIFY_READ, epc, 4)) {
+		force_sig(SIGSEGV, current);
+		return 1;
+	}
+	*opcode = *epc;
+
+	return 0;
+}
+
+void do_bp(struct pt_regs *regs)
+{
+	unsigned int opcode, bcode;
+
+	/*
+	 * There is the ancient bug in the MIPS assemblers that the break
+	 * code starts left to bit 16 instead to bit 6 in the opcode.
+	 * Gas is bug-compatible ...
+	 */
+	if (get_insn_opcode(regs, &opcode))
+		return;
+	bcode = ((opcode >> 16) & ((1 << 20) - 1));
+
+	/*
+	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
+	 * insns, even for break codes that indicate arithmetic failures.
+	 * Weird ...)
+	 */
+	force_sig(SIGTRAP, current);
+}
+
+void do_tr(struct pt_regs *regs)
+{
+	unsigned int opcode, bcode;
+
+	if (get_insn_opcode(regs, &opcode))
+		return;
+	bcode = ((opcode >> 6) & ((1 << 20) - 1));
+
+	/*
+	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
+	 * insns, even for break codes that indicate arithmetic failures.
+	 * Wiered ...)
+	 */
+	force_sig(SIGTRAP, current);
+}
+
+void do_ri(struct pt_regs *regs)
+{
+	lock_kernel();
+	printk("[%s:%ld] Illegal instruction at %08lx ra=%08lx\n",
+	       current->comm, current->pid, regs->cp0_epc, regs->regs[31]);
+	unlock_kernel();
+	if (compute_return_epc(regs))
+		return;
+	force_sig(SIGILL, current);
+}
+
+void do_cpu(struct pt_regs *regs)
+{
+	u32 cpid;
+
+	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
+	if (cpid != 1)
+		goto bad_cid;
+
+	regs->cp0_status |= ST0_CU1;
+	if (last_task_used_math == current)
+		return;
+
+	if (current->used_math) {		/* Using the FPU again.  */
+		lazy_fpu_switch(last_task_used_math);
+	} else {				/* First time FPU user.  */
+		init_fpu();
+		current->used_math = 1;
+	}
+	last_task_used_math = current;
+	return;
+
+bad_cid:
+	force_sig(SIGILL, current);
+}
+
+void do_watch(struct pt_regs *regs)
+{
+	/*
+	 * We use the watch exception where available to detect stack
+	 * overflows.
+	 */
+	show_regs(regs);
+	panic("Caught WATCH exception - probably caused by stack overflow.");
+}
+
+void do_reserved(struct pt_regs *regs)
+{
+	/*
+	 * Game over - no way to handle this if it ever occurs.  Most probably
+	 * caused by a new unknown cpu type or after another deadly
+	 * hard/software error.
+	 */
+	panic("Caught reserved exception %d - should not happen.",
+	      (regs->cp0_cause & 0x1f) >> 2);
+}
+
+static inline void watch_init(unsigned long cputype)
+{
+	switch(cputype) {
+	case CPU_R10000:
+	case CPU_R4000MC:
+	case CPU_R4400MC:
+	case CPU_R4000SC:
+	case CPU_R4400SC:
+	case CPU_R4000PC:
+	case CPU_R4400PC:
+	case CPU_R4200:
+	case CPU_R4300:
+		set_except_vector(23, handle_watch);
+		watch_available = 1;
+		break;
+	}
+}
+
+/*
+ * Some MIPS CPUs have a dedicated interrupt vector which reduces the
+ * interrupt processing overhead.  Use it where available.
+ * FIXME: more CPUs than just the Nevada have this feature.
+ */
+static inline void setup_dedicated_int(void)
+{
+	extern void except_vec4(void);
+
+	switch(mips_cputype) {
+	case CPU_NEVADA:
+		memcpy((void *)(KSEG0 + 0x200), except_vec4, 8);
+		set_cp0_cause(CAUSEF_IV, CAUSEF_IV);
+		dedicated_iv_available = 1;
+	}
+}
+
+unsigned long exception_handlers[32];
+
+/*
+ * As a side effect of the way this is implemented we're limited
+ * to interrupt handlers in the address range from
+ * KSEG0 <= x < KSEG0 + 256mb on the Nevada.  Oh well ...
+ */
+void set_except_vector(int n, void *addr)
+{
+	unsigned long handler = (unsigned long) addr;
+	exception_handlers[n] = handler;
+	if (n == 0 && dedicated_iv_available) {
+		*(volatile u32 *)(KSEG0+0x200) = 0x08000000 |
+		                                 (0x03ffffff & (handler >> 2));
+		flush_icache_range(KSEG0+0x200, KSEG0 + 0x204);
+	}
+}
+
+static inline void mips4_setup(void)
+{
+	switch (mips_cputype) {
+	case CPU_R5000:
+	case CPU_R5000A:
+	case CPU_NEVADA:
+	case CPU_R8000:
+	case CPU_R10000:
+		mips4_available = 1;
+		set_cp0_status(ST0_XX, ST0_XX);
+	}
+	mips4_available = 0;
+}
+
+static inline void go_64(void)
+{
+	unsigned int bits;
+
+	bits = ST0_KX|ST0_SX|ST0_UX;
+	set_cp0_status(bits, bits);
+	printk("Entering 64-bit mode.\n");
+}
+
+void __init trap_init(void)
+{
+	extern char __tlb_refill_debug_tramp;
+	extern char __xtlb_refill_debug_tramp;
+	extern char except_vec2_generic;
+	extern char except_vec3_generic, except_vec3_r4000;
+	extern void bus_error_init(void);
+	unsigned long i;
+
+	/* Some firmware leaves the BEV flag set, clear it.  */
+	set_cp0_status(ST0_BEV, 0);
+
+	/* Copy the generic exception handler code to it's final destination. */
+	memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
+	memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80);
+
+	/*
+	 * Setup default vectors
+	 */
+	for(i = 0; i <= 31; i++)
+		set_except_vector(i, handle_reserved);
+
+	/*
+	 * Only some CPUs have the watch exceptions or a dedicated
+	 * interrupt vector.
+	 */
+	watch_init(mips_cputype);
+	setup_dedicated_int();
+	mips4_setup();
+	go_64();		/* In memoriam C128 ;-)  */
+
+	/*
+	 * Handling the following exceptions depends mostly of the cpu type
+	 */
+	switch(mips_cputype) {
+	case CPU_R10000:
+		/*
+		 * The R10000 is in most aspects similar to the R4400.  It
+		 * should get some special optimizations.
+		 */
+		write_32bit_cp0_register(CP0_FRAMEMASK, 0);
+		set_cp0_status(ST0_XX, ST0_XX);
+		goto r4k;
+
+	case CPU_R4000MC:
+	case CPU_R4400MC:
+	case CPU_R4000SC:
+	case CPU_R4400SC:
+		vce_available = 1;
+		/* Fall through ...  */
+	case CPU_R4000PC:
+	case CPU_R4400PC:
+	case CPU_R4200:
+	case CPU_R4300:
+	case CPU_R4600:
+	case CPU_R5000:
+	case CPU_NEVADA:
+r4k:
+		/* Debug TLB refill handler.  */
+		memcpy((void *)KSEG0, &__tlb_refill_debug_tramp, 0x80);
+		memcpy((void *)KSEG0 + 0x080, &__xtlb_refill_debug_tramp, 0x80);
+
+		/* Cache error vector  */
+		memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80);
+
+		if (vce_available) {
+			memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000,
+			       0x180);
+		} else {
+			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
+			       0x100);
+		}
+
+		set_except_vector(1, __xtlb_mod_debug);
+		set_except_vector(2, __xtlb_tlbl_debug);
+		set_except_vector(3, __xtlb_tlbs_debug);
+		set_except_vector(4, handle_adel);
+		set_except_vector(5, handle_ades);
+
+		/* DBE / IBE exception handler are system specific.  */
+		bus_error_init();
+
+		set_except_vector(8, handle_sys);
+		set_except_vector(9, handle_bp);
+		set_except_vector(10, handle_ri);
+		set_except_vector(11, handle_cpu);
+		set_except_vector(12, handle_ov);
+		set_except_vector(13, handle_tr);
+		set_except_vector(15, handle_fpe);
+		break;
+
+	case CPU_R8000:
+		panic("unsupported CPU type %s.\n", cpu_names[mips_cputype]);
+		break;
+
+	case CPU_UNKNOWN:
+	default:
+		panic("Unknown CPU type");
+	}
+	flush_icache_range(KSEG0, KSEG0 + 0x200);
+
+	atomic_inc(&init_mm.mm_count);	/* XXX UP?  */
+	current->active_mm = &init_mm;
+	current_pgd = init_mm.pgd;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/unaligned.c linux/arch/mips64/kernel/unaligned.c
--- v2.3.47/linux/arch/mips64/kernel/unaligned.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/kernel/unaligned.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,405 @@
+/* $Id: unaligned.c,v 1.2 2000/01/17 23:32:46 ralf Exp $
+ *
+ * Handle unaligned accesses by emulation.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * This file contains exception handler for address error exception with the
+ * special capability to execute faulting instructions in software.  The
+ * handler does not try to handle the case when the program counter points
+ * to an address not aligned to a word boundary.
+ *
+ * Putting data to unaligned addresses is a bad practice even on Intel where
+ * only the performance is affected.  Much worse is that such code is non-
+ * portable.  Due to several programs that die on MIPS due to alignment
+ * problems I decided to implement this handler anyway though I originally
+ * didn't intend to do this at all for user code.
+ *
+ * For now I enable fixing of address errors by default to make life easier.
+ * I however intend to disable this somewhen in the future when the alignment
+ * problems with user programs have been fixed.  For programmers this is the
+ * right way to go.
+ *
+ * Fixing address errors is a per process option.  The option is inherited
+ * across fork(2) and execve(2) calls.  If you really want to use the
+ * option in your user programs - I discourage the use of the software
+ * emulation strongly - use the following code in your userland stuff:
+ *
+ * #include <sys/sysmips.h>
+ *
+ * ...
+ * sysmips(MIPS_FIXADE, x);
+ * ...
+ *
+ * The argument x is 0 for disabling software emulation, enabled otherwise.
+ *
+ * Below a little program to play around with this feature.
+ *
+ * #include <stdio.h>
+ * #include <asm/sysmips.h>
+ * 
+ * struct foo {
+ *         unsigned char bar[8];
+ * };
+ *
+ * main(int argc, char *argv[])
+ * {
+ *         struct foo x = {0, 1, 2, 3, 4, 5, 6, 7};
+ *         unsigned int *p = (unsigned int *) (x.bar + 3);
+ *         int i;
+ *
+ *         if (argc > 1)
+ *                 sysmips(MIPS_FIXADE, atoi(argv[1]));
+ *
+ *         printf("*p = %08lx\n", *p);
+ *
+ *         *p = 0xdeadface;
+ *
+ *         for(i = 0; i <= 7; i++)
+ *         printf("%02x ", x.bar[i]);
+ *         printf("\n");
+ * }
+ *
+ * Coprocessor loads are not supported; I think this case is unimportant
+ * in the practice.
+ *
+ * TODO: Handle ndc (attempted store to doubleword in uncached memory)
+ *       exception for the R6000.
+ *       A store crossing a page boundary might be executed only partially.
+ *       Undo the partial store in this case.
+ */
+#include <linux/mm.h>
+#include <linux/signal.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+
+#include <asm/asm.h>
+#include <asm/branch.h>
+#include <asm/byteorder.h>
+#include <asm/inst.h>
+#include <asm/uaccess.h>
+
+#define STR(x)  __STR(x)
+#define __STR(x)  #x
+
+/*
+ * User code may only access USEG; kernel code may access the
+ * entire address space.
+ */
+#define check_axs(p,a,s)                                \
+	if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0)      \
+		goto sigbus;
+
+static inline void
+emulate_load_store_insn(struct pt_regs *regs,
+                        unsigned long addr,
+                        unsigned long pc)
+{
+	union mips_instruction insn;
+	unsigned long value, fixup;
+
+	regs->regs[0] = 0;
+	/*
+	 * This load never faults.
+	 */
+	__get_user(insn.word, (unsigned int *)pc);
+
+	switch (insn.i_format.opcode) {
+	/*
+	 * These are instructions that a compiler doesn't generate.  We
+	 * can assume therefore that the code is MIPS-aware and
+	 * really buggy.  Emulating these instructions would break the
+	 * semantics anyway.
+	 */
+	case ll_op:
+	case lld_op:
+	case sc_op:
+	case scd_op:
+
+	/*
+	 * For these instructions the only way to create an address
+	 * error is an attempted access to kernel/supervisor address
+	 * space.
+	 */
+	case ldl_op:
+	case ldr_op:
+	case lwl_op:
+	case lwr_op:
+	case sdl_op:
+	case sdr_op:
+	case swl_op:
+	case swr_op:
+	case lb_op:
+	case lbu_op:
+	case sb_op:
+		goto sigbus;
+
+	/*
+	 * The remaining opcodes are the ones that are really of interest.
+	 */
+	case lh_op:
+		check_axs(pc, addr, 2);
+		__asm__(
+			".set\tnoat\n"
+#ifdef __BIG_ENDIAN
+			"1:\tlb\t%0,0(%1)\n"
+			"2:\tlbu\t$1,1(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tlb\t%0,1(%1)\n"
+			"2:\tlbu\t$1,0(%1)\n\t"
+#endif
+			"sll\t%0,0x8\n\t"
+			"or\t%0,$1\n\t"
+			".set\tat\n\t"
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b,%2\n\t"
+			STR(PTR)"\t2b,%2\n\t"
+			".previous"
+			:"=&r" (value)
+			:"r" (addr), "i" (&&fault)
+			:"$1");
+		regs->regs[insn.i_format.rt] = value;
+		return;
+
+	case lw_op:
+		check_axs(pc, addr, 4);
+		__asm__(
+#ifdef __BIG_ENDIAN
+			"1:\tlwl\t%0,(%1)\n"
+			"2:\tlwr\t%0,3(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tlwl\t%0,3(%1)\n"
+			"2:\tlwr\t%0,(%1)\n\t"
+#endif
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b,%2\n\t"
+			STR(PTR)"\t2b,%2\n\t"
+			".previous"
+			:"=&r" (value)
+			:"r" (addr), "i" (&&fault));
+			regs->regs[insn.i_format.rt] = value;
+			return;
+
+	case lhu_op:
+		check_axs(pc, addr, 2);
+		__asm__(
+			".set\tnoat\n"
+#ifdef __BIG_ENDIAN
+			"1:\tlbu\t%0,0(%1)\n"
+			"2:\tlbu\t$1,1(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tlbu\t%0,1(%1)\n"
+			"2:\tlbu\t$1,0(%1)\n\t"
+#endif
+			"sll\t%0,0x8\n\t"
+			"or\t%0,$1\n\t"
+			".set\tat\n\t"
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b,%2\n\t"
+			STR(PTR)"\t2b,%2\n\t"
+			".previous"
+			:"=&r" (value)
+			:"r" (addr), "i" (&&fault)
+			:"$1");
+		regs->regs[insn.i_format.rt] = value;
+		return;
+
+	case lwu_op:
+		check_axs(pc, addr, 4);
+		__asm__(
+#ifdef __BIG_ENDIAN
+			"1:\tlwl\t%0,(%1)\n"
+			"2:\tlwr\t%0,3(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tlwl\t%0,3(%1)\n"
+			"2:\tlwr\t%0,(%1)\n\t"
+#endif
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b,%2\n\t"
+			STR(PTR)"\t2b,%2\n\t"
+			".previous"
+			:"=&r" (value)
+			:"r" (addr), "i" (&&fault));
+		value &= 0xffffffff;
+		regs->regs[insn.i_format.rt] = value;
+		return;
+
+	case ld_op:
+		check_axs(pc, addr, 8);
+		__asm__(
+			".set\tmips3\n"
+#ifdef __BIG_ENDIAN
+			"1:\tldl\t%0,(%1)\n"
+			"2:\tldr\t%0,7(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tldl\t%0,7(%1)\n"
+			"2:\tldr\t%0,(%1)\n\t"
+#endif
+			".set\tmips0\n\t"
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b,%2\n\t"
+			STR(PTR)"\t2b,%2\n\t"
+			".previous"
+			:"=&r" (value)
+			:"r" (addr), "i" (&&fault));
+		regs->regs[insn.i_format.rt] = value;
+		return;
+
+	case sh_op:
+		check_axs(pc, addr, 2);
+		value = regs->regs[insn.i_format.rt];
+		__asm__(
+#ifdef __BIG_ENDIAN
+			".set\tnoat\n"
+			"1:\tsb\t%0,1(%1)\n\t"
+			"srl\t$1,%0,0x8\n"
+			"2:\tsb\t$1,0(%1)\n\t"
+			".set\tat\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			".set\tnoat\n"
+			"1:\tsb\t%0,0(%1)\n\t"
+			"srl\t$1,%0,0x8\n"
+			"2:\tsb\t$1,1(%1)\n\t"
+			".set\tat\n\t"
+#endif
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b,%2\n\t"
+			STR(PTR)"\t2b,%2\n\t"
+			".previous"
+			: /* no outputs */
+			:"r" (value), "r" (addr), "i" (&&fault)
+			:"$1");
+		return;
+
+	case sw_op:
+		check_axs(pc, addr, 4);
+		value = regs->regs[insn.i_format.rt];
+		__asm__(
+#ifdef __BIG_ENDIAN
+			"1:\tswl\t%0,(%1)\n"
+			"2:\tswr\t%0,3(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tswl\t%0,3(%1)\n"
+			"2:\tswr\t%0,(%1)\n\t"
+#endif
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b,%2\n\t"
+			STR(PTR)"\t2b,%2\n\t"
+			".previous"
+			: /* no outputs */
+			:"r" (value), "r" (addr), "i" (&&fault));
+		return;
+
+	case sd_op:
+		check_axs(pc, addr, 8);
+		value = regs->regs[insn.i_format.rt];
+		__asm__(
+			".set\tmips3\n"
+#ifdef __BIG_ENDIAN
+			"1:\tsdl\t%0,(%1)\n"
+			"2:\tsdr\t%0,7(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tsdl\t%0,7(%1)\n"
+			"2:\tsdr\t%0,(%1)\n\t"
+#endif
+			".set\tmips0\n\t"
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b,%2\n\t"
+			STR(PTR)"\t2b,%2\n\t"
+			".previous"
+			: /* no outputs */
+			:"r" (value), "r" (addr), "i" (&&fault));
+		return;
+
+	case lwc1_op:
+	case ldc1_op:
+	case swc1_op:
+	case sdc1_op:
+		/*
+		 * I herewith declare: this does not happen.  So send SIGBUS.
+		 */
+		goto sigbus;
+
+	case lwc2_op:
+	case ldc2_op:
+	case swc2_op:
+	case sdc2_op:
+		/*
+		 * These are the coprocessor 2 load/stores.  The current
+		 * implementations don't use cp2 and cp2 should always be
+		 * disabled in c0_status.  So send SIGILL.
+                 * (No longer true: The Sony Praystation uses cp2 for
+                 * 3D matrix operations.  Dunno if that thingy has a MMU ...)
+		 */
+	default:
+		/*
+		 * Pheeee...  We encountered an yet unknown instruction or
+		 * cache coherence problem.  Die sucker, die ...
+		 */
+		goto sigill;
+	}
+	return;
+
+fault:
+	/* Did we have an exception handler installed? */
+	fixup = search_exception_table(regs->cp0_epc);
+	if (fixup) {
+		long new_epc;
+		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
+		printk(KERN_DEBUG "%s: Forwarding exception at [<%lx>] (%lx)\n",
+		       current->comm, regs->cp0_epc, new_epc);
+		regs->cp0_epc = new_epc;
+		return;
+	}
+
+	send_sig(SIGSEGV, current, 1);
+	return;
+sigbus:
+	send_sig(SIGBUS, current, 1);
+	return;
+sigill:
+	send_sig(SIGILL, current, 1);
+	return;
+}
+
+unsigned long unaligned_instructions;
+
+asmlinkage void do_ade(struct pt_regs *regs)
+{
+	unsigned long pc;
+
+	/*
+	 * Did we catch a fault trying to load an instruction?
+	 * This also catches attempts to activate MIPS16 code on
+	 * CPUs which don't support it.
+	 */
+	if (regs->cp0_badvaddr == regs->cp0_epc)
+		goto sigbus;
+
+	pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0);
+	if (compute_return_epc(regs))
+		return;
+	if ((current->thread.mflags & MF_FIXADE) == 0)
+		goto sigbus;
+
+	emulate_load_store_insn(regs, regs->cp0_badvaddr, pc);
+	unaligned_instructions++;
+
+	return;
+
+sigbus:
+	force_sig(SIGBUS, current);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/ld.script.elf32 linux/arch/mips64/ld.script.elf32
--- v2.3.47/linux/arch/mips64/ld.script.elf32	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/ld.script.elf32	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,110 @@
+OUTPUT_ARCH(mips)
+ENTRY(kernel_entry)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = 0x80000000;
+  .init          : { *(.init)		} =0
+  .text      :
+  {
+    _ftext = . ;
+    *(.text)
+    *(.rodata)
+    *(.rodata1)
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+  } =0
+  _etext = .;
+  PROVIDE (etext = .);
+
+  . = ALIGN(16384);
+  .data.init_task : { *(.data.init_task) }
+
+  /* Startup code */
+  . = ALIGN(4096);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(16);
+  __setup_start = .;
+  .setup.init : { *(.setup.init) }
+  __setup_end = .;
+  __initcall_start = .;
+  .initcall.init : { *(.initcall.init) }
+  __initcall_end = .;
+  . = ALIGN(4096);	/* Align double page for init_task_union */
+  __init_end = .;
+
+  . = ALIGN(4096);
+  .data.page_aligned : { *(.data.idt) }
+
+  . = ALIGN(32);
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+  .fini      : { *(.fini)    } =0
+  .reginfo : { *(.reginfo) }
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  It would
+     be more correct to do this:
+       . = .;
+     The current expression does not correctly handle the case of a
+     text segment ending precisely at the end of a page; it causes the
+     data segment to skip a page.  The above expression does not have
+     this problem, but it will currently (2/95) cause BFD to allocate
+     a single segment, combining both text and data, for this case.
+     This will prevent the text segment from being shared among
+     multiple executions of the program; I think that is more
+     important than losing a page of the virtual address space (note
+     that no actual memory is lost; the page which is skipped can not
+     be referenced).  */
+  . = .;
+  .data    :
+  {
+    _fdata = . ;
+    *(.data)
+    CONSTRUCTORS
+  }
+  .data1   : { *(.data1) }
+  _gp = . + 0x8000;
+  .lit8 : { *(.lit8) }
+  .lit4 : { *(.lit4) }
+  .ctors         : { *(.ctors)   }
+  .dtors         : { *(.dtors)   }
+  .got           : { *(.got.plt) *(.got) }
+  .dynamic       : { *(.dynamic) }
+  /* We want the small data sections together, so single-instruction offsets
+     can access them all, and initialized data all before uninitialized, so
+     we can shorten the on-disk segment size.  */
+  .sdata     : { *(.sdata) }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __bss_start = .;
+  _fbss = .;
+  .sbss      : { *(.sbss) *(.scommon) }
+  .bss       :
+  {
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  _end = . ;
+  PROVIDE (end = .);
+  }
+  /* These are needed for ELF backends which have not yet been
+     converted to the new style linker.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  /* DWARF debug sections.
+     Symbols in the .debug DWARF section are relative to the beginning of the
+     section so we begin .debug at 0.  It's not clear yet what needs to happen
+     for the others.   */
+  .debug          0 : { *(.debug) }
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  .line           0 : { *(.line) }
+  /* These must appear regardless of  .  */
+  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/ld.script.elf64 linux/arch/mips64/ld.script.elf64
--- v2.3.47/linux/arch/mips64/ld.script.elf64	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/ld.script.elf64	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,119 @@
+OUTPUT_ARCH(mips)
+ENTRY(kernel_entry)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  /* . = 0xc000000000000000; */
+
+  /* This is the value for an Origin kernel, taken from an IRIX kernel.  */
+  /* . = 0xc00000000001c000; */
+
+  /* Set the vaddr for the text segment to a value 
+        >= 0xa800 0000 0001 9000 if no symmon is going to configured
+        >= 0xa800 0000 0030 0000 otherwise  */
+
+  /* . = 0xa800000000300000; */
+  /* . = 0xa800000000300000; */
+  . = 0xffffffff80300000;
+  .text : {
+    _ftext = . ;
+    *(.text)
+    *(.rodata)
+    *(.rodata1)
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+  } = 0
+  _etext = .;
+  PROVIDE (etext = .);
+
+  . = ALIGN(16384);
+  .data.init_task : { *(.data.init_task) }
+
+  /* Startup code */
+  . = ALIGN(4096);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(16);
+  __setup_start = .;
+  .setup.init : { *(.setup.init) }
+  __setup_end = .;
+  __initcall_start = .;
+  .initcall.init : { *(.initcall.init) }
+  __initcall_end = .;
+  . = ALIGN(4096);	/* Align double page for init_task_union */
+  __init_end = .;
+
+  . = ALIGN(4096);
+  .data.page_aligned : { *(.data.idt) }
+
+  . = ALIGN(32);
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+  .fini      : { *(.fini)    } =0
+  .reginfo : { *(.reginfo) }
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  It would
+     be more correct to do this:
+       . = .;
+     The current expression does not correctly handle the case of a
+     text segment ending precisely at the end of a page; it causes the
+     data segment to skip a page.  The above expression does not have
+     this problem, but it will currently (2/95) cause BFD to allocate
+     a single segment, combining both text and data, for this case.
+     This will prevent the text segment from being shared among
+     multiple executions of the program; I think that is more
+     important than losing a page of the virtual address space (note
+     that no actual memory is lost; the page which is skipped can not
+     be referenced).  */
+  . = .;
+  .data    :
+  {
+    _fdata = . ;
+    *(.data)
+    CONSTRUCTORS
+  }
+  .data1   : { *(.data1) }
+  _gp = . + 0x8000;
+  .lit8 : { *(.lit8) }
+  .lit4 : { *(.lit4) }
+  .ctors         : { *(.ctors)   }
+  .dtors         : { *(.dtors)   }
+  .got           : { *(.got.plt) *(.got) }
+  .dynamic       : { *(.dynamic) }
+  /* We want the small data sections together, so single-instruction offsets
+     can access them all, and initialized data all before uninitialized, so
+     we can shorten the on-disk segment size.  */
+  .sdata     : { *(.sdata) }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __bss_start = .;
+  _fbss = .;
+  .sbss      : { *(.sbss) *(.scommon) }
+  .bss       :
+  {
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  _end = . ;
+  PROVIDE (end = .);
+  }
+  /* These are needed for ELF backends which have not yet been
+     converted to the new style linker.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  /* DWARF debug sections.
+     Symbols in the .debug DWARF section are relative to the beginning of the
+     section so we begin .debug at 0.  It's not clear yet what needs to happen
+     for the others.   */
+  .debug          0 : { *(.debug) }
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  .line           0 : { *(.line) }
+  /* These must appear regardless of  .  */
+  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/Makefile linux/arch/mips64/lib/Makefile
--- v2.3.47/linux/arch/mips64/lib/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/Makefile	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,17 @@
+# $Id: Makefile,v 1.2 1999/12/04 03:59:00 ralf Exp $
+#
+# Makefile for MIPS-specific library files..
+#
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+L_TARGET = lib.a
+L_OBJS	= csum_partial.o csum_partial_copy.o dump_tlb.o floppy-std.o \
+	  floppy-no.o ide-std.o ide-no.o kbd-std.o kbd-no.o rtc-std.o \
+	  rtc-no.o memset.o memcpy.o strlen_user.o strncpy_user.o \
+	  strnlen_user.o watch.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/csum_partial.S linux/arch/mips64/lib/csum_partial.S
--- v2.3.47/linux/arch/mips64/lib/csum_partial.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/csum_partial.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,243 @@
+/* $Id: csum_partial.S,v 1.2 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Quick'n'dirty IP checksum ...
+ *
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+#define ADDC(sum,reg)						\
+	addu	sum, reg;					\
+	sltu	v1, sum, reg;					\
+	addu	sum, v1
+
+#define CSUM_BIGCHUNK(src, offset, sum, t0, t1, t2, t3)		\
+	lw	t0, (offset + 0x00)(src);			\
+	lw	t1, (offset + 0x04)(src);			\
+	lw	t2, (offset + 0x08)(src); 			\
+	lw	t3, (offset + 0x0c)(src); 			\
+	ADDC(sum, t0);						\
+	ADDC(sum, t1);						\
+	ADDC(sum, t2);						\
+	ADDC(sum, t3);						\
+	lw	t0, (offset + 0x10)(src);			\
+	lw	t1, (offset + 0x14)(src);			\
+	lw	t2, (offset + 0x18)(src);			\
+	lw	t3, (offset + 0x1c)(src);			\
+	ADDC(sum, t0);						\
+	ADDC(sum, t1);						\
+	ADDC(sum, t2);						\
+	ADDC(sum, t3);						\
+
+/*
+ * a0: source address
+ * a1: length of the area to checksum
+ * a2: partial checksum
+ */
+
+#define src a0
+#define sum v0
+
+	.text
+	.set	noreorder
+
+/* unknown src alignment and < 8 bytes to go  */
+small_csumcpy:
+	move	a1, ta2
+
+	andi	ta0, a1, 4
+	beqz	ta0, 1f
+	 andi	ta0, a1, 2
+
+	/* Still a full word to go  */
+	ulw	ta1, (src)
+	daddiu	src, 4
+	ADDC(sum, ta1)
+
+1:	move	ta1, zero
+	beqz	ta0, 1f
+	 andi	ta0, a1, 1
+
+	/* Still a halfword to go  */
+	ulhu	ta1, (src)
+	daddiu	src, 2
+
+1:	beqz	ta0, 1f
+	 sll	ta1, ta1, 16
+
+	lbu	ta2, (src)
+	 nop
+
+#ifdef __MIPSEB__
+	sll	ta2, ta2, 8
+#endif
+	or	ta1, ta2
+
+1:	ADDC(sum, ta1)
+
+	/* fold checksum */
+	sll	v1, sum, 16
+	addu	sum, v1
+	sltu	v1, sum, v1
+	srl	sum, sum, 16
+	addu	sum, v1
+
+	/* odd buffer alignment? */
+	beqz	t3, 1f
+	 nop
+	sll	v1, sum, 8
+	srl	sum, sum, 8
+	or	sum, v1
+	andi	sum, 0xffff
+1:
+	.set	reorder
+	/* Add the passed partial csum.  */
+	ADDC(sum, a2)
+	jr	ra
+	.set	noreorder
+
+/* ------------------------------------------------------------------------- */
+
+	.align	5
+LEAF(csum_partial)
+	move	sum, zero
+	move	t3, zero
+
+	sltiu	t8, a1, 0x8
+	bnez	t8, small_csumcpy		/* < 8 bytes to copy */
+	 move	ta2, a1
+
+	beqz	a1, out
+	 andi	t3, src, 0x1			/* odd buffer? */
+
+hword_align:
+	beqz	t3, word_align
+	 andi	t8, src, 0x2
+
+	lbu	ta0, (src)
+	dsubu	a1, a1, 0x1
+#ifdef __MIPSEL__
+	sll	ta0, ta0, 8
+#endif
+	ADDC(sum, ta0)
+	daddu	src, src, 0x1
+	andi	t8, src, 0x2
+
+word_align:
+	beqz	t8, dword_align
+	 sltiu	t8, a1, 56
+
+	lhu	ta0, (src)
+	dsubu	a1, a1, 0x2
+	ADDC(sum, ta0)
+	sltiu	t8, a1, 56
+	daddu	src, src, 0x2
+
+dword_align:
+	bnez	t8, do_end_words
+	 move	t8, a1
+
+	andi	t8, src, 0x4
+	beqz	t8, qword_align
+	 andi	t8, src, 0x8
+
+	lw	ta0, 0x00(src)
+	dsubu	a1, a1, 0x4
+	ADDC(sum, ta0)
+	daddu	src, src, 0x4
+	andi	t8, src, 0x8
+
+qword_align:
+	beqz	t8, oword_align
+	 andi	t8, src, 0x10
+
+	lw	ta0, 0x00(src)
+	lw	ta1, 0x04(src)
+	dsubu	a1, a1, 0x8
+	ADDC(sum, ta0)
+	ADDC(sum, ta1)
+	daddu	src, src, 0x8
+	andi	t8, src, 0x10
+
+oword_align:
+	beqz	t8, begin_movement
+	 dsrl	t8, a1, 0x7
+
+	lw	ta3, 0x08(src)
+	lw	t0, 0x0c(src)
+	lw	ta0, 0x00(src)
+	lw	ta1, 0x04(src)
+	ADDC(sum, ta3)
+	ADDC(sum, t0)
+	ADDC(sum, ta0)
+	ADDC(sum, ta1)
+	dsubu	a1, a1, 0x10
+	daddu	src, src, 0x10
+	dsrl	t8, a1, 0x7
+
+begin_movement:
+	beqz	t8, 1f
+	 andi	ta2, a1, 0x40
+
+move_128bytes:
+	CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
+	CSUM_BIGCHUNK(src, 0x20, sum, ta0, ta1, ta3, t0)
+	CSUM_BIGCHUNK(src, 0x40, sum, ta0, ta1, ta3, t0)
+	CSUM_BIGCHUNK(src, 0x60, sum, ta0, ta1, ta3, t0)
+	dsubu	t8, t8, 0x01
+	bnez	t8, move_128bytes
+	 daddu	src, src, 0x80
+
+1:
+	beqz	ta2, 1f
+	 andi	ta2, a1, 0x20
+
+move_64bytes:
+	CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
+	CSUM_BIGCHUNK(src, 0x20, sum, ta0, ta1, ta3, t0)
+	daddu	src, src, 0x40
+
+1:
+	beqz	ta2, do_end_words
+	 andi	t8, a1, 0x1c
+
+move_32bytes:
+	CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
+	andi	t8, a1, 0x1c
+	daddu	src, src, 0x20
+
+do_end_words:
+	beqz	t8, maybe_end_cruft
+	 dsrl	t8, t8, 0x2
+
+end_words:
+	lw	ta0, (src)
+	dsubu	t8, t8, 0x1
+	ADDC(sum, ta0)
+	bnez	t8, end_words
+	 daddu	src, src, 0x4
+
+maybe_end_cruft:
+	andi	ta2, a1, 0x3
+
+small_memcpy:
+ j small_csumcpy; move a1, ta2		/* XXX ??? */
+	beqz	t2, out
+	 move	a1, ta2
+
+end_bytes:
+	lb	ta0, (src)
+	dsubu	a1, a1, 0x1
+	bnez	a2, end_bytes
+	 daddu	src, src, 0x1
+
+out:
+	jr	ra
+	 move	v0, sum
+	END(csum_partial)
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/csum_partial_copy.c linux/arch/mips64/lib/csum_partial_copy.c
--- v2.3.47/linux/arch/mips64/lib/csum_partial_copy.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/csum_partial_copy.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,50 @@
+/* $Id: csum_partial_copy.c,v 1.3 2000/02/05 06:47:09 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * MIPS64 specific IP/TCP/UDP checksumming routines
+ *
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ */
+#include <net/checksum.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/string.h>
+#include <asm/uaccess.h>
+
+/*
+ * copy while checksumming, otherwise like csum_partial
+ */
+unsigned int csum_partial_copy(const char *src, char *dst, 
+                               int len, unsigned int sum)
+{
+	/*
+	 * It's 2:30 am and I don't feel like doing it real ...
+	 * This is lots slower than the real thing (tm)
+	 */
+	sum = csum_partial(src, len, sum);
+	memcpy(dst, src, len);
+
+	return sum;
+}
+
+/*
+ * Copy from userspace and compute checksum.  If we catch an exception
+ * then zero the rest of the buffer.
+ */
+unsigned int csum_partial_copy_from_user (const char *src, char *dst,
+                                          int len, unsigned int sum,
+                                          int *err_ptr)
+{
+	int missing;
+
+	missing = copy_from_user(dst, src, len);
+	if (missing) {
+		memset(dst + len - missing, 0, missing);
+		*err_ptr = -EFAULT;
+	}
+		
+	return csum_partial(dst, len, sum);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/dump_tlb.c linux/arch/mips64/lib/dump_tlb.c
--- v2.3.47/linux/arch/mips64/lib/dump_tlb.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/dump_tlb.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,207 @@
+/*
+ * Dump R4x00 TLB for debugging purposes.
+ *
+ * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#define mips_tlb_entries 64
+
+void
+dump_tlb(int first, int last)
+{
+	unsigned long s_entryhi, entryhi, entrylo0, entrylo1, asid;
+	unsigned int s_index, pagemask, c0, c1, i;
+
+	s_entryhi = get_entryhi();
+	s_index = get_index();
+	asid = s_entryhi & 0xff;
+
+	for (i = first; i <= last; i++) {
+		write_32bit_cp0_register(CP0_INDEX, i);
+		__asm__ __volatile__(
+			".set\tnoreorder\n\t"
+			"nop;nop;nop;nop\n\t"
+			"tlbr\n\t"
+			"nop;nop;nop;nop\n\t"
+			".set\treorder");
+		pagemask = read_32bit_cp0_register(CP0_PAGEMASK);
+		entryhi  = get_entryhi();
+		entrylo0 = get_entrylo0();
+		entrylo1 = get_entrylo1();
+
+		/* Unused entries have a virtual address of CKSEG0.  */
+		if ((entryhi & ~0x1ffffUL) != CKSEG0
+		    && (entryhi & 0xff) == asid) {
+			/*
+			 * Only print entries in use
+			 */
+			printk("Index: %2d pgmask=%08x ", i, pagemask);
+
+			c0 = (entrylo0 >> 3) & 7;
+			c1 = (entrylo1 >> 3) & 7;
+
+			printk("va=%08lx asid=%02lx"
+			       "  [pa=%06lx c=%d d=%d v=%d g=%ld]"
+			       "  [pa=%06lx c=%d d=%d v=%d g=%ld]\n",
+			       (entryhi & ~0x1fffUL),
+			       entryhi & 0xff,
+			       entrylo0 & PAGE_MASK, c0,
+			       (entrylo0 & 4) ? 1 : 0,
+			       (entrylo0 & 2) ? 1 : 0,
+			       (entrylo0 & 1),
+			       entrylo1 & PAGE_MASK, c1,
+			       (entrylo1 & 4) ? 1 : 0,
+			       (entrylo1 & 2) ? 1 : 0,
+			       (entrylo1 & 1));
+			       
+		}
+	}
+	printk("\n");
+
+	set_entryhi(s_entryhi);
+	set_index(s_index);
+}
+
+void
+dump_tlb_all(void)
+{
+	dump_tlb(0, mips_tlb_entries - 1);
+}
+
+void
+dump_tlb_wired(void)
+{
+	int	wired;
+
+	wired = read_32bit_cp0_register(CP0_WIRED);
+	printk("Wired: %d", wired);
+	dump_tlb(0, read_32bit_cp0_register(CP0_WIRED));
+}
+
+#define BARRIER						\
+	__asm__ __volatile__(				\
+		".set\tnoreorder\n\t"			\
+		"nop;nop;nop;nop;nop;nop;nop\n\t"	\
+		".set\treorder");
+
+void
+dump_tlb_addr(unsigned long addr)
+{
+	unsigned int flags, oldpid;
+	int index;
+
+	__save_and_cli(flags);
+	oldpid = get_entryhi() & 0xff;
+	BARRIER;
+	set_entryhi((addr & PAGE_MASK) | oldpid);
+	BARRIER;
+	tlb_probe();
+	BARRIER;
+	index = get_index();
+	set_entryhi(oldpid);
+	__restore_flags(flags);
+
+	if (index < 0) {
+		printk("No entry for address 0x%08lx in TLB\n", addr);
+		return;
+	}
+
+	printk("Entry %d maps address 0x%08lx\n", index, addr);
+	dump_tlb(index, index);
+}
+
+void
+dump_tlb_nonwired(void)
+{
+	dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_tlb_entries - 1);
+}
+
+void
+dump_list_process(struct task_struct *t, void *address)
+{
+	pgd_t	*page_dir, *pgd;
+	pmd_t	*pmd;
+	pte_t	*pte, page;
+	unsigned int addr;
+	unsigned long val;
+
+	addr = (unsigned int) address;
+
+	printk("Addr                 == %08x\n", addr);
+	printk("tasks->mm.pgd        == %08x\n", (unsigned int) t->mm->pgd);
+
+	page_dir = pgd_offset(t->mm, 0);
+	printk("page_dir == %08x\n", (unsigned int) page_dir);
+
+	pgd = pgd_offset(t->mm, addr);
+	printk("pgd == %08x, ", (unsigned int) pgd);
+
+	pmd = pmd_offset(pgd, addr);
+	printk("pmd == %08x, ", (unsigned int) pmd);
+
+	pte = pte_offset(pmd, addr);
+	printk("pte == %08x, ", (unsigned int) pte);
+
+	page = *pte;
+	printk("page == %08x\n", (unsigned int) pte_val(page));
+
+	val = pte_val(page);
+	if (val & _PAGE_PRESENT) printk("present ");
+	if (val & _PAGE_READ) printk("read ");
+	if (val & _PAGE_WRITE) printk("write ");
+	if (val & _PAGE_ACCESSED) printk("accessed ");
+	if (val & _PAGE_MODIFIED) printk("modified ");
+	if (val & _PAGE_R4KBUG) printk("r4kbug ");
+	if (val & _PAGE_GLOBAL) printk("global ");
+	if (val & _PAGE_VALID) printk("valid ");
+	printk("\n");
+}
+
+void
+dump_list_current(void *address)
+{
+	dump_list_process(current, address);
+}
+
+unsigned int
+vtop(void *address)
+{
+	pgd_t	*pgd;
+	pmd_t	*pmd;
+	pte_t	*pte;
+	unsigned int addr, paddr;
+
+	addr = (unsigned long) address;
+	pgd = pgd_offset(current->mm, addr);
+	pmd = pmd_offset(pgd, addr);
+	pte = pte_offset(pmd, addr);
+	paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
+	paddr |= (addr & ~PAGE_MASK);
+
+	return paddr;
+}
+
+void
+dump16(unsigned long *p)
+{
+	int i;
+
+	for(i=0;i<8;i++)
+	{
+		printk("*%08lx == %08lx, ",
+		       (unsigned long)p, (unsigned long)*p++);
+		printk("*%08lx == %08lx\n",
+		       (unsigned long)p, (unsigned long)*p++);
+	}
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/floppy-no.c linux/arch/mips64/lib/floppy-no.c
--- v2.3.47/linux/arch/mips64/lib/floppy-no.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/floppy-no.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,58 @@
+/* $Id: floppy-no.c,v 1.2 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Dummy file for machines without standard floppy drives.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <asm/floppy.h>
+
+/*
+ * How to access the FDC's registers.
+ */
+static void no_fd_dummy(void)
+{
+	panic("no_fd_dummy called - shouldn't happen");
+}
+
+static unsigned long no_fd_getfdaddr1(void)
+{
+	return (unsigned long)-1;	/* No FDC nowhere ... */
+}
+
+static unsigned long no_fd_drive_type(unsigned long n)
+{
+	return 0;
+}
+
+struct fd_ops no_fd_ops = {
+	/*
+	 * How to access the floppy controller's ports
+	 */
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	/*
+	 * How to access the floppy DMA functions.
+	 */
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	no_fd_getfdaddr1,
+	(void *) no_fd_dummy,
+	(void *) no_fd_dummy,
+	no_fd_drive_type
+};
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/floppy-std.c linux/arch/mips64/lib/floppy-std.c
--- v2.3.47/linux/arch/mips64/lib/floppy-std.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/floppy-std.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,166 @@
+/* $Id: floppy-std.c,v 1.2 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Access the floppy hardware on PC style hardware
+ *
+ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/dma.h>
+#include <asm/floppy.h>
+#include <asm/keyboard.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mc146818rtc.h>
+#include <asm/pgtable.h>
+
+/*
+ * How to access the FDC's registers.
+ */
+static unsigned char std_fd_inb(unsigned int port)
+{
+	return inb_p(port);
+}
+
+static void std_fd_outb(unsigned char value, unsigned int port)
+{
+	outb_p(value, port);
+}
+
+/*
+ * How to access the floppy DMA functions.
+ */
+static void std_fd_enable_dma(int channel)
+{
+	enable_dma(channel);
+}
+
+static void std_fd_disable_dma(int channel)
+{
+	disable_dma(channel);
+}
+
+static int std_fd_request_dma(int channel)
+{
+	return request_dma(channel, "floppy");
+}
+
+static void std_fd_free_dma(int channel)
+{
+	free_dma(channel);
+}
+
+static void std_fd_clear_dma_ff(int channel)
+{
+	clear_dma_ff(channel);
+}
+
+static void std_fd_set_dma_mode(int channel, char mode)
+{
+	set_dma_mode(channel, mode);
+}
+
+static void std_fd_set_dma_addr(int channel, unsigned int addr)
+{
+	set_dma_addr(channel, addr);
+}
+
+static void std_fd_set_dma_count(int channel, unsigned int count)
+{
+	set_dma_count(channel, count);
+}
+
+static int std_fd_get_dma_residue(int channel)
+{
+	return get_dma_residue(channel);
+}
+
+static void std_fd_enable_irq(int irq)
+{
+	enable_irq(irq);
+}
+
+static void std_fd_disable_irq(int irq)
+{
+	disable_irq(irq);
+}
+
+static unsigned long std_fd_getfdaddr1(void)
+{
+	return 0x3f0;
+}
+
+/* Pure 2^n version of get_order */
+static int __get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+static unsigned long std_fd_dma_mem_alloc(unsigned long size)
+{
+	int order = __get_order(size);
+	unsigned long mem;
+
+	mem = __get_dma_pages(GFP_KERNEL,order);
+
+	return mem;
+}
+
+static void std_fd_dma_mem_free(unsigned long addr, unsigned long size)
+{       
+	free_pages(addr, __get_order(size));	
+}
+
+static unsigned long std_fd_drive_type(unsigned long n)
+{
+	if (n == 0)
+		return 4;	/* 3,5", 1.44mb */
+
+	return 0;
+}
+
+struct fd_ops std_fd_ops = {
+	/*
+	 * How to access the floppy controller's ports
+	 */
+	std_fd_inb,
+	std_fd_outb,
+	/*
+	 * How to access the floppy DMA functions.
+	 */
+	std_fd_enable_dma,
+	std_fd_disable_dma,
+	std_fd_request_dma,
+	std_fd_free_dma,
+	std_fd_clear_dma_ff,
+	std_fd_set_dma_mode,
+	std_fd_set_dma_addr,
+	std_fd_set_dma_count,
+	std_fd_get_dma_residue,
+	std_fd_enable_irq,
+	std_fd_disable_irq,
+        std_fd_getfdaddr1,
+        std_fd_dma_mem_alloc,
+        std_fd_dma_mem_free,
+	std_fd_drive_type
+};
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/ide-no.c linux/arch/mips64/lib/ide-no.c
--- v2.3.47/linux/arch/mips64/lib/ide-no.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/ide-no.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,71 @@
+/* $Id: ide-no.c,v 1.2 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Stub IDE routines to keep Linux from crashing on machine which don't
+ * have IDE like the Indy.
+ *
+ * Copyright (C) 1998, 1999 by Ralf Baechle
+ */
+#include <linux/hdreg.h>
+#include <linux/kernel.h>
+#include <linux/ide.h>
+#include <asm/hdreg.h>
+#include <asm/ptrace.h>
+
+static int no_ide_default_irq(ide_ioreg_t base)
+{
+	return 0;
+}
+
+static ide_ioreg_t no_ide_default_io_base(int index)
+{
+	return 0;
+}
+
+static void no_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port,
+                                    ide_ioreg_t ctrl_port, int *irq)
+{
+}
+
+static int no_ide_request_irq(unsigned int irq,
+                              void (*handler)(int,void *, struct pt_regs *),
+                              unsigned long flags, const char *device,
+                              void *dev_id)
+{
+	panic("no_no_ide_request_irq called - shouldn't happen");
+}			
+
+static void no_ide_free_irq(unsigned int irq, void *dev_id)
+{
+	panic("no_ide_free_irq called - shouldn't happen");
+}
+
+static int no_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+	panic("no_ide_check_region called - shouldn't happen");
+}
+
+static void no_ide_request_region(ide_ioreg_t from, unsigned int extent,
+                                    const char *name)
+{
+	panic("no_ide_request_region called - shouldn't happen");
+}
+
+static void no_ide_release_region(ide_ioreg_t from, unsigned int extent)
+{
+	panic("no_ide_release_region called - shouldn't happen");
+}
+
+struct ide_ops no_ide_ops = {
+	&no_ide_default_irq,
+	&no_ide_default_io_base,
+	&no_ide_init_hwif_ports,
+	&no_ide_request_irq,
+	&no_ide_free_irq,
+	&no_ide_check_region,
+	&no_ide_request_region,
+	&no_ide_release_region
+};
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/ide-std.c linux/arch/mips64/lib/ide-std.c
--- v2.3.47/linux/arch/mips64/lib/ide-std.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/ide-std.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,103 @@
+/* $Id: ide-std.c,v 1.2 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * IDE routines for typical pc-like standard configurations.
+ *
+ * Copyright (C) 1998, 1999 by Ralf Baechle
+ */
+#include <linux/sched.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+#include <linux/hdreg.h>
+#include <asm/ptrace.h>
+#include <asm/hdreg.h>
+
+static int std_ide_default_irq(ide_ioreg_t base)
+{
+	switch (base) {
+		case 0x1f0: return 14;
+		case 0x170: return 15;
+		case 0x1e8: return 11;
+		case 0x168: return 10;
+		case 0x1e0: return 8;
+		case 0x160: return 12;
+		default:
+			return 0;
+	}
+}
+
+static ide_ioreg_t std_ide_default_io_base(int index)
+{
+	switch (index) {
+		case 0:	return 0x1f0;
+		case 1:	return 0x170;
+		case 2: return 0x1e8;
+		case 3: return 0x168;
+		case 4: return 0x1e0;
+		case 5: return 0x160;
+		default:
+			return 0;
+	}
+}
+
+static void std_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port,
+                                     ide_ioreg_t ctrl_port, int *irq)
+{
+	ide_ioreg_t reg = data_port;
+	int i;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += 1;
+	}
+	if (ctrl_port) {
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+	} else {
+		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
+	}
+	if (irq != NULL)
+		*irq = 0;
+}
+
+static int std_ide_request_irq(unsigned int irq,
+                                void (*handler)(int,void *, struct pt_regs *),
+                                unsigned long flags, const char *device,
+                                void *dev_id)
+{
+	return request_irq(irq, handler, flags, device, dev_id);
+}			
+
+static void std_ide_free_irq(unsigned int irq, void *dev_id)
+{
+	free_irq(irq, dev_id);
+}
+
+static int std_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+	return check_region(from, extent);
+}
+
+static void std_ide_request_region(ide_ioreg_t from, unsigned int extent,
+                                    const char *name)
+{
+	request_region(from, extent, name);
+}
+
+static void std_ide_release_region(ide_ioreg_t from, unsigned int extent)
+{
+	release_region(from, extent);
+}
+
+struct ide_ops std_ide_ops = {
+	&std_ide_default_irq,
+	&std_ide_default_io_base,
+	&std_ide_init_hwif_ports,
+	&std_ide_request_irq,
+	&std_ide_free_irq,
+	&std_ide_check_region,
+	&std_ide_request_region,
+	&std_ide_release_region
+};
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/kbd-no.c linux/arch/mips64/lib/kbd-no.c
--- v2.3.47/linux/arch/mips64/lib/kbd-no.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/kbd-no.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,63 @@
+/* $Id: kbd-no.c,v 1.2 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Stub keyboard and psaux routines to keep Linux from crashing on machines
+ * without a keyboard.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/sched.h>
+#include <asm/keyboard.h>
+
+static void no_kbd_request_region(void)
+{
+	/* No I/O ports are being used on the Indy.  */
+}
+
+static int no_kbd_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+	return -ENODEV;
+}
+
+static int no_aux_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+	return -ENODEV;
+}
+
+static void no_aux_free_irq(void)
+{
+}
+
+static unsigned char no_kbd_read_input(void)
+{
+	return 0;
+}
+
+static void no_kbd_write_output(unsigned char val)
+{
+}
+
+static void no_kbd_write_command(unsigned char val)
+{
+}
+
+static unsigned char no_kbd_read_status(void)
+{
+	return 0;
+}
+
+struct kbd_ops no_kbd_ops = {
+	no_kbd_request_region,
+	no_kbd_request_irq,
+
+	no_aux_request_irq,
+	no_aux_free_irq,
+
+	no_kbd_read_input,
+	no_kbd_write_output,
+	no_kbd_write_command,
+	no_kbd_read_status
+};
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/kbd-std.c linux/arch/mips64/lib/kbd-std.c
--- v2.3.47/linux/arch/mips64/lib/kbd-std.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/kbd-std.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,81 @@
+/* $Id: kbd-std.c,v 1.2 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Routines for standard PC style keyboards accessible via I/O ports.
+ *
+ * Copyright (C) 1998, 1999 by Ralf Baechle
+ */
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/pc_keyb.h>
+#include <asm/keyboard.h>
+#include <asm/io.h>
+
+#define KEYBOARD_IRQ 1
+#define AUX_IRQ 12
+
+static void std_kbd_request_region(void)
+{
+	request_region(0x60, 16, "keyboard");
+}
+
+static int std_kbd_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+	return request_irq(KEYBOARD_IRQ, handler, 0, "keyboard", NULL);
+}
+
+static int std_aux_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+	return request_irq(AUX_IRQ, handler, 0, "PS/2 Mouse", NULL);
+}
+
+static void std_aux_free_irq(void)
+{
+	free_irq(AUX_IRQ, NULL);
+}
+
+static unsigned char std_kbd_read_input(void)
+{
+	return inb(KBD_DATA_REG);
+}
+
+static void std_kbd_write_output(unsigned char val)
+{
+	int status;
+
+	do {
+		status = inb(KBD_CNTL_REG);
+	} while (status & KBD_STAT_IBF);
+	outb(val, KBD_DATA_REG);
+}
+
+static void std_kbd_write_command(unsigned char val)
+{
+	int status;
+
+	do {
+		status = inb(KBD_CNTL_REG);
+	} while (status & KBD_STAT_IBF);
+	outb(val, KBD_CNTL_REG);
+}
+
+static unsigned char std_kbd_read_status(void)
+{
+	return inb(KBD_STATUS_REG);
+}
+
+struct kbd_ops std_kbd_ops = {
+	std_kbd_request_region,
+	std_kbd_request_irq,
+
+	std_aux_request_irq,
+	std_aux_free_irq,
+
+	std_kbd_read_input,
+	std_kbd_write_output,
+	std_kbd_write_command,
+	std_kbd_read_status
+};
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/memcpy.S linux/arch/mips64/lib/memcpy.S
--- v2.3.47/linux/arch/mips64/lib/memcpy.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/memcpy.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,708 @@
+/* $Id: memcpy.S,v 1.4 2000/01/27 01:05:24 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Unified implementation of memcpy, memmove and the __copy_user backend.
+ *
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * For __rmemcpy and memmove an exception is always a kernel bug, therefore
+ * they're not protected.  In order to keep the exception fixup routine
+ * simple all memory accesses in __copy_user to src rsp. dst are stricly
+ * incremental.  The fixup routine depends on $at not being changed.
+ */
+#include <asm/asm.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+/*
+ * The fixup routine for copy_to_user depends on copying strictly in
+ * increasing order.  Gas expands the ulw/usw macros in the wrong order for
+ * little endian machines, so we cannot depend on them.
+ */
+#ifdef __MIPSEB__
+#define uswL	swl
+#define uswU	swr
+#define ulwL	lwl
+#define ulwU	lwr
+#endif
+#ifdef __MIPSEL__
+#define uswL	swr
+#define uswU	swl
+#define ulwL	lwr
+#define ulwU	lwl
+#endif
+
+#define EX(insn,reg,addr,handler)			\
+9:	insn	reg, addr;				\
+	.section __ex_table,"a"; 			\
+	PTR	9b, handler; 				\
+	.previous
+
+#define UEX(insn,reg,addr,handler)			\
+9:	insn ## L reg, addr;				\
+10:	insn ## U reg, 3 + addr;			\
+	.section __ex_table,"a"; 			\
+	PTR	9b, handler; 				\
+	PTR	10b, handler; 				\
+	.previous
+
+/* ascending order, destination aligned  */
+#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
+	EX(lw, t0, (offset + 0x00)(src), l_fixup); \
+	EX(lw, t1, (offset + 0x04)(src), l_fixup); \
+	EX(lw, t2, (offset + 0x08)(src), l_fixup); \
+	EX(lw, t3, (offset + 0x0c)(src), l_fixup); \
+	EX(sw, t0, (offset + 0x00)(dst), s_fixup); \
+	EX(sw, t1, (offset + 0x04)(dst), s_fixup); \
+	EX(sw, t2, (offset + 0x08)(dst), s_fixup); \
+	EX(sw, t3, (offset + 0x0c)(dst), s_fixup); \
+	EX(lw, t0, (offset + 0x10)(src), l_fixup); \
+	EX(lw, t1, (offset + 0x14)(src), l_fixup); \
+	EX(lw, t2, (offset + 0x18)(src), l_fixup); \
+	EX(lw, t3, (offset + 0x1c)(src), l_fixup); \
+	EX(sw, t0, (offset + 0x10)(dst), s_fixup); \
+	EX(sw, t1, (offset + 0x14)(dst), s_fixup); \
+	EX(sw, t2, (offset + 0x18)(dst), s_fixup); \
+	EX(sw, t3, (offset + 0x1c)(dst), s_fixup)
+
+/* ascending order, destination unaligned  */
+#define UMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
+	EX(lw, t0, (offset + 0x00)(src), l_fixup); \
+	EX(lw, t1, (offset + 0x04)(src), l_fixup); \
+	EX(lw, t2, (offset + 0x08)(src), l_fixup); \
+	EX(lw, t3, (offset + 0x0c)(src), l_fixup); \
+	UEX(usw, t0, (offset + 0x00)(dst), s_fixup); \
+	UEX(usw, t1, (offset + 0x04)(dst), s_fixup); \
+	UEX(usw, t2, (offset + 0x08)(dst), s_fixup); \
+	UEX(usw, t3, (offset + 0x0c)(dst), s_fixup); \
+	EX(lw, t0, (offset + 0x10)(src), l_fixup); \
+	EX(lw, t1, (offset + 0x14)(src), l_fixup); \
+	EX(lw, t2, (offset + 0x18)(src), l_fixup); \
+	EX(lw, t3, (offset + 0x1c)(src), l_fixup); \
+	UEX(usw, t0, (offset + 0x10)(dst), s_fixup); \
+	UEX(usw, t1, (offset + 0x14)(dst), s_fixup); \
+	UEX(usw, t2, (offset + 0x18)(dst), s_fixup); \
+	UEX(usw, t3, (offset + 0x1c)(dst), s_fixup)
+
+	.text
+	.set	noreorder
+	.set	noat
+
+	.align	5
+LEAF(xxmemcpy)					/* a0=dst a1=src a2=len */
+	move	v0, a0				/* return value */
+__memcpy:
+FEXPORT(__copy_user)
+	xor	ta0, a0, a1
+	andi	ta0, ta0, 0x3
+	move	t3, a0
+	beqz	ta0, can_align
+	 sltiu	t8, a2, 0x8
+
+	b	memcpy_u_src			# bad alignment
+	 move	ta2, a2
+
+can_align:
+	bnez	t8, small_memcpy		# < 8 bytes to copy
+	 move	ta2, a2
+
+	beqz	a2, out
+	 andi	t8, a1, 0x1
+
+hword_align:
+	beqz	t8, word_align
+	 andi	t8, a1, 0x2
+
+	EX(lb, ta0, (a1), l_fixup)
+	dsubu	a2, a2, 0x1
+	EX(sb, ta0, (a0), s_fixup)
+	daddu	a1, a1, 0x1
+	daddu	a0, a0, 0x1
+	andi	t8, a1, 0x2
+
+word_align:
+	beqz	t8, dword_align
+	 sltiu	t8, a2, 56
+	
+	EX(lh, ta0, (a1), l_fixup)
+	dsubu	a2, a2, 0x2
+	EX(sh, ta0, (a0), s_fixup)
+	sltiu	t8, a2, 56
+	daddu	a0, a0, 0x2
+	daddu	a1, a1, 0x2
+
+dword_align:
+	bnez	t8, do_end_words
+	 move	t8, a2
+
+	andi	t8, a1, 0x4
+	beqz	t8, qword_align
+	 andi	t8, a1, 0x8
+
+	EX(lw, ta0, 0x00(a1), l_fixup)
+	dsubu	a2, a2, 0x4
+	EX(sw, ta0, 0x00(a0), s_fixup)
+	daddu	a1, a1, 0x4
+	daddu	a0, a0, 0x4
+	andi	t8, a1, 0x8
+
+qword_align:
+	beqz	t8, oword_align
+	 andi	t8, a1, 0x10
+
+	EX(lw, ta0, 0x00(a1), l_fixup)
+	EX(lw, ta1, 0x04(a1), l_fixup)
+	dsubu	a2, a2, 0x8
+	EX(sw, ta0, 0x00(a0), s_fixup)
+	EX(sw, ta1, 0x04(a0), s_fixup)
+	daddu	a1, a1, 0x8
+	andi	t8, a1, 0x10
+	daddu	a0, a0, 0x8
+
+oword_align:
+	beqz	t8, begin_movement
+	 srl	t8, a2, 0x7
+
+	EX(lw, ta3, 0x00(a1), l_fixup)
+	EX(lw, t0, 0x04(a1), l_fixup)
+	EX(lw, ta0, 0x08(a1), l_fixup)
+	EX(lw, ta1, 0x0c(a1), l_fixup)
+	EX(sw, ta3, 0x00(a0), s_fixup)
+	EX(sw, t0, 0x04(a0), s_fixup)
+	EX(sw, ta0, 0x08(a0), s_fixup)
+	EX(sw, ta1, 0x0c(a0), s_fixup)
+	dsubu	a2, a2, 0x10
+	daddu	a1, a1, 0x10
+	srl	t8, a2, 0x7
+	daddu	a0, a0, 0x10
+
+begin_movement:
+	beqz	t8, 0f
+	 andi	ta2, a2, 0x40
+
+move_128bytes:
+	MOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)
+	MOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0)
+	MOVE_BIGCHUNK(a1, a0, 0x40, ta0, ta1, ta3, t0)
+	MOVE_BIGCHUNK(a1, a0, 0x60, ta0, ta1, ta3, t0)
+	dsubu	t8, t8, 0x01
+	daddu	a1, a1, 0x80
+	bnez	t8, move_128bytes
+	 daddu	a0, a0, 0x80
+
+0:
+	beqz	ta2, 1f
+	 andi	ta2, a2, 0x20
+
+move_64bytes:
+	MOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)
+	MOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0)
+	daddu	a1, a1, 0x40
+	daddu	a0, a0, 0x40
+
+1:
+	beqz	ta2, do_end_words
+	 andi	t8, a2, 0x1c
+
+move_32bytes:
+	MOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)
+	andi	t8, a2, 0x1c
+	daddu	a1, a1, 0x20
+	daddu	a0, a0, 0x20
+
+do_end_words:
+	beqz	t8, maybe_end_cruft
+	 srl	t8, t8, 0x2
+
+end_words:
+	EX(lw, ta0, (a1), l_fixup)
+	dsubu	t8, t8, 0x1
+	EX(sw, ta0, (a0), s_fixup)
+	daddu	a1, a1, 0x4
+	bnez	t8, end_words
+	 daddu	a0, a0, 0x4
+
+maybe_end_cruft:
+	andi	ta2, a2, 0x3
+
+small_memcpy:
+	beqz	ta2, out
+	 move	a2, ta2
+
+end_bytes:
+	EX(lb, ta0, (a1), l_fixup)
+	dsubu	a2, a2, 0x1
+	EX(sb, ta0, (a0), s_fixup)
+	daddu	a1, a1, 0x1
+	bnez	a2, end_bytes
+	 daddu	a0, a0, 0x1
+
+out:	jr	ra
+	 move	a2, zero
+
+/* ------------------------------------------------------------------------- */
+
+/* Bad, bad.  At least try to align the source  */
+
+memcpy_u_src:
+	bnez	t8, small_memcpy		# < 8 bytes?
+	 move	ta2, a2
+
+	daddiu	ta0, a1, 7			# ta0: how much to align
+	ori	ta0, 7
+	xori	ta0, 7
+	dsubu	ta0, a1
+
+	UEX(ulw, ta1, 0(a1), l_fixup)		# dword alignment
+	UEX(ulw, ta2, 4(a1), l_fixup)
+	UEX(usw, ta1, 0(a0), s_fixup)
+	UEX(usw, ta2, 4(a0), s_fixup)
+
+	daddu	a1, ta0				# src
+	daddu	a0, ta0				# dst
+	dsubu	a2, ta0				# len
+
+	sltiu	t8, a2, 56
+	bnez	t8, u_do_end_words
+	 andi	t8, a2, 0x3c
+
+	andi	t8, a1, 8			# now qword aligned?
+
+u_qword_align:
+	beqz	t8, u_oword_align
+	 andi	t8, a1, 0x10
+
+	EX(lw, ta0, 0x00(a1), l_fixup)
+	EX(lw, ta1, 0x04(a1), l_fixup)
+	dsubu	a2, a2, 0x8
+	UEX(usw, ta0, 0x00(a0), s_fixup)
+	UEX(usw, ta1, 0x04(a0), s_fixup)
+	daddu	a1, a1, 0x8
+	andi	t8, a1, 0x10
+	daddu	a0, a0, 0x8
+
+u_oword_align:
+	beqz	t8, u_begin_movement
+	 srl	t8, a2, 0x7
+
+	EX(lw, ta3, 0x08(a1), l_fixup)
+	EX(lw, t0, 0x0c(a1), l_fixup)
+	EX(lw, ta0, 0x00(a1), l_fixup)
+	EX(lw, ta1, 0x04(a1), l_fixup)
+	UEX(usw, ta3, 0x08(a0), s_fixup)
+	UEX(usw, t0, 0x0c(a0), s_fixup)
+	UEX(usw, ta0, 0x00(a0), s_fixup)
+	UEX(usw, ta1, 0x04(a0), s_fixup)
+	dsubu	a2, a2, 0x10
+	daddu	a1, a1, 0x10
+	srl	t8, a2, 0x7
+	daddu	a0, a0, 0x10
+
+u_begin_movement:
+	beqz	t8, 0f
+	 andi	ta2, a2, 0x40
+
+u_move_128bytes:
+	UMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)
+	UMOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0)
+	UMOVE_BIGCHUNK(a1, a0, 0x40, ta0, ta1, ta3, t0)
+	UMOVE_BIGCHUNK(a1, a0, 0x60, ta0, ta1, ta3, t0)
+	dsubu	t8, t8, 0x01
+	daddu	a1, a1, 0x80
+	bnez	t8, u_move_128bytes
+	 daddu	a0, a0, 0x80
+
+0:
+	beqz	ta2, 1f
+	 andi	ta2, a2, 0x20
+
+u_move_64bytes:
+	UMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)
+	UMOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0)
+	daddu	a1, a1, 0x40
+	daddu	a0, a0, 0x40
+
+1:
+	beqz	ta2, u_do_end_words
+	 andi	t8, a2, 0x1c
+
+u_move_32bytes:
+	UMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)
+	andi	t8, a2, 0x1c
+	daddu	a1, a1, 0x20
+	daddu	a0, a0, 0x20
+
+u_do_end_words:
+	beqz	t8, u_maybe_end_cruft
+	 srl	t8, t8, 0x2
+
+u_end_words:
+	EX(lw, ta0, 0x00(a1), l_fixup)
+	dsubu	t8, t8, 0x1
+	UEX(usw, ta0, 0x00(a0), s_fixup)
+	daddu	a1, a1, 0x4
+	bnez	t8, u_end_words
+	 daddu	a0, a0, 0x4
+
+u_maybe_end_cruft:
+	andi	ta2, a2, 0x3
+
+u_cannot_optimize:
+	beqz	ta2, out
+	 move	a2, ta2
+
+u_end_bytes:
+	EX(lb, ta0, (a1), l_fixup)
+	dsubu	a2, a2, 0x1
+	EX(sb, ta0, (a0), s_fixup)
+	daddu	a1, a1, 0x1
+	bnez	a2, u_end_bytes
+	 daddu	a0, a0, 0x1
+
+	jr	ra
+	 move	a2, zero
+	END(xxmemcpy)
+
+/* descending order, destination aligned  */
+#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
+	lw	t0, (offset + 0x10)(src); \
+	lw	t1, (offset + 0x14)(src); \
+	lw	t2, (offset + 0x18)(src); \
+	lw	t3, (offset + 0x1c)(src); \
+	sw	t0, (offset + 0x10)(dst); \
+	sw	t1, (offset + 0x14)(dst); \
+	sw	t2, (offset + 0x18)(dst); \
+	sw	t3, (offset + 0x1c)(dst); \
+	lw	t0, (offset + 0x00)(src); \
+	lw	t1, (offset + 0x04)(src); \
+	lw	t2, (offset + 0x08)(src); \
+	lw	t3, (offset + 0x0c)(src); \
+	sw	t0, (offset + 0x00)(dst); \
+	sw	t1, (offset + 0x04)(dst); \
+	sw	t2, (offset + 0x08)(dst); \
+	sw	t3, (offset + 0x0c)(dst)
+
+/* descending order, destination ununaligned  */
+#define RUMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
+	lw	t0, (offset + 0x10)(src); \
+	lw	t1, (offset + 0x14)(src); \
+	lw	t2, (offset + 0x18)(src); \
+	lw	t3, (offset + 0x1c)(src); \
+	usw	t0, (offset + 0x10)(dst); \
+	usw	t1, (offset + 0x14)(dst); \
+	usw	t2, (offset + 0x18)(dst); \
+	usw	t3, (offset + 0x1c)(dst); \
+	lw	t0, (offset + 0x00)(src); \
+	lw	t1, (offset + 0x04)(src); \
+	lw	t2, (offset + 0x08)(src); \
+	lw	t3, (offset + 0x0c)(src); \
+	usw	t0, (offset + 0x00)(dst); \
+	usw	t1, (offset + 0x04)(dst); \
+	usw	t2, (offset + 0x08)(dst); \
+	usw	t3, (offset + 0x0c)(dst)
+
+	.align	5
+LEAF(xxmemmove)
+	sltu	ta0, a0, a1			# dst < src -> memcpy
+	bnez	ta0, xxmemcpy
+	 daddu	v0, a0, a2
+	sltu	ta0, v0, a1			# dst + len < src -> non-
+	bnez	ta0, __memcpy			# overlapping, can use memcpy
+	 move	v0, a0				/* return value */
+	END(xxmemmove)
+
+LEAF(__rmemcpy)					/* a0=dst a1=src a2=len */
+	daddu	a0, a2				# dst = dst + len
+	daddu	a1, a2				# src = src + len
+
+#if 0 /* Horror fix */
+	xor	ta0, a0, a1
+	andi	ta0, ta0, 0x3
+	move	t3, a0
+	beqz	ta0, r_can_align
+	 sltiu	t8, a2, 0x8
+
+	b	r_memcpy_u_src			# bad alignment
+	 move	ta2, a2
+
+r_can_align:
+	bnez	t8, r_small_memcpy		# < 8 bytes to copy
+	 move	ta2, a2
+
+	beqz	a2, r_out
+	 andi	t8, a1, 0x1
+
+r_hword_align:
+	beqz	t8, r_word_align
+	 andi	t8, a1, 0x2
+
+	lb	ta0, -1(a1)
+	dsubu	a2, a2, 0x1
+	sb	ta0, -1(a0)
+	dsubu	a1, a1, 0x1
+	dsubu	a0, a0, 0x1
+	andi	t8, a1, 0x2
+
+r_word_align:
+	beqz	t8, r_dword_align
+	 sltiu	t8, a2, 56
+	
+	lh	ta0, -2(a1)
+	dsubu	a2, a2, 0x2
+	sh	ta0, -2(a0)
+	sltiu	t8, a2, 56
+	dsubu	a0, a0, 0x2
+	dsubu	a1, a1, 0x2
+
+r_dword_align:
+	bnez	t8, r_do_end_words
+	 move	t8, a2
+
+	andi	t8, a1, 0x4
+	beqz	t8, r_qword_align
+	 andi	t8, a1, 0x8
+
+	lw	ta0, -4(a1)
+	dsubu	a2, a2, 0x4
+	sw	ta0, -4(a0)
+	dsubu	a1, a1, 0x4
+	dsubu	a0, a0, 0x4
+	andi	t8, a1, 0x8
+
+r_qword_align:
+	beqz	t8, r_oword_align
+	 andi	t8, a1, 0x10
+
+	dsubu	a1, a1, 0x8
+	lw	ta0, 0x04(a1)
+	lw	ta1, 0x00(a1)
+	dsubu	a0, a0, 0x8
+	sw	ta0, 0x04(a0)
+	sw	ta1, 0x00(a0)
+	dsubu	a2, a2, 0x8
+
+	andi	t8, a1, 0x10
+
+r_oword_align:
+	beqz	t8, r_begin_movement
+	 srl	t8, a2, 0x7
+
+	dsubu	a1, a1, 0x10
+	lw	ta3, 0x08(a1)			# assumes subblock ordering
+	lw	t0, 0x0c(a1)
+	lw	ta0, 0x00(a1)
+	lw	ta1, 0x04(a1)
+	dsubu	a0, a0, 0x10
+	sw	ta3, 0x08(a0)
+	sw	t0, 0x0c(a0)
+	sw	ta0, 0x00(a0)
+	sw	ta1, 0x04(a0)
+	dsubu	a2, a2, 0x10
+	srl	t8, a2, 0x7
+
+r_begin_movement:
+	beqz	t8, 0f
+	 andi	ta2, a2, 0x40
+
+r_move_128bytes:
+	RMOVE_BIGCHUNK(a1, a0, -0x80, ta0, ta1, ta3, t0)
+	RMOVE_BIGCHUNK(a1, a0, -0x60, ta0, ta1, ta3, t0)
+	RMOVE_BIGCHUNK(a1, a0, -0x40, ta0, ta1, ta3, t0)
+	RMOVE_BIGCHUNK(a1, a0, -0x20, ta0, ta1, ta3, t0)
+	dsubu	t8, t8, 0x01
+	dsubu	a1, a1, 0x80
+	bnez	t8, r_move_128bytes
+	 dsubu	a0, a0, 0x80
+
+0:
+	beqz	ta2, 1f
+	 andi	ta2, a2, 0x20
+
+r_move_64bytes:
+	dsubu	a1, a1, 0x40
+	dsubu	a0, a0, 0x40
+	RMOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0)
+	RMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)
+
+1:
+	beqz	ta2, r_do_end_words
+	 andi	t8, a2, 0x1c
+
+r_move_32bytes:
+	dsubu	a1, a1, 0x20
+	dsubu	a0, a0, 0x20
+	RMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)
+	andi	t8, a2, 0x1c
+
+r_do_end_words:
+	beqz	t8, r_maybe_end_cruft
+	 srl	t8, t8, 0x2
+
+r_end_words:
+	lw	ta0, -4(a1)
+	dsubu	t8, t8, 0x1
+	sw	ta0, -4(a0)
+	dsubu	a1, a1, 0x4
+	bnez	t8, r_end_words
+	 dsubu	a0, a0, 0x4
+
+r_maybe_end_cruft:
+	andi	ta2, a2, 0x3
+
+r_small_memcpy:
+	beqz	ta2, r_out
+	 move	a2, ta2
+#endif /* Horror fix */
+
+r_end_bytes:
+	lb	ta0, -1(a1)
+	dsubu	a2, a2, 0x1
+	sb	ta0, -1(a0)
+	dsubu	a1, a1, 0x1
+	bnez	a2, r_end_bytes
+	 dsubu	a0, a0, 0x1
+
+r_out:
+	jr	ra
+	 move	a2, zero
+
+#if 0 /* Horror fix */
+/* ------------------------------------------------------------------------- */
+
+/* Bad, bad.  At least try to align the source  */
+
+r_memcpy_u_src:
+	bnez	t8, r_small_memcpy		# < 8 bytes?
+	 move	ta2, a2
+
+	andi	ta0, a1, 7			# ta0: how much to align
+
+	ulw	ta1, -8(a1)			# dword alignment
+	ulw	ta2, -4(a1)
+	usw	ta1, -8(a0)
+	usw	ta2, -4(a0)
+
+	dsubu	a1, ta0				# src
+	dsubu	a0, ta0				# dst
+	dsubu	a2, ta0				# len
+
+	sltiu	t8, a2, 56
+	bnez	t8, ru_do_end_words
+	 andi	t8, a2, 0x3c
+
+	andi	t8, a1, 8			# now qword aligned?
+
+ru_qword_align:
+	beqz	t8, ru_oword_align
+	 andi	t8, a1, 0x10
+
+	dsubu	a1, a1, 0x8
+	lw	ta0, 0x00(a1)
+	lw	ta1, 0x04(a1)
+	dsubu	a0, a0, 0x8
+	usw	ta0, 0x00(a0)
+	usw	ta1, 0x04(a0)
+	dsubu	a2, a2, 0x8
+
+	andi	t8, a1, 0x10
+
+ru_oword_align:
+	beqz	t8, ru_begin_movement
+	 srl	t8, a2, 0x7
+
+	dsubu	a1, a1, 0x10
+	lw	ta3, 0x08(a1)			# assumes subblock ordering
+	lw	t0, 0x0c(a1)
+	lw	ta0, 0x00(a1)
+	lw	ta1, 0x04(a1)
+	dsubu	a0, a0, 0x10
+	usw	ta3, 0x08(a0)
+	usw	t0, 0x0c(a0)
+	usw	ta0, 0x00(a0)
+	usw	ta1, 0x04(a0)
+	dsubu	a2, a2, 0x10
+
+	srl	t8, a2, 0x7
+
+ru_begin_movement:
+	beqz	t8, 0f
+	 andi	ta2, a2, 0x40
+
+ru_move_128bytes:
+	RUMOVE_BIGCHUNK(a1, a0, -0x80, ta0, ta1, ta3, t0)
+	RUMOVE_BIGCHUNK(a1, a0, -0x60, ta0, ta1, ta3, t0)
+	RUMOVE_BIGCHUNK(a1, a0, -0x40, ta0, ta1, ta3, t0)
+	RUMOVE_BIGCHUNK(a1, a0, -0x20, ta0, ta1, ta3, t0)
+	dsubu	t8, t8, 0x01
+	dsubu	a1, a1, 0x80
+	bnez	t8, ru_move_128bytes
+	 dsubu	a0, a0, 0x80
+
+0:
+	beqz	ta2, 1f
+	 andi	ta2, a2, 0x20
+
+ru_move_64bytes:
+	dsubu	a1, a1, 0x40
+	dsubu	a0, a0, 0x40
+	RUMOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0)
+	RUMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)
+
+1:
+	beqz	ta2, ru_do_end_words
+	 andi	t8, a2, 0x1c
+
+ru_move_32bytes:
+	dsubu	a1, a1, 0x20
+	dsubu	a0, a0, 0x20
+	RUMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)
+	andi	t8, a2, 0x1c
+
+ru_do_end_words:
+	beqz	t8, ru_maybe_end_cruft
+	 srl	t8, t8, 0x2
+
+ru_end_words:
+	lw	ta0, -4(a1)
+	usw	ta0, -4(a0)
+	dsubu	t8, t8, 0x1
+	dsubu	a1, a1, 0x4
+	bnez	t8, ru_end_words
+	 dsubu	a0, a0, 0x4
+
+ru_maybe_end_cruft:
+	andi	ta2, a2, 0x3
+
+ru_cannot_optimize:
+	beqz	ta2, r_out
+	 move	a2, ta2
+
+ru_end_bytes:
+	lb	ta0, -1(a1)
+	dsubu	a2, a2, 0x1
+	sb	ta0, -1(a0)
+	dsubu	a1, a1, 0x1
+	bnez	a2, ru_end_bytes
+	 dsubu	a0, a0, 0x1
+
+	jr	ra
+	 move	a2, zero
+#endif /* Horror fix */
+	END(__rmemcpy)
+
+l_fixup:					# clear the rest of the buffer
+	ld	ta0, THREAD_BUADDR($28)
+	 nop
+	dsubu	a2, AT, ta0			# a2 bytes to go
+	daddu	a0, ta0				# compute start address in a1
+	dsubu	a0, a1
+	j	__bzero
+	 move	a1, zero
+
+s_fixup:
+	jr	ra
+	 nop
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/memset.S linux/arch/mips64/lib/memset.S
--- v2.3.47/linux/arch/mips64/lib/memset.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/memset.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,139 @@
+/* $Id: memset.S,v 1.3 2000/01/16 01:37:19 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+#define EX(insn,reg,addr,handler)			\
+9:	insn	reg, addr;				\
+	.section __ex_table,"a"; 			\
+	PTR	9b, handler; 				\
+	.previous
+
+#define F_FILL64(dst, offset, val, fixup)		\
+	EX(sd, val, (offset + 0x00)(dst), fixup);	\
+	EX(sd, val, (offset + 0x08)(dst), fixup);	\
+	EX(sd, val, (offset + 0x10)(dst), fixup);	\
+	EX(sd, val, (offset + 0x18)(dst), fixup);	\
+	EX(sd, val, (offset + 0x20)(dst), fixup);	\
+	EX(sd, val, (offset + 0x28)(dst), fixup);	\
+	EX(sd, val, (offset + 0x30)(dst), fixup);	\
+	EX(sd, val, (offset + 0x38)(dst), fixup)
+
+/*
+ * memset(void *s, int c, size_t n)
+ *
+ * a0: start of area to clear
+ * a1: char to fill with
+ * a2: size of area to clear
+ */
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+	.set	noreorder
+	.align	5
+LEAF(memset)
+	beqz	a1, 1f
+	 move	v0, a0				/* result */
+
+	andi	a1, 0xff			/* spread fillword */
+	dsll	t1, a1, 8
+	or	a1, t1
+	dsll	t1, a1, 16
+	or	a1, t1
+	dsll	t1, a1, 32
+	or	a1, t1
+
+1:
+
+FEXPORT(__bzero)
+	sltiu	t0, a2, 8			/* very small region? */
+	bnez	t0, small_memset
+	 andi	t0, a0, 7			/* aligned? */
+
+	beqz	t0, 1f
+	 dsubu	t0, 8				/* alignment in bytes */
+
+#ifdef __MIPSEB__
+	EX(sdl, a1, (a0), first_fixup)		/* make dword aligned */
+#endif
+#ifdef __MIPSEL__
+	EX(sdr, a1, (a0), first_fixup)		/* make dword aligned */
+#endif
+	dsubu	a0, t0				/* dword align ptr */
+	daddu	a2, t0				/* correct size */
+
+1:	ori	t1, a2, 0x3f			/* # of full blocks */
+	xori	t1, 0x3f
+	beqz	t1, memset_partial		/* no block to fill */
+	 andi	t0, a2, 0x38
+
+	daddu	t1, a0				/* end address */
+	.set	reorder
+1:	daddiu	a0, 64
+	F_FILL64(a0, -64, a1, fwd_fixup)
+	bne	t1, a0, 1b
+	.set	noreorder
+
+memset_partial:
+	la	t1, 2f				/* where to start */
+	.set	noat
+	dsrl	AT, t0, 1
+	dsubu	t1, AT
+	.set	noat
+	jr	t1
+	 daddu	a0, t0				/* dest ptr */
+
+	F_FILL64(a0, -64, a1, partial_fixup)	/* ... but first do dwds ... */
+2:	andi	a2, 7				/* 0 <= n <= 7 to go */
+
+	beqz	a2, 1f
+	 daddu	a0, a2				/* What's left */
+#ifdef __MIPSEB__
+	EX(sdr, a1, -1(a0), last_fixup)
+#endif
+#ifdef __MIPSEL__
+	EX(sdl, a1, -1(a0), last_fixup)
+#endif
+1:	jr	ra
+	 move	a2, zero
+
+small_memset:
+	beqz	a2, 2f
+	 daddu	t1, a0, a2
+
+1:	daddiu	a0, 1				/* fill bytewise */
+	bne	t1, a0, 1b
+	 sb	a1, -1(a0)
+
+2:	jr	ra				/* done */
+	 move	a2, zero
+	END(memset)
+
+first_fixup:
+	jr	ra
+	 nop
+
+fwd_fixup:
+	ld	t0, THREAD_BUADDR($28)
+	andi	a2, 0x3f
+	daddu	a2, t1
+	jr	ra
+	 dsubu	a2, t0
+
+partial_fixup:
+	ld	t0, THREAD_BUADDR($28)
+	andi	a2, 7
+	daddu	a2, t1
+	jr	ra
+	 dsubu	a2, t0
+
+last_fixup:
+	jr	ra
+	 andi	v1, a2, 7
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/rtc-no.c linux/arch/mips64/lib/rtc-no.c
--- v2.3.47/linux/arch/mips64/lib/rtc-no.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/rtc-no.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,34 @@
+/* $Id: rtc-no.c,v 1.2 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Stub RTC routines to keep Linux from crashing on machine which don't
+ * have a RTC chip.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/mc146818rtc.h>
+
+static unsigned char no_rtc_read_data(unsigned long addr)
+{
+	panic("no_rtc_read_data called - shouldn't happen.");
+}
+
+static void no_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	panic("no_rtc_write_data called - shouldn't happen.");
+}
+
+static int no_rtc_bcd_mode(void)
+{
+	panic("no_rtc_bcd_mode called - shouldn't happen.");
+}
+
+struct rtc_ops no_rtc_ops = {
+	&no_rtc_read_data,
+	&no_rtc_write_data,
+	&no_rtc_bcd_mode
+};
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/rtc-std.c linux/arch/mips64/lib/rtc-std.c
--- v2.3.47/linux/arch/mips64/lib/rtc-std.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/rtc-std.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,35 @@
+/* $Id: rtc-std.c,v 1.2 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * RTC routines for PC style attached Dallas chip.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/mc146818rtc.h>
+#include <asm/io.h>
+
+static unsigned char std_rtc_read_data(unsigned long addr)
+{
+	outb_p(addr, RTC_PORT(0));
+	return inb_p(RTC_PORT(1));
+}
+
+static void std_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	outb_p(addr, RTC_PORT(0));
+	outb_p(data, RTC_PORT(1));
+}
+
+static int std_rtc_bcd_mode(void)
+{
+	return 1;
+}
+
+struct rtc_ops std_rtc_ops = {
+	&std_rtc_read_data,
+	&std_rtc_write_data,
+	&std_rtc_bcd_mode
+};
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/strlen_user.S linux/arch/mips64/lib/strlen_user.S
--- v2.3.47/linux/arch/mips64/lib/strlen_user.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/strlen_user.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,45 @@
+/* $Id: strlen_user.S,v 1.3 2000/01/17 23:32:46 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1996, 1998, 1999 by Ralf Baechle
+ * Copyright (c) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+#include <asm/sgidefs.h>
+
+#define EX(insn,reg,addr,handler)			\
+9:	insn	reg, addr;				\
+	.section __ex_table,"a";			\
+	PTR	9b, handler;				\
+	.previous
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+LEAF(__strlen_user_asm)
+	ld	v0, THREAD_CURDS($28)			# pointer ok?
+	and	v0, a0
+	bltz	v0, fault
+
+FEXPORT(__strlen_user_nocheck_asm)
+	move	v0, a0
+1:	EX(lb, ta0, (v0), fault)
+	daddiu	v0, 1
+	bnez	ta0, 1b
+	dsubu	v0, a0
+	jr	ra
+	END(__strlen_user_asm)
+
+	.section	__ex_table,"a"
+	PTR		1b, fault
+	.previous
+
+fault:	move	v0, zero
+	jr	ra
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/strncpy_user.S linux/arch/mips64/lib/strncpy_user.S
--- v2.3.47/linux/arch/mips64/lib/strncpy_user.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/strncpy_user.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,59 @@
+/* $Id: strncpy_user.S,v 1.3 2000/01/17 23:32:46 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1996, 1999 by Ralf Baechle
+ */
+#include <linux/errno.h>
+#include <asm/asm.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+#define EX(insn,reg,addr,handler)			\
+9:	insn	reg, addr;				\
+	.section __ex_table,"a";			\
+	PTR	9b, handler;				\
+	.previous
+
+/*
+ * Returns: -EFAULT if exception before terminator, N if the entire
+ * buffer filled, else strlen.
+ */
+
+/*
+ * Ugly special case have to check: we might get passed a user space
+ * pointer which wraps into the kernel space.  We don't deal with that.  If
+ * it happens at most some bytes of the exceptions handlers will be copied.
+ */
+
+LEAF(__strncpy_from_user_asm)
+	ld	v0, THREAD_CURDS($28)		# pointer ok?
+	and	v0, a1
+	bltz	v0, fault
+
+FEXPORT(__strncpy_from_user_nocheck_asm)
+	move	v0, zero
+	move	v1, a1
+	.set	noreorder
+1:	EX(lbu,	 ta0, (v1), fault)
+	daddiu	v1, 1
+	beqz	ta0, 2f
+	 sb	ta0, (a0)
+	daddiu	v0, 1
+	bne	v0, a2, 1b
+	 daddiu	a0, 1
+	.set	reorder
+2:	daddu	ta0, a1, v0
+	xor	ta0, a1
+	bltz	ta0, fault
+	jr	ra				# return n
+	END(__strncpy_from_user_asm)
+
+fault:	li	v0, -EFAULT
+	jr	ra
+
+	.section	__ex_table,"a"
+	PTR	1b, fault
+	.previous
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/strnlen_user.S linux/arch/mips64/lib/strnlen_user.S
--- v2.3.47/linux/arch/mips64/lib/strnlen_user.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/strnlen_user.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,47 @@
+/* $Id: strnlen_user.S,v 1.1 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1996, 1998, 1999 by Ralf Baechle
+ * Copyright (c) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+#include <asm/sgidefs.h>
+
+#define EX(insn,reg,addr,handler)			\
+9:	insn	reg, addr;				\
+	.section __ex_table,"a";			\
+	PTR	9b, handler;				\
+	.previous
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error, len on string but at max a1 otherwise
+ */
+LEAF(__strnlen_user_asm)
+	ld	v0, THREAD_CURDS($28)	# pointer ok?
+	and	v0, ta0
+	bltz	v0, fault
+
+EXPORT(__strnlen_user_nocheck_asm)
+	move	v0, a0
+	daddu	a1, a0			# stop pointer
+1:	beq	v0, a1, 1f		# limit reached?
+	EX(lb, ta0, (v0), fault)
+	daddiu	v0, 1
+	bnez	ta0, 1b
+1:	dsubu	v0, a0
+	jr	ra
+	END(__strnlen_user_asm)
+
+	.section	__ex_table,"a"
+	PTR		1b, fault
+	.previous
+
+fault:	move	v0, zero
+	jr	ra
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/lib/watch.S linux/arch/mips64/lib/watch.S
--- v2.3.47/linux/arch/mips64/lib/watch.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/lib/watch.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,61 @@
+/* $Id: watch.S,v 1.2 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Kernel debug stuff to use the Watch registers.
+ * Useful to find stack overflows, dangling pointers etc.
+ *
+ * Copyright (C) 1995, 1996, 1999 by Ralf Baechle
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+
+		.set	noreorder
+/*
+ * Parameter: a0 - logic address to watch
+ *                 Currently only KSEG0 addresses are allowed!
+ *            a1 - set bit #1 to trap on load references
+ *                     bit #0 to trap on store references
+ * Results  : none
+ */
+		LEAF(__watch_set)
+		li	t0,0x80000000
+		subu	a0,t0
+		ori	a0,7
+		xori	a0,7
+		or	a0,a1
+		mtc0	a0,CP0_WATCHLO
+		sw	a0,watch_savelo
+
+		jr	ra
+		 mtc0	zero,CP0_WATCHHI
+		END(__watch_set)
+
+/*
+ * Parameter: none
+ * Results  : none
+ */
+		LEAF(__watch_clear)
+		jr	ra
+		 mtc0	zero,CP0_WATCHLO
+		END(__watch_clear)
+
+/*
+ * Parameter: none
+ * Results  : none
+ */
+		LEAF(__watch_reenable)
+		lw	t0,watch_savelo
+		jr	ra
+		 mtc0	t0,CP0_WATCHLO
+		END(__watch_reenable)
+
+/*
+ * Saved value of the c0_watchlo register for watch_reenable()
+ */
+		.data
+watch_savelo:	.word	0
+		.text
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/mm/Makefile linux/arch/mips64/mm/Makefile
--- v2.3.47/linux/arch/mips64/mm/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mm/Makefile	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,33 @@
+# $Id: Makefile,v 1.5 2000/02/24 00:12:41 ralf Exp $
+#
+# Makefile for the Linux/MIPS-specific parts of the memory manager.
+#
+
+O_TARGET := mm.o
+O_OBJS	 := extable.o init.o fault.o loadmmu.o
+
+ifdef CONFIG_CPU_R4300
+O_OBJS	+= r4xx0.o
+endif
+ifdef CONFIG_CPU_R4X00
+O_OBJS	+= r4xx0.o
+endif
+ifdef CONFIG_CPU_R5000
+O_OBJS	+= r4xx0.o
+endif
+ifdef CONFIG_CPU_NEVADA
+O_OBJS	+= r4xx0.o
+endif
+ifdef CONFIG_CPU_R10000
+O_OBJS	+= andes.o
+endif
+
+ifdef CONFIG_SGI_IP22
+O_OBJS   += umap.o
+endif
+
+ifdef CONFIG_BAGET_MIPS
+O_OBJS   += umap.o
+endif
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/mm/andes.c linux/arch/mips64/mm/andes.c
--- v2.3.47/linux/arch/mips64/mm/andes.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mm/andes.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,475 @@
+/* $Id: andes.c,v 1.6 2000/02/24 00:12:41 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/r10kcache.h>
+#include <asm/system.h>
+#include <asm/sgialib.h>
+#include <asm/mmu_context.h>
+
+/* CP0 hazard avoidance.  I think we can drop this for the R10000.  */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+/* R10000 has no Create_Dirty type cacheops.  */
+static void andes_clear_page(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tsd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page), "I" (PAGE_SIZE)
+		:"$1", "memory");
+}
+
+static void andes_copy_page(void * to, void * from)
+{
+	unsigned long dummy1, dummy2, reg1, reg2;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%6\n"
+		"1:\tld\t%2,(%1)\n\t"
+		"ld\t%3,8(%1)\n\t"
+		"sd\t%2,(%0)\n\t"
+		"sd\t%3,8(%0)\n\t"
+		"ld\t%2,16(%1)\n\t"
+		"ld\t%3,24(%1)\n\t"
+		"sd\t%2,16(%0)\n\t"
+		"sd\t%3,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"daddiu\t%1,64\n\t"
+		"ld\t%2,-32(%1)\n\t"
+		"ld\t%3,-24(%1)\n\t"
+		"sd\t%2,-32(%0)\n\t"
+		"sd\t%3,-24(%0)\n\t"
+		"ld\t%2,-16(%1)\n\t"
+		"ld\t%3,-8(%1)\n\t"
+		"sd\t%2,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		" sd\t%3,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
+		:"0" (to), "1" (from), "I" (PAGE_SIZE));
+}
+
+/* Cache operations.  These are only used with the virtual memory system,
+   not for non-coherent I/O so it's ok to ignore the secondary caches.  */
+static void
+andes_flush_cache_all(void)
+{
+	blast_dcache32(); blast_icache64();
+}
+
+static void
+andes_flush_cache_mm(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		andes_flush_cache_all();
+	}
+}
+
+static void
+andes_flush_cache_range(struct mm_struct *mm, unsigned long start,
+                        unsigned long end)
+{
+	if (mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		save_and_cli(flags);
+		blast_dcache32(); blast_icache64();
+		restore_flags(flags);
+	}
+}
+
+static void
+andes_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int text;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if(!(pte_val(*ptep) & _PAGE_PRESENT))
+		goto out;
+
+	text = (vma->vm_flags & VM_EXEC);
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if ((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+		blast_dcache32_page(page);
+		if(text)
+			blast_icache64_page(page);
+	} else {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (CKSEG0 + (page & (dcache_size - 1)));
+		blast_dcache32_page_indexed(page);
+		if(text)
+			blast_icache64_page_indexed(page);
+	}
+out:
+	restore_flags(flags);
+}
+
+/* Hoo hum...  will this ever be called for an address that is not in CKSEG0
+   and not cacheable?  */
+static void
+andes_flush_page_to_ram(struct page * page)
+{
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= K0BASE_NONCOH && addr < (0xb0UL << 56))
+	    || (addr >= KSEG0 && addr < KSEG1)
+	    || (addr >= KSEG2)) {
+#ifdef DEBUG_CACHE
+		printk("cram[%08lx]", addr);
+#endif
+		blast_dcache32_page(addr);
+	}
+}
+
+static void
+andes_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long daddr, iaddr;
+
+	daddr = addr & ~(dc_lsize - 1);
+	protected_writeback_dcache_line(daddr);
+	protected_writeback_dcache_line(daddr + dc_lsize);
+	iaddr = addr & ~(ic_lsize - 1);
+	protected_flush_icache_line(iaddr);
+	protected_flush_icache_line(iaddr + ic_lsize);
+}
+
+#define NTLB_ENTRIES       64
+#define NTLB_ENTRIES_HALF  32
+
+/* TLB operations.
+   XXX These should work fine on R10k without the BARRIERs.  */
+static inline void
+andes_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	unsigned long entry;
+
+#ifdef DEBUG_TLB
+	printk("[tlball]");
+#endif
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = get_entryhi() & 0xff;
+	set_entryhi(CKSEG0);
+	set_entrylo0(0);
+	set_entrylo1(0);
+	BARRIER;
+
+	entry = get_wired();
+
+	/* Blast 'em all away. */
+	while(entry < NTLB_ENTRIES) {
+		set_index(entry);
+		BARRIER;
+		tlb_write_indexed();
+		BARRIER;
+		entry++;
+	}
+	BARRIER;
+	set_entryhi(old_ctx);
+	__restore_flags(flags);
+}
+
+static void andes_flush_tlb_mm(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_TLB
+		printk("[tlbmm<%d>]", mm->context);
+#endif
+		save_and_cli(flags);
+		get_new_mmu_context(mm, asid_cache);
+		if(mm == current->mm)
+			set_entryhi(mm->context & 0xff);
+		restore_flags(flags);
+	}
+}
+
+static void
+andes_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+                      unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+		int size;
+
+#ifdef DEBUG_TLB
+		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
+		       start, end);
+#endif
+		save_and_cli(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if(size <= NTLB_ENTRIES_HALF) {
+			int oldpid = (get_entryhi() & 0xff);
+			int newpid = (mm->context & 0xff);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while(start < end) {
+				int idx;
+
+				set_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				BARRIER;
+				tlb_probe();
+				BARRIER;
+				idx = get_index();
+				set_entrylo0(0);
+				set_entrylo1(0);
+				set_entryhi(KSEG0);
+				BARRIER;
+				if(idx < 0)
+					continue;
+				tlb_write_indexed();
+				BARRIER;
+			}
+			set_entryhi(oldpid);
+		} else {
+			get_new_mmu_context(mm, asid_cache);
+			if(mm == current->mm)
+				set_entryhi(mm->context & 0xff);
+		}
+		__restore_flags(flags);
+	}
+}
+
+static void
+andes_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	if(vma->vm_mm->context != 0) {
+		unsigned long flags;
+		int oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
+#endif
+		newpid = (vma->vm_mm->context & 0xff);
+		page &= (PAGE_MASK << 1);
+		save_and_cli(flags);
+		oldpid = (get_entryhi() & 0xff);
+		set_entryhi(page | newpid);
+		BARRIER;
+		tlb_probe();
+		BARRIER;
+		idx = get_index();
+		set_entrylo0(0);
+		set_entrylo1(0);
+		set_entryhi(KSEG0);
+		if(idx < 0)
+			goto finish;
+		BARRIER;
+		tlb_write_indexed();
+
+	finish:
+		BARRIER;
+		set_entryhi(oldpid);
+		restore_flags(flags);
+	}
+}
+
+/* XXX Simplify this.  On the R10000 writing a TLB entry for an virtual
+   address that already exists will overwrite the old entry and not result
+   in TLB malfunction or TLB shutdown.  */
+static void andes_update_mmu_cache(struct vm_area_struct * vma,
+                                   unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	pid = get_entryhi() & 0xff;
+
+#ifdef DEBUG_TLB
+	if((pid != (vma->vm_mm->context & 0xff)) ||
+           (vma->vm_mm->context == 0)) {
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
+		       (int) (vma->vm_mm->context & 0xff), pid);
+	}
+#endif
+
+	__save_and_cli(flags);
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	BARRIER;
+	tlb_probe();
+	BARRIER;
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	BARRIER;
+	set_entrylo0(pte_val(*ptep++) >> 6);
+	set_entrylo1(pte_val(*ptep) >> 6);
+	set_entryhi(address | (pid));
+	BARRIER;
+	if(idx < 0) {
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	BARRIER;
+	set_entryhi(pid);
+	BARRIER;
+	__restore_flags(flags);
+}
+
+static int
+andes_user_mode(struct pt_regs *regs)
+{
+	return (regs->cp0_status & ST0_KSU) == KSU_USER;
+}
+
+static void andes_show_regs(struct pt_regs *regs)
+{
+	/* Saved main processor registers. */
+	printk("$0      : %016lx %016lx %016lx %016lx\n",
+	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
+	printk("$4      : %016lx %016lx %016lx %016lx\n",
+               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+	printk("$8      : %016lx %016lx %016lx %016lx\n",
+	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
+	printk("$12     : %016lx %016lx %016lx %016lx\n",
+               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+	printk("$16     : %016lx %016lx %016lx %016lx\n",
+	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
+	printk("$20     : %016lx %016lx %016lx %016lx\n",
+               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+	printk("$24     : %016lx %016lx\n",
+	       regs->regs[24], regs->regs[25]);
+	printk("$28     : %016lx %016lx %016lx %016lx\n",
+	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
+	printk("Hi      : %016lx\n", regs->hi);
+	printk("Lo      : %016lx\n", regs->lo);
+
+	/* Saved cp0 registers. */
+	printk("epc     : %016lx\nbadvaddr: %016lx\n",
+	       regs->cp0_epc, regs->cp0_badvaddr);
+	printk("Status  : %08x\nCause   : %08x\n",
+	       (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause);
+}
+
+void __init ld_mmu_andes(void)
+{
+	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
+
+	printk("Primary instruction cache %dkb, linesize %d bytes\n",
+	       icache_size >> 10, ic_lsize);
+	printk("Primary data cache %dkb, linesize %d bytes\n",
+	       dcache_size >> 10, dc_lsize);
+	printk("Secondary cache sized at %ldK, linesize %ld\n",
+	       scache_size() >> 10, sc_lsize());
+
+	_clear_page = andes_clear_page;
+	_copy_page = andes_copy_page;
+
+	_flush_cache_all = andes_flush_cache_all;
+	_flush_cache_mm = andes_flush_cache_mm;
+	_flush_cache_range = andes_flush_cache_range;
+	_flush_cache_page = andes_flush_cache_page;
+	_flush_cache_sigtramp = andes_flush_cache_sigtramp;
+	_flush_page_to_ram = andes_flush_page_to_ram;
+
+	_flush_tlb_all = andes_flush_tlb_all;
+	_flush_tlb_mm = andes_flush_tlb_mm;
+	_flush_tlb_range = andes_flush_tlb_range;
+	_flush_tlb_page = andes_flush_tlb_page;
+    
+	update_mmu_cache = andes_update_mmu_cache;
+
+	_show_regs = andes_show_regs;
+	_user_mode = andes_user_mode;
+
+        flush_cache_all();
+        write_32bit_cp0_register(CP0_WIRED, 0);
+
+	/*
+	 * You should never change this register:
+	 *   - On R4600 1.7 the tlbp never hits for pages smaller than
+	 *     the value in the c0_pagemask register.
+	 *   - The entire mm handling assumes the c0_pagemask register to
+	 *     be set for 4kb pages.
+	 */
+	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
+
+        /* From this point on the ARC firmware is dead.  */
+	flush_tlb_all();
+
+        /* Did I tell you that ARC SUCKS?  */
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/mm/extable.c linux/arch/mips64/mm/extable.c
--- v2.3.47/linux/arch/mips64/mm/extable.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mm/extable.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,60 @@
+/* $Id: extable.c,v 1.2 1999/12/04 03:59:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1999 by Silicon Graphics
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
+
+static inline unsigned long
+search_one_table(const struct exception_table_entry *first,
+                 const struct exception_table_entry *last,
+                 unsigned long value)
+{
+	while (first <= last) {
+		const struct exception_table_entry *mid;
+		long diff;
+
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+		if (diff == 0)
+			return mid->nextinsn;
+		else if (diff < 0)
+			first = mid+1;
+		else
+			last = mid-1;
+	}
+	return 0;
+}
+
+unsigned long
+search_exception_table(unsigned long addr)
+{
+	unsigned long ret;
+
+#ifndef CONFIG_MODULES
+	/* There is only the kernel to search.  */
+	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
+	if (ret) return ret;
+#else
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (mp->ex_table_start == NULL)
+			continue;
+		ret = search_one_table(mp->ex_table_start,
+				       mp->ex_table_end - 1, addr);
+		if (ret) return ret;
+	}
+#endif
+
+	return 0;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/mm/fault.c linux/arch/mips64/mm/fault.c
--- v2.3.47/linux/arch/mips64/mm/fault.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mm/fault.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,184 @@
+/* $Id: fault.c,v 1.6 2000/02/18 00:24:31 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 by Silicon Graphics
+ */
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/version.h>
+
+#include <asm/hardirq.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+#include <asm/softirq.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#define development_version (LINUX_VERSION_CODE & 0x100)
+
+extern void die(char *, struct pt_regs *, unsigned long write);
+
+unsigned long asid_cache;
+
+/*
+ * Macro for exception fixup code to access integer registers.
+ */
+#define dpf_reg(r) (regs->regs[r])
+
+/*
+ * This routine handles page faults.  It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+ * routines.
+ */
+asmlinkage void
+do_page_fault(struct pt_regs *regs, unsigned long write, unsigned long address)
+{
+	struct vm_area_struct * vma;
+	struct task_struct *tsk = current;
+	struct mm_struct *mm = tsk->mm;
+	int si_code = SEGV_MAPERR;
+	unsigned long fixup;
+
+	/*
+	 * If we're in an interrupt or have no user
+	 * context, we must not take the fault..
+	 */
+	if (in_interrupt() || mm == &init_mm)
+		goto no_context;
+#if 0
+	printk("[%s:%d:%08lx:%ld:%08lx]\n", current->comm, current->pid,
+	       address, write, regs->cp0_epc);
+#endif
+	down(&mm->mmap_sem);
+	vma = find_vma(mm, address);
+	if (!vma)
+		goto bad_area;
+	if (vma->vm_start <= address)
+		goto good_area;
+	if (!(vma->vm_flags & VM_GROWSDOWN))
+		goto bad_area;
+	if (expand_stack(vma, address))
+		goto bad_area;
+/*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+good_area:
+	si_code = SEGV_ACCERR;
+
+	if (write) {
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	} else {
+		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+			goto bad_area;
+	}
+
+	/*
+	 * If for any reason at all we couldn't handle the fault,
+	 * make sure we exit gracefully rather than endlessly redo
+	 * the fault.
+	 */
+	{
+		int fault = handle_mm_fault(tsk, vma, address, write);
+		if (fault < 0)
+			goto out_of_memory;
+		if (!fault)
+			goto do_sigbus;
+	}
+
+	up(&mm->mmap_sem);
+	return;
+
+/*
+ * Something tried to access memory that isn't in our memory map..
+ * Fix it, but check if it's kernel or user first..
+ */
+bad_area:
+	up(&mm->mmap_sem);
+
+	if (user_mode(regs)) {
+		struct siginfo si;
+		tsk->thread.cp0_badvaddr = address;
+		tsk->thread.error_code = write;
+#if 0
+		printk("do_page_fault() #2: sending SIGSEGV to %s for illegal %s\n"
+		       "%08lx (epc == %08lx, ra == %08lx)\n",
+		       tsk->comm,
+		       write ? "write access to" : "read access from",
+		       address,
+		       (unsigned long) regs->cp0_epc,
+		       (unsigned long) regs->regs[31]);
+#endif
+		si.si_signo = SIGSEGV;
+		si.si_code = si_code;
+		si.si_addr = (void *) address;
+		force_sig_info(SIGSEGV, &si, tsk);
+		return;
+	}
+
+no_context:
+	/* Are we prepared to handle this kernel fault?  */
+	fixup = search_exception_table(regs->cp0_epc);
+	if (fixup) {
+		long new_epc;
+
+		tsk->thread.cp0_baduaddr = address;
+		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
+		if (development_version)
+			printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n",
+			       tsk->comm, regs->cp0_epc, new_epc);
+		regs->cp0_epc = new_epc;
+		return;
+	}
+
+	/*
+	 * Oops. The kernel tried to access some bad page. We'll have to
+	 * terminate things with extreme prejudice.
+	 */
+	printk(KERN_ALERT "Unable to handle kernel paging request at virtual "
+	       "address %08lx, epc == %08lx, ra == %08lx\n",
+	       address, regs->cp0_epc, regs->regs[31]);
+while(1);
+	die("Oops", regs, write);
+	do_exit(SIGKILL);
+
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+out_of_memory:
+	up(&mm->mmap_sem);
+	printk("VM: killing process %s\n", tsk->comm);
+	if (user_mode(regs))
+		do_exit(SIGKILL);
+	goto no_context;
+
+do_sigbus:
+	up(&mm->mmap_sem);
+
+	/*
+	 * Send a sigbus, regardless of whether we were in kernel
+	 * or user mode.
+	 */
+	tsk->thread.cp0_badvaddr = address;
+	force_sig(SIGBUS, tsk);
+
+	/* Kernel mode? Handle exceptions or die */
+	if (!user_mode(regs))
+		goto no_context;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/mm/init.c linux/arch/mips64/mm/init.c
--- v2.3.47/linux/arch/mips64/mm/init.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mm/init.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,448 @@
+/* $Id: init.c,v 1.13 2000/02/23 00:41:00 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/pagemap.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/swap.h>
+#include <linux/swapctl.h>
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#endif
+
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#ifdef CONFIG_SGI_IP22
+#include <asm/sgialib.h>
+#endif
+#include <asm/mmu_context.h>
+
+unsigned long totalram_pages = 0;
+
+void __bad_pte_kernel(pmd_t *pmd)
+{
+	printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
+	pmd_set(pmd, BAD_PAGETABLE);
+}
+
+void __bad_pte(pmd_t *pmd)
+{
+	printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
+	pmd_set(pmd, BAD_PAGETABLE);
+}
+
+/* Fixme, we need something like BAD_PMDTABLE ...  */
+void __bad_pmd(pgd_t *pgd)
+{
+	printk("Bad pgd in pmd_alloc: %08lx\n", pgd_val(*pgd));
+	pgd_set(pgd, (pmd_t *) BAD_PAGETABLE);
+}
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p, *end;
+
+ 	p = (unsigned long *) page;
+	end = p + PTRS_PER_PGD;
+
+	while (p < end) {
+		p[0] = (unsigned long) invalid_pmd_table;
+		p[1] = (unsigned long) invalid_pmd_table;
+		p[2] = (unsigned long) invalid_pmd_table;
+		p[3] = (unsigned long) invalid_pmd_table;
+		p[4] = (unsigned long) invalid_pmd_table;
+		p[5] = (unsigned long) invalid_pmd_table;
+		p[6] = (unsigned long) invalid_pmd_table;
+		p[7] = (unsigned long) invalid_pmd_table;
+		p += 8;
+	}
+}
+
+pgd_t *get_pgd_slow(void)
+{
+	pgd_t *ret, *init;
+
+	ret = (pgd_t *) __get_free_pages(GFP_KERNEL, 1);
+	if (ret) {
+		init = pgd_offset(&init_mm, 0);
+		pgd_init((unsigned long)ret);
+	}
+	return ret;
+}
+
+void pmd_init(unsigned long addr)
+{
+	unsigned long *p, *end;
+
+ 	p = (unsigned long *) addr;
+	end = p + PTRS_PER_PMD;
+
+	while (p < end) {
+		p[0] = (unsigned long) invalid_pte_table;
+		p[1] = (unsigned long) invalid_pte_table;
+		p[2] = (unsigned long) invalid_pte_table;
+		p[3] = (unsigned long) invalid_pte_table;
+		p[4] = (unsigned long) invalid_pte_table;
+		p[5] = (unsigned long) invalid_pte_table;
+		p[6] = (unsigned long) invalid_pte_table;
+		p[7] = (unsigned long) invalid_pte_table;
+		p += 8;
+	}
+}
+
+pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset)
+{
+	pmd_t *pmd;
+
+	pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, 1);
+	if (pgd_none(*pgd)) {
+		if (pmd) {
+			pmd_init((unsigned long)pmd);
+			pgd_set(pgd, pmd);
+			return pmd + offset;
+		}
+		pgd_set(pgd, BAD_PMDTABLE);
+		return NULL;
+	}
+	free_page((unsigned long)pmd);
+	if (pgd_bad(*pgd)) {
+		__bad_pmd(pgd);
+		return NULL;
+	}
+	return (pmd_t *) pgd_page(*pgd) + offset;
+}
+
+pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
+{
+	pte_t *page;
+
+	page = (pte_t *) __get_free_pages(GFP_USER, 1);
+	if (pmd_none(*pmd)) {
+		if (page) {
+			clear_page(page);
+			pmd_set(pmd, page);
+			return page + offset;
+		}
+		pmd_set(pmd, BAD_PAGETABLE);
+		return NULL;
+	}
+	free_page((unsigned long)page);
+	if (pmd_bad(*pmd)) {
+		__bad_pte_kernel(pmd);
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + offset;
+}
+
+pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
+{
+	pte_t *page;
+
+	page = (pte_t *) __get_free_pages(GFP_KERNEL, 1);
+	if (pmd_none(*pmd)) {
+		if (page) {
+			clear_page(page);
+			pmd_val(*pmd) = (unsigned long)page;
+			return page + offset;
+		}
+		pmd_set(pmd, BAD_PAGETABLE);
+		return NULL;
+	}
+	free_pages((unsigned long)page, 1);
+	if (pmd_bad(*pmd)) {
+		__bad_pte(pmd);
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + offset;
+}
+
+int do_check_pgt_cache(int low, int high)
+{
+	int freed = 0;
+
+	if (pgtable_cache_size > high) {
+		do {
+			if (pgd_quicklist)
+				free_pgd_slow(get_pgd_fast()), freed++;
+			if (pmd_quicklist)
+				free_pmd_slow(get_pmd_fast()), freed++;
+			if (pte_quicklist)
+				free_pte_slow(get_pte_fast()), freed++;
+		} while (pgtable_cache_size > low);
+	}
+	return freed;
+}
+
+
+asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
+{
+	/* XXX Just get it working for now... */
+	flush_cache_all();
+	return 0;
+}
+
+/*
+ * We have upto 8 empty zeroed pages so we can map one of the right colour
+ * when needed.  This is necessary only on R4000 / R4400 SC and MC versions
+ * where we have to avoid VCED / VECI exceptions for good performance at
+ * any price.  Since page is never written to after the initialization we
+ * don't have to care about aliases on other CPUs.
+ */
+unsigned long empty_zero_page, zero_page_mask;
+
+unsigned long setup_zero_pages(void)
+{
+	unsigned long order, size, pg;
+
+	switch (mips_cputype) {
+	case CPU_R4000SC:
+	case CPU_R4000MC:
+	case CPU_R4400SC:
+	case CPU_R4400MC:
+		order = 3;
+		break;
+	default:
+		order = 0;
+	}
+
+	empty_zero_page = __get_free_pages(GFP_KERNEL, order);
+	if (!empty_zero_page)
+		panic("Oh boy, that early out of memory?");
+
+	pg = MAP_NR(empty_zero_page);
+	while (pg < MAP_NR(empty_zero_page) + (1 << order)) {
+		set_bit(PG_reserved, &mem_map[pg].flags);
+		set_page_count(mem_map + pg, 0);
+		pg++;
+	}
+
+	size = PAGE_SIZE << order;
+	zero_page_mask = (size - 1) & PAGE_MASK;
+	memset((void *)empty_zero_page, 0, size);
+
+	return 1UL << order;
+}
+
+extern inline void pte_init(unsigned long page)
+{
+	unsigned long *p, *end, bp;
+
+	bp = pte_val(BAD_PAGE);
+ 	p = (unsigned long *) page;
+	end = p + PTRS_PER_PTE;
+
+	while (p < end) {
+		p[0] = p[1] = p[2] = p[3] =
+		p[4] = p[5] = p[6] = p[7] = bp;
+		p += 8;
+	}
+}
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+pmd_t * __bad_pmd_table(void)
+{
+	extern pmd_t invalid_pmd_table[PTRS_PER_PMD];
+	unsigned long page;
+
+	page = (unsigned long) invalid_pmd_table;
+	pte_init(page);
+
+	return (pmd_t *) page;
+}
+
+pte_t * __bad_pagetable(void)
+{
+	extern char empty_bad_page_table[PAGE_SIZE];
+	unsigned long page;
+
+	page = (unsigned long) empty_bad_page_table;
+	pte_init(page);
+
+	return (pte_t *) page;
+}
+
+pte_t __bad_page(void)
+{
+	extern char empty_bad_page[PAGE_SIZE];
+	unsigned long page = (unsigned long) empty_bad_page;
+
+	clear_page((void *)page);
+	return pte_mkdirty(mk_pte_phys(__pa(page), PAGE_SHARED));
+}
+
+void show_mem(void)
+{
+	int i, free = 0, total = 0, reserved = 0;
+	int shared = 0, cached = 0;
+
+	printk("Mem-info:\n");
+	show_free_areas();
+	printk("Free swap:       %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+	i = max_mapnr;
+	while (i-- > 0) {
+		total++;
+		if (PageReserved(mem_map+i))
+			reserved++;
+		else if (PageSwapCache(mem_map+i))
+			cached++;
+		else if (!page_count(mem_map + i))
+			free++;
+		else
+			shared += page_count(mem_map + i) - 1;
+	}
+	printk("%d pages of RAM\n", total);
+	printk("%d reserved pages\n", reserved);
+	printk("%d pages shared\n", shared);
+	printk("%d pages swap cached\n",cached);
+	printk("%ld pages in page table cache\n", pgtable_cache_size);
+	printk("%d free pages\n", free);
+	show_buffers();
+}
+
+#ifndef CONFIG_DISCONTIGMEM
+/* References to section boundaries */
+
+extern char _ftext, _etext, _fdata, _edata;
+extern char __init_begin, __init_end;
+
+void __init paging_init(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+	unsigned long max_dma, low;
+
+	/* Initialize the entire pgd.  */
+	pgd_init((unsigned long)swapper_pg_dir);
+	pgd_init((unsigned long)swapper_pg_dir + PAGE_SIZE / 2);
+	pmd_init((unsigned long)invalid_pmd_table);
+
+	max_dma =  virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+	low = max_low_pfn;
+
+	if (low < max_dma)
+		zones_size[ZONE_DMA] = low;
+	else {
+		zones_size[ZONE_DMA] = max_dma;
+		zones_size[ZONE_NORMAL] = low - max_dma;
+	}
+
+	free_area_init(zones_size);
+}
+
+extern int page_is_ram(unsigned long pagenr);
+
+void __init mem_init(void)
+{
+	unsigned long codesize, reservedpages, datasize, initsize;
+	unsigned long tmp, ram;
+
+	max_mapnr = num_physpages = max_low_pfn;
+	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
+
+	totalram_pages += free_all_bootmem();
+	totalram_pages -= setup_zero_pages();	/* Setup zeroed pages.  */
+
+	reservedpages = ram = 0;
+	for (tmp = 0; tmp < max_low_pfn; tmp++)
+		if (page_is_ram(tmp)) {
+			ram++;
+			if (PageReserved(mem_map+tmp))
+				reservedpages++;
+		}
+
+	codesize =  (unsigned long) &_etext - (unsigned long) &_ftext;
+	datasize =  (unsigned long) &_edata - (unsigned long) &_fdata;
+	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
+	       "%ldk data, %ldk init)\n",
+	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+	       ram << (PAGE_SHIFT-10),
+	       codesize >> 10,
+	       reservedpages << (PAGE_SHIFT-10),
+	       datasize >> 10,
+	       initsize >> 10);
+}
+#endif /* !CONFIG_DISCONTIGMEM */
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(mem_map + MAP_NR(start));
+		set_page_count(mem_map+MAP_NR(start), 1);
+		free_page(start);
+		totalram_pages++;
+	}
+	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
+extern char __init_begin, __init_end;
+extern void prom_free_prom_memory(void);
+
+void
+free_initmem(void)
+{
+	unsigned long addr, page;
+
+	prom_free_prom_memory();
+    
+	addr = (unsigned long)(&__init_begin);
+	while (addr < (unsigned long)&__init_end) {
+		page = PAGE_OFFSET | CPHYSADDR(addr);
+		ClearPageReserved(mem_map + MAP_NR(page));
+		set_page_count(mem_map + MAP_NR(page), 1);
+		free_page(page);
+		totalram_pages++;
+		addr += PAGE_SIZE;
+	}
+	printk("Freeing unused kernel memory: %ldk freed\n",
+	       (&__init_end - &__init_begin) >> 10);
+}
+
+void
+si_meminfo(struct sysinfo *val)
+{
+	val->totalram = totalram_pages;
+	val->sharedram = 0;
+	val->freeram = nr_free_pages();
+	val->bufferram = atomic_read(&buffermem_pages);
+	val->totalhigh = 0;
+	val->freehigh = nr_free_highpages();
+	val->mem_unit = PAGE_SIZE;
+
+	return;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/mm/loadmmu.c linux/arch/mips64/mm/loadmmu.c
--- v2.3.47/linux/arch/mips64/mm/loadmmu.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mm/loadmmu.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,103 @@
+/* $Id: loadmmu.c,v 1.6 2000/02/24 00:12:41 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/sgialib.h>
+
+/* memory functions */
+void (*_clear_page)(void * page);
+void (*_copy_page)(void * to, void * from);
+
+/* Cache operations. */
+void (*_flush_cache_all)(void);
+void (*_flush_cache_mm)(struct mm_struct *mm);
+void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
+                           unsigned long end);
+void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
+void (*_flush_cache_sigtramp)(unsigned long addr);
+void (*_flush_page_to_ram)(struct page * page);
+
+/* DMA cache operations. */
+void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
+void (*_dma_cache_wback)(unsigned long start, unsigned long size);
+void (*_dma_cache_inv)(unsigned long start, unsigned long size);
+
+/* TLB operations. */
+void (*_flush_tlb_all)(void);
+void (*_flush_tlb_mm)(struct mm_struct *mm);
+void (*_flush_tlb_range)(struct mm_struct *mm, unsigned long start,
+			unsigned long end);
+void (*_flush_tlb_page)(struct vm_area_struct *vma, unsigned long page);
+
+/* Miscellaneous. */
+void (*update_mmu_cache)(struct vm_area_struct * vma,
+			 unsigned long address, pte_t pte);
+
+void (*_show_regs)(struct pt_regs *);
+
+int (*_user_mode)(struct pt_regs *);
+
+extern void ld_mmu_r4xx0(void);
+extern void ld_mmu_andes(void);
+
+void __init load_mmu(void)
+{
+	switch(mips_cputype) {
+#if defined (CONFIG_CPU_R4300)						\
+    || defined (CONFIG_CPU_R4X00)					\
+    || defined (CONFIG_CPU_R5000)					\
+    || defined (CONFIG_CPU_NEVADA)
+	case CPU_R4000PC:
+	case CPU_R4000SC:
+	case CPU_R4000MC:
+	case CPU_R4200:
+	case CPU_R4300:
+	case CPU_R4400PC:
+	case CPU_R4400SC:
+	case CPU_R4400MC:
+	case CPU_R4600:
+	case CPU_R4640:
+	case CPU_R4650:
+	case CPU_R4700:
+	case CPU_R5000:
+	case CPU_R5000A:
+	case CPU_NEVADA:
+		printk("Loading R4000 MMU routines.\n");
+		ld_mmu_r4xx0();
+		break;
+#endif
+
+#if defined (CONFIG_CPU_R10000)
+	case CPU_R10000:
+		printk("Loading R10000 MMU routines.\n");
+		ld_mmu_andes();
+		break;
+#endif
+
+	default:
+		/* XXX We need an generic routine in the MIPS port
+		 * XXX to jabber stuff onto the screen on all machines
+		 * XXX before the console is setup.  The ARCS prom
+		 * XXX routines look good for this, but only the SGI
+		 * XXX code has a full library for that at this time.
+		 */
+		panic("Yeee, unsupported mmu/cache architecture or "
+		      "wrong compiletime kernel configuration.");
+	}
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/mm/r4xx0.c linux/arch/mips64/mm/r4xx0.c
--- v2.3.47/linux/arch/mips64/mm/r4xx0.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mm/r4xx0.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,2542 @@
+/* $Id: r4xx0.c,v 1.8 2000/02/24 00:12:41 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bcache.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/sgialib.h>
+#include <asm/mmu_context.h>
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+/* Primary cache parameters. */
+static int icache_size, dcache_size; /* Size in bytes */
+static int ic_lsize, dc_lsize;       /* LineSize in bytes */
+
+/* Secondary cache (if present) parameters. */
+static unsigned int scache_size, sc_lsize;	/* Again, in bytes */
+
+#include <asm/r4kcacheops.h>
+#include <asm/r4kcache.h>
+
+#undef DEBUG_CACHE
+
+/*
+ * Dummy cache handling routines for machines without boardcaches
+ */
+static void no_sc_noop(void) {}
+
+static struct bcache_ops no_sc_ops = {
+	(void *)no_sc_noop, (void *)no_sc_noop,
+	(void *)no_sc_noop, (void *)no_sc_noop
+};
+
+struct bcache_ops *bcops = &no_sc_ops;
+
+/*
+ * On processors with QED R4600 style two set assosicative cache
+ * this is the bit which selects the way in the cache for the
+ * indexed cachops.
+ */
+#define icache_waybit (icache_size >> 1)
+#define dcache_waybit (dcache_size >> 1)
+
+/*
+ * Zero an entire page.  Basically a simple unrolled loop should do the
+ * job but we want more performance by saving memory bus bandwidth.  We
+ * have five flavours of the routine available for:
+ *
+ * - 16byte cachelines and no second level cache
+ * - 32byte cachelines second level cache
+ * - a version which handles the buggy R4600 v1.x
+ * - a version which handles the buggy R4600 v2.0
+ * - Finally a last version without fancy cache games for the SC and MC
+ *   versions of R4000 and R4400.
+ */
+
+static void r4k_clear_page_d16(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"cache\t%3,16(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"cache\t%3,-32(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"cache\t%3,-16(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
+		:"$1", "memory");
+}
+
+static void r4k_clear_page_d32(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"cache\t%3,-32(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
+		:"$1", "memory");
+}
+
+
+/*
+ * This flavour of r4k_clear_page is for the R4600 V1.x.  Cite from the
+ * IDT R4600 V1.7 errata:
+ *
+ *  18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D,
+ *      Hit_Invalidate_D and Create_Dirty_Excl_D should only be
+ *      executed if there is no other dcache activity. If the dcache is
+ *      accessed for another instruction immeidately preceding when these
+ *      cache instructions are executing, it is possible that the dcache 
+ *      tag match outputs used by these cache instructions will be 
+ *      incorrect. These cache instructions should be preceded by at least
+ *      four instructions that are not any kind of load or store 
+ *      instruction.
+ *
+ *      This is not allowed:    lw
+ *                              nop
+ *                              nop
+ *                              nop
+ *                              cache       Hit_Writeback_Invalidate_D
+ *
+ *      This is allowed:        lw
+ *                              nop
+ *                              nop
+ *                              nop
+ *                              nop
+ *                              cache       Hit_Writeback_Invalidate_D
+ */
+static void r4k_clear_page_r4600_v1(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tnop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"cache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"cache\t%3,-32(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_D)
+		:"$1", "memory");
+}
+
+/*
+ * And this one is for the R4600 V2.0
+ */
+static void r4k_clear_page_r4600_v2(void * page)
+{
+	unsigned int flags;
+
+	__save_and_cli(flags);
+	*(volatile unsigned int *)KSEG1;
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"cache\t%3,-32(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
+		:"$1", "memory");
+	__restore_flags(flags);
+}
+
+/*
+ * The next 4 versions are optimized for all possible scache configurations
+ * of the SC / MC versions of R4000 and R4400 ...
+ *
+ * Todo: For even better performance we should have a routine optimized for
+ * every legal combination of dcache / scache linesize.  When I (Ralf) tried
+ * this the kernel crashed shortly after mounting the root filesystem.  CPU
+ * bug?  Weirdo cache instruction semantics?
+ */
+static void r4k_clear_page_s16(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"cache\t%3,16(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"cache\t%3,-32(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"cache\t%3,-16(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
+		:"$1","memory");
+}
+
+static void r4k_clear_page_s32(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"cache\t%3,-32(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
+		:"$1","memory");
+}
+
+static void r4k_clear_page_s64(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD)
+		:"$1","memory");
+}
+
+static void r4k_clear_page_s128(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"sd\t$0,32(%0)\n\t"
+		"sd\t$0,40(%0)\n\t"
+		"sd\t$0,48(%0)\n\t"
+		"sd\t$0,56(%0)\n\t"
+		"daddiu\t%0,128\n\t"
+		"sd\t$0,-64(%0)\n\t"
+		"sd\t$0,-56(%0)\n\t"
+		"sd\t$0,-48(%0)\n\t"
+		"sd\t$0,-40(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (page)
+		:"0" (page),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD)
+		:"$1", "memory");
+}
+
+
+/*
+ * This is still inefficient.  We only can do better if we know the
+ * virtual address where the copy will be accessed.
+ */
+
+static void r4k_copy_page_d16(void * to, void * from)
+{
+	unsigned long dummy1, dummy2, reg1, reg2;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%6\n"
+		"1:\tcache\t%7,(%0)\n\t"
+		"ld\t%2,(%1)\n\t"
+		"ld\t%3,8(%1)\n\t"
+		"sd\t%2,(%0)\n\t"
+		"sd\t%3,8(%0)\n\t"
+		"cache\t%7,16(%0)\n\t"
+		"ld\t%2,16(%1)\n\t"
+		"ld\t%3,24(%1)\n\t"
+		"sd\t%2,16(%0)\n\t"
+		"sd\t%3,24(%0)\n\t"
+		"cache\t%7,32(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"daddiu\t%1,64\n\t"
+		"ld\t%2,-32(%1)\n\t"
+		"ld\t%3,-24(%1)\n\t"
+		"sd\t%2,-32(%0)\n\t"
+		"sd\t%3,-24(%0)\n\t"
+		"cache\t%7,-16(%0)\n\t"
+		"ld\t%2,-16(%1)\n\t"
+		"ld\t%3,-8(%1)\n\t"
+		"sd\t%2,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		" sd\t%4,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
+		:"0" (to), "1" (from), "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_D));
+}
+
+static void r4k_copy_page_d32(void * to, void * from)
+{
+	unsigned long dummy1, dummy2, reg1, reg2;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%6\n"
+		"1:\tcache\t%7,(%0)\n\t"
+		"ld\t%2,(%1)\n\t"
+		"ld\t%3,8(%1)\n\t"
+		"sd\t%2,(%0)\n\t"
+		"sd\t%3,8(%0)\n\t"
+		"ld\t%2,16(%1)\n\t"
+		"ld\t%3,24(%1)\n\t"
+		"sd\t%2,16(%0)\n\t"
+		"sd\t%3,24(%0)\n\t"
+		"cache\t%7,32(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"daddiu\t%1,64\n\t"
+		"ld\t%2,-32(%1)\n\t"
+		"ld\t%3,-24(%1)\n\t"
+		"sd\t%2,-32(%0)\n\t"
+		"sd\t%3,-24(%0)\n\t"
+		"ld\t%2,-16(%1)\n\t"
+		"ld\t%3,-8(%1)\n\t"
+		"sd\t%2,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		" sd\t%3,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
+		:"0" (to), "1" (from), "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_D));
+}
+
+/*
+ * Again a special version for the R4600 V1.x
+ */
+static void r4k_copy_page_r4600_v1(void * to, void * from)
+{
+	unsigned long dummy1, dummy2, reg1, reg2;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%6\n"
+		"1:\tnop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"\tcache\t%7,(%0)\n\t"
+		"ld\t%2,(%1)\n\t"
+		"ld\t%3,8(%1)\n\t"
+		"sd\t%2,(%0)\n\t"
+		"sd\t%3,8(%0)\n\t"
+		"ld\t%2,16(%1)\n\t"
+		"ld\t%3,24(%1)\n\t"
+		"sd\t%2,16(%0)\n\t"
+		"sd\t%3,24(%0)\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"cache\t%7,32(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"daddiu\t%1,64\n\t"
+		"ld\t%2,-32(%1)\n\t"
+		"ld\t%3,-24(%1)\n\t"
+		"sd\t%2,-32(%0)\n\t"
+		"sd\t%3,-24(%0)\n\t"
+		"ld\t%2,-16(%1)\n\t"
+		"ld\t%3,-8(%1)\n\t"
+		"sd\t%2,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		" sd\t%3,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
+		:"0" (to), "1" (from), "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_D));
+}
+
+static void r4k_copy_page_r4600_v2(void * to, void * from)
+{
+	unsigned long dummy1, dummy2, reg1, reg2;
+	unsigned int flags;
+
+	__save_and_cli(flags);
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%6\n"
+		"1:\tnop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"\tcache\t%7,(%0)\n\t"
+		"ld\t%2,(%1)\n\t"
+		"ld\t%3,8(%1)\n\t"
+		"sd\t%2,(%0)\n\t"
+		"sd\t%3,8(%0)\n\t"
+		"ld\t%2,16(%1)\n\t"
+		"ld\t%3,24(%1)\n\t"
+		"sd\t%2,16(%0)\n\t"
+		"sd\t%3,24(%0)\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"cache\t%7,32(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"daddiu\t%1,64\n\t"
+		"ld\t%2,-32(%1)\n\t"
+		"ld\t%3,-24(%1)\n\t"
+		"sd\t%2,-32(%0)\n\t"
+		"sd\t%3,-24(%0)\n\t"
+		"ld\t%2,-16(%1)\n\t"
+		"ld\t%3,-8(%1)\n\t"
+		"sd\t%2,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		" sd\t%3,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
+		:"0" (to), "1" (from), "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_D));
+	__restore_flags(flags);
+}
+
+/*
+ * These are for R4000SC / R4400MC
+ */
+static void r4k_copy_page_s16(void * to, void * from)
+{
+	unsigned long dummy1, dummy2, reg1, reg2;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%6\n"
+		"1:\tcache\t%7,(%0)\n\t"
+		"ld\t%2,(%1)\n\t"
+		"ld\t%3,8(%1)\n\t"
+		"sd\t%2,(%0)\n\t"
+		"sd\t%3,8(%0)\n\t"
+		"cache\t%7,16(%0)\n\t"
+		"ld\t%2,16(%1)\n\t"
+		"ld\t%3,24(%1)\n\t"
+		"sd\t%2,16(%0)\n\t"
+		"sd\t%3,24(%0)\n\t"
+		"cache\t%7,32(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"daddiu\t%1,64\n\t"
+		"ld\t%2,-32(%1)\n\t"
+		"ld\t%3,-24(%1)\n\t"
+		"sd\t%2,-32(%0)\n\t"
+		"sd\t%3,-24(%0)\n\t"
+		"cache\t%7,-16(%0)\n\t"
+		"ld\t%2,-16(%1)\n\t"
+		"ld\t%3,-8(%1)\n\t"
+		"sd\t%2,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		" sd\t%3,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
+		:"0" (to), "1" (from), "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD));
+}
+
+static void r4k_copy_page_s32(void * to, void * from)
+{
+	unsigned long dummy1, dummy2, reg1, reg2;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%6\n"
+		"1:\tcache\t%7,(%0)\n\t"
+		"ld\t%2,(%1)\n\t"
+		"ld\t%3,8(%1)\n\t"
+		"sd\t%2,(%0)\n\t"
+		"sd\t%3,8(%0)\n\t"
+		"ld\t%2,16(%1)\n\t"
+		"ld\t%3,24(%1)\n\t"
+		"sd\t%2,16(%0)\n\t"
+		"sd\t%3,24(%0)\n\t"
+		"cache\t%7,32(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"daddiu\t%1,64\n\t"
+		"ld\t%2,-32(%1)\n\t"
+		"ld\t%3,-24(%1)\n\t"
+		"sd\t%2,-32(%0)\n\t"
+		"sd\t%3,-24(%0)\n\t"
+		"ld\t%2,-16(%1)\n\t"
+		"ld\t%3,-8(%1)\n\t"
+		"sd\t%2,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		" sd\t%3,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
+		:"0" (to), "1" (from), "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD));
+}
+
+static void r4k_copy_page_s64(void * to, void * from)
+{
+	unsigned long dummy1, dummy2, reg1, reg2;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%6\n"
+		"1:\tcache\t%7,(%0)\n\t"
+		"ld\t%2,(%1)\n\t"
+		"ld\t%3,8(%1)\n\t"
+		"sd\t%2,(%0)\n\t"
+		"sd\t%3,8(%0)\n\t"
+		"ld\t%2,16(%1)\n\t"
+		"ld\t%3,24(%1)\n\t"
+		"sd\t%2,16(%0)\n\t"
+		"sd\t%3,24(%0)\n\t"
+		"daddiu\t%0,64\n\t"
+		"daddiu\t%1,64\n\t"
+		"ld\t%2,-32(%1)\n\t"
+		"ld\t%3,-24(%1)\n\t"
+		"sd\t%2,-32(%0)\n\t"
+		"sd\t%3,-24(%0)\n\t"
+		"ld\t%2,-16(%1)\n\t"
+		"ld\t%3,-8(%1)\n\t"
+		"sd\t%2,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		" sd\t%3,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
+		:"0" (to), "1" (from), "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD));
+}
+
+static void r4k_copy_page_s128(void * to, void * from)
+{
+	unsigned long dummy1, dummy2;
+	unsigned long reg1, reg2, reg3, reg4;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"daddiu\t$1,%0,%8\n"
+		"1:\tcache\t%9,(%0)\n\t"
+		"ld\t%2,(%1)\n\t"
+		"ld\t%3,8(%1)\n\t"
+		"ld\t%4,16(%1)\n\t"
+		"ld\t%5,24(%1)\n\t"
+		"sd\t%2,(%0)\n\t"
+		"sd\t%3,8(%0)\n\t"
+		"sd\t%4,16(%0)\n\t"
+		"sd\t%5,24(%0)\n\t"
+		"ld\t%2,32(%1)\n\t"
+		"ld\t%3,40(%1)\n\t"
+		"ld\t%4,48(%1)\n\t"
+		"ld\t%5,56(%1)\n\t"
+		"sd\t%2,32(%0)\n\t"
+		"sd\t%3,40(%0)\n\t"
+		"sd\t%4,48(%0)\n\t"
+		"sd\t%5,56(%0)\n\t"
+		"daddiu\t%0,128\n\t"
+		"daddiu\t%1,128\n\t"
+		"ld\t%2,-64(%1)\n\t"
+		"ld\t%3,-56(%1)\n\t"
+		"ld\t%4,-48(%1)\n\t"
+		"ld\t%5,-40(%1)\n\t"
+		"sd\t%2,-64(%0)\n\t"
+		"sd\t%3,-56(%0)\n\t"
+		"sd\t%4,-48(%0)\n\t"
+		"sd\t%5,-40(%0)\n\t"
+		"ld\t%2,-32(%1)\n\t"
+		"ld\t%3,-24(%1)\n\t"
+		"ld\t%4,-16(%1)\n\t"
+		"ld\t%5,-8(%1)\n\t"
+		"sd\t%2,-32(%0)\n\t"
+		"sd\t%3,-24(%0)\n\t"
+		"sd\t%4,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		" sd\t%5,-8(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2),
+		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
+		:"0" (to), "1" (from),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_SD));
+}
+
+
+/*
+ * If you think for one second that this stuff coming up is a lot
+ * of bulky code eating too many kernel cache lines.  Think _again_.
+ *
+ * Consider:
+ * 1) Taken branches have a 3 cycle penalty on R4k
+ * 2) The branch itself is a real dead cycle on even R4600/R5000.
+ * 3) Only one of the following variants of each type is even used by
+ *    the kernel based upon the cache parameters we detect at boot time.
+ *
+ * QED.
+ */
+
+static inline void r4k_flush_cache_all_s16d16i16(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache16(); blast_icache16(); blast_scache16();
+	__restore_flags(flags);
+}
+
+static inline void r4k_flush_cache_all_s32d16i16(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache16(); blast_icache16(); blast_scache32();
+	__restore_flags(flags);
+}
+
+static inline void r4k_flush_cache_all_s64d16i16(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache16(); blast_icache16(); blast_scache64();
+	__restore_flags(flags);
+}
+
+static inline void r4k_flush_cache_all_s128d16i16(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache16(); blast_icache16(); blast_scache128();
+	__restore_flags(flags);
+}
+
+static inline void r4k_flush_cache_all_s32d32i32(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache32(); blast_icache32(); blast_scache32();
+	__restore_flags(flags);
+}
+
+static inline void r4k_flush_cache_all_s64d32i32(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache32(); blast_icache32(); blast_scache64();
+	__restore_flags(flags);
+}
+
+static inline void r4k_flush_cache_all_s128d32i32(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache32(); blast_icache32(); blast_scache128();
+	__restore_flags(flags);
+}
+
+static inline void r4k_flush_cache_all_d16i16(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache16(); blast_icache16();
+	__restore_flags(flags);
+}
+
+static inline void r4k_flush_cache_all_d32i32(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache32(); blast_icache32();
+	__restore_flags(flags);
+}
+
+static void
+r4k_flush_cache_range_s16d16i16(struct mm_struct *mm, unsigned long start,
+                                unsigned long end)
+{
+	struct vm_area_struct *vma;
+	unsigned long flags;
+
+	if(mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if(vma) {
+		if(mm->context != current->mm->context) {
+			r4k_flush_cache_all_s16d16i16();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			__save_and_cli(flags);
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache16_page(start);
+				start += PAGE_SIZE;
+			}
+			restore_flags(flags);
+		}
+	}
+}
+
+static void
+r4k_flush_cache_range_s32d16i16(struct mm_struct *mm, unsigned long start,
+                                unsigned long end)
+{
+	struct vm_area_struct *vma;
+	unsigned long flags;
+
+	if(mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if(vma) {
+		if(mm->context != current->mm->context) {
+			r4k_flush_cache_all_s32d16i16();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			save_and_cli(flags);
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache32_page(start);
+				start += PAGE_SIZE;
+			}
+			restore_flags(flags);
+		}
+	}
+}
+
+static void
+r4k_flush_cache_range_s64d16i16(struct mm_struct *mm, unsigned long start,
+                                unsigned long end)
+{
+	struct vm_area_struct *vma;
+	unsigned long flags;
+
+	if(mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if(vma) {
+		if(mm->context != current->mm->context) {
+			r4k_flush_cache_all_s64d16i16();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			save_and_cli(flags);
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache64_page(start);
+				start += PAGE_SIZE;
+			}
+			restore_flags(flags);
+		}
+	}
+}
+
+static void
+r4k_flush_cache_range_s128d16i16(struct mm_struct *mm, unsigned long start,
+                                 unsigned long end)
+{
+	struct vm_area_struct *vma;
+	unsigned long flags;
+
+	if(mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if(vma) {
+		if(mm->context != current->mm->context) {
+			r4k_flush_cache_all_s128d16i16();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			save_and_cli(flags);
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache128_page(start);
+				start += PAGE_SIZE;
+			}
+			restore_flags(flags);
+		}
+	}
+}
+
+static void
+r4k_flush_cache_range_s32d32i32(struct mm_struct *mm, unsigned long start,
+                                unsigned long end)
+{
+	struct vm_area_struct *vma;
+	unsigned long flags;
+
+	if(mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if(vma) {
+		if(mm->context != current->mm->context) {
+			r4k_flush_cache_all_s32d32i32();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			save_and_cli(flags);
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache32_page(start);
+				start += PAGE_SIZE;
+			}
+			restore_flags(flags);
+		}
+	}
+}
+
+static void
+r4k_flush_cache_range_s64d32i32(struct mm_struct *mm, unsigned long start,
+                                unsigned long end)
+{
+	struct vm_area_struct *vma;
+	unsigned long flags;
+
+	if(mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if(vma) {
+		if(mm->context != current->mm->context) {
+			r4k_flush_cache_all_s64d32i32();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			save_and_cli(flags);
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache64_page(start);
+				start += PAGE_SIZE;
+			}
+			restore_flags(flags);
+		}
+	}
+}
+
+static void
+r4k_flush_cache_range_s128d32i32(struct mm_struct *mm, unsigned long start,
+                                 unsigned long end)
+{
+	struct vm_area_struct *vma;
+	unsigned long flags;
+
+	if(mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if(vma) {
+		if(mm->context != current->mm->context) {
+			r4k_flush_cache_all_s128d32i32();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			save_and_cli(flags);
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache128_page(start);
+				start += PAGE_SIZE;
+			}
+			restore_flags(flags);
+		}
+	}
+}
+
+static void
+r4k_flush_cache_range_d16i16(struct mm_struct *mm, unsigned long start,
+                             unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		save_and_cli(flags);
+		blast_dcache16(); blast_icache16();
+		restore_flags(flags);
+	}
+}
+
+static void
+r4k_flush_cache_range_d32i32(struct mm_struct *mm, unsigned long start,
+                             unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		save_and_cli(flags);
+		blast_dcache32(); blast_icache32();
+		restore_flags(flags);
+	}
+}
+
+/*
+ * On architectures like the Sparc, we could get rid of lines in
+ * the cache created only by a certain context, but on the MIPS
+ * (and actually certain Sparc's) we cannot.
+ */
+static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s16d16i16();
+	}
+}
+
+static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s32d16i16();
+	}
+}
+
+static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s64d16i16();
+	}
+}
+
+static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s128d16i16();
+	}
+}
+
+static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s32d32i32();
+	}
+}
+
+static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s64d32i32();
+	}
+}
+
+static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s128d32i32();
+	}
+}
+
+static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_d16i16();
+	}
+}
+
+static void r4k_flush_cache_mm_d32i32(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_d32i32();
+	}
+}
+
+static void
+r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma, unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int text;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if(mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if(!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	text = (vma->vm_flags & VM_EXEC);
+	/* Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if(mm->context != current->mm->context) {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache16_page_indexed(page);
+		if(text)
+			blast_icache16_page_indexed(page);
+		blast_scache16_page_indexed(page);
+	} else
+		blast_scache16_page(page);
+out:
+	restore_flags(flags);
+}
+
+static void
+r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma, unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int text;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if(mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/* If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if(!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	text = (vma->vm_flags & VM_EXEC);
+	/* Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if(mm->context != current->mm->context) {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache16_page_indexed(page);
+		if(text)
+			blast_icache16_page_indexed(page);
+		blast_scache32_page_indexed(page);
+	} else
+		blast_scache32_page(page);
+out:
+	restore_flags(flags);
+}
+
+static void
+r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma, unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int text;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if(mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/* If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if(!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	text = (vma->vm_flags & VM_EXEC);
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if(mm->context != current->mm->context) {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache16_page_indexed(page);
+		if(text)
+			blast_icache16_page_indexed(page);
+		blast_scache64_page_indexed(page);
+	} else
+		blast_scache64_page(page);
+out:
+	restore_flags(flags);
+}
+
+static void
+r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma, unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int text;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if(mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if(!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	text = (vma->vm_flags & VM_EXEC);
+	/* Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if(mm->context != current->mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache16_page_indexed(page);
+		if(text)
+			blast_icache16_page_indexed(page);
+		blast_scache128_page_indexed(page);
+	} else
+		blast_scache128_page(page);
+out:
+	restore_flags(flags);
+}
+
+static void
+r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma, unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int text;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if(mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if(!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	text = (vma->vm_flags & VM_EXEC);
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if(mm->context != current->mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache32_page_indexed(page);
+		if(text)
+			blast_icache32_page_indexed(page);
+		blast_scache32_page_indexed(page);
+	} else
+		blast_scache32_page(page);
+out:
+	restore_flags(flags);
+}
+
+static void
+r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma, unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int text;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if(mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if(!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	text = (vma->vm_flags & VM_EXEC);
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if(mm->context != current->mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache32_page_indexed(page);
+		if(text)
+			blast_icache32_page_indexed(page);
+		blast_scache64_page_indexed(page);
+	} else
+		blast_scache64_page(page);
+out:
+	restore_flags(flags);
+}
+
+static void
+r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma, unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int text;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if(mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/* If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if(!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	text = (vma->vm_flags & VM_EXEC);
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if(mm->context != current->mm->context) {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache32_page_indexed(page);
+		if(text)
+			blast_icache32_page_indexed(page);
+		blast_scache128_page_indexed(page);
+	} else
+		blast_scache128_page(page);
+out:
+	restore_flags(flags);
+}
+
+static void
+r4k_flush_cache_page_d16i16(struct vm_area_struct *vma, unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int text;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if(mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/* If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if(!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	text = (vma->vm_flags & VM_EXEC);
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if(mm == current->mm) {
+		blast_dcache16_page(page);
+		if(text)
+			blast_icache16_page(page);
+	} else {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache16_page_indexed(page);
+		if(text)
+			blast_icache16_page_indexed(page);
+	}
+out:
+	restore_flags(flags);
+}
+
+static void
+r4k_flush_cache_page_d32i32(struct vm_area_struct *vma, unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int text;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if(mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if(!(pte_val(*ptep) & _PAGE_PRESENT))
+		goto out;
+
+	text = (vma->vm_flags & VM_EXEC);
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+		blast_dcache32_page(page);
+		if(text)
+			blast_icache32_page(page);
+	} else {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache32_page_indexed(page);
+		if(text)
+			blast_icache32_page_indexed(page);
+	}
+out:
+	restore_flags(flags);
+}
+
+static void
+r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
+                                  unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int text;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if(mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if(!(pte_val(*ptep) & _PAGE_PRESENT))
+		goto out;
+
+	text = (vma->vm_flags & VM_EXEC);
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+		blast_dcache32_page(page);
+		if(text)
+			blast_icache32_page(page);
+	} else {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache32_page_indexed(page);
+		blast_dcache32_page_indexed(page ^ dcache_waybit);
+		if(text) {
+			blast_icache32_page_indexed(page);
+			blast_icache32_page_indexed(page ^ icache_waybit);
+		}
+	}
+out:
+	restore_flags(flags);
+}
+
+/* If the addresses passed to these routines are valid, they are either:
+ *
+ * 1) In KSEG0, so we can do a direct flush of the page.
+ * 2) In KSEG2, and since every process can translate those addresses all
+ *    the time in kernel mode we can do a direct flush.
+ * 3) In KSEG1, no flush necessary.
+ */
+static void r4k_flush_page_to_ram_s16d16i16(struct page * page)
+{
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
+#ifdef DEBUG_CACHE
+		printk("cram[%08lx]", addr);
+#endif
+		blast_scache16_page(addr);
+	}
+}
+
+static void r4k_flush_page_to_ram_s32d16i16(struct page * page)
+{
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
+#ifdef DEBUG_CACHE
+		printk("cram[%08lx]", addr);
+#endif
+		blast_scache32_page(addr);
+	}
+}
+
+static void r4k_flush_page_to_ram_s64d16i16(struct page * page)
+{
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
+#ifdef DEBUG_CACHE
+		printk("cram[%08lx]", addr);
+#endif
+		blast_scache64_page(addr);
+	}
+}
+
+static void r4k_flush_page_to_ram_s128d16i16(struct page * page)
+{
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
+#ifdef DEBUG_CACHE
+		printk("cram[%08lx]", addr);
+#endif
+		blast_scache128_page(addr);
+	}
+}
+
+static void r4k_flush_page_to_ram_s32d32i32(struct page * page)
+{
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
+#ifdef DEBUG_CACHE
+		printk("cram[%08lx]", addr);
+#endif
+		blast_scache32_page(addr);
+	}
+}
+
+static void r4k_flush_page_to_ram_s64d32i32(struct page * page)
+{
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
+#ifdef DEBUG_CACHE
+		printk("cram[%08lx]", addr);
+#endif
+		blast_scache64_page(addr);
+	}
+}
+
+static void r4k_flush_page_to_ram_s128d32i32(struct page * page)
+{
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
+#ifdef DEBUG_CACHE
+		printk("cram[%08lx]", addr);
+#endif
+		blast_scache128_page(addr);
+	}
+}
+
+static void r4k_flush_page_to_ram_d16i16(struct page * page)
+{
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
+		unsigned long flags;
+
+#ifdef DEBUG_CACHE
+		printk("cram[%08lx]", addr);
+#endif
+		__save_and_cli(flags);
+		blast_dcache16_page(addr);
+		__restore_flags(flags);
+	}
+}
+
+static void r4k_flush_page_to_ram_d32i32(struct page * page)
+{
+	unsigned long addr = page_address(page) & PAGE_MASK;
+
+	if ((addr >= KSEG0 && addr < KSEG1) || (addr >= KSEG2)) {
+		unsigned long flags;
+
+#ifdef DEBUG_CACHE
+		printk("cram[%08lx]", addr);
+#endif
+		__save_and_cli(flags);
+		blast_dcache32_page(addr);
+		__restore_flags(flags);
+	}
+}
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ *
+ * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D,
+ * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only
+ * operate correctly if the internal data cache refill buffer is empty.  These
+ * CACHE instructions should be separated from any potential data cache miss
+ * by a load instruction to an uncached address to empty the response buffer."
+ * (Revision 2.0 device errata from IDT available on http://www.idt.com/
+ * in .pdf format.)
+ */
+static void
+r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+		/* Workaround for R4600 bug.  See comment above. */
+		__save_and_cli(flags);
+		*(volatile unsigned long *)KSEG1;
+
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+	bc_wback_inv(addr, size);
+}
+
+static void
+r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		flush_cache_all();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+		/* Workaround for R4600 bug.  See comment above. */
+		__save_and_cli(flags);
+		*(volatile unsigned long *)KSEG1;
+
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+
+	bc_inv(addr, size);
+}
+
+static void
+r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		flush_cache_all();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_scache_line(a); /* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+r4k_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("r4k_dma_cache called - should not happen.\n");
+}
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case.  Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void r4k_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long daddr, iaddr;
+
+	daddr = addr & ~(dc_lsize - 1);
+	__asm__ __volatile__("nop;nop;nop;nop");	/* R4600 V1.7 */
+	protected_writeback_dcache_line(daddr);
+	protected_writeback_dcache_line(daddr + dc_lsize);
+	iaddr = addr & ~(ic_lsize - 1);
+	protected_flush_icache_line(iaddr);
+	protected_flush_icache_line(iaddr + ic_lsize);
+}
+
+static void r4600v20k_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long daddr, iaddr;
+	unsigned int flags;
+
+	daddr = addr & ~(dc_lsize - 1);
+	__save_and_cli(flags);
+
+	/* Clear internal cache refill buffer */
+	*(volatile unsigned int *)KSEG1;
+
+	protected_writeback_dcache_line(daddr);
+	protected_writeback_dcache_line(daddr + dc_lsize);
+	iaddr = addr & ~(ic_lsize - 1);
+	protected_flush_icache_line(iaddr);
+	protected_flush_icache_line(iaddr + ic_lsize);
+	__restore_flags(flags);
+}
+
+#undef DEBUG_TLB
+#undef DEBUG_TLBUPDATE
+
+#define NTLB_ENTRIES       48  /* Fixed on all R4XX0 variants... */
+
+#define NTLB_ENTRIES_HALF  24  /* Fixed on all R4XX0 variants... */
+
+static inline void r4k_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+#ifdef DEBUG_TLB
+	printk("[tlball]");
+#endif
+
+	save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = (get_entryhi() & 0xff);
+	set_entryhi(KSEG0);
+	set_entrylo0(0);
+	set_entrylo1(0);
+	BARRIER;
+
+	entry = get_wired();
+
+	/* Blast 'em all away. */
+	while(entry < NTLB_ENTRIES) {
+		set_index(entry);
+		BARRIER;
+		tlb_write_indexed();
+		BARRIER;
+		entry++;
+	}
+	BARRIER;
+	set_entryhi(old_ctx);
+	restore_flags(flags);
+}
+
+static void r4k_flush_tlb_mm(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_TLB
+		printk("[tlbmm<%d>]", mm->context);
+#endif
+		save_and_cli(flags);
+		get_new_mmu_context(mm, asid_cache);
+		if(mm == current->mm)
+			set_entryhi(mm->context & 0xff);
+		restore_flags(flags);
+	}
+}
+
+static void r4k_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+				unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+		int size;
+
+#ifdef DEBUG_TLB
+		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
+		       start, end);
+#endif
+		save_and_cli(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if(size <= NTLB_ENTRIES_HALF) {
+			int oldpid = (get_entryhi() & 0xff);
+			int newpid = (mm->context & 0xff);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while(start < end) {
+				int idx;
+
+				set_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				BARRIER;
+				tlb_probe();
+				BARRIER;
+				idx = get_index();
+				set_entrylo0(0);
+				set_entrylo1(0);
+				set_entryhi(KSEG0);
+				BARRIER;
+				if(idx < 0)
+					continue;
+				tlb_write_indexed();
+				BARRIER;
+			}
+			set_entryhi(oldpid);
+		} else {
+			get_new_mmu_context(mm, asid_cache);
+			if(mm == current->mm)
+				set_entryhi(mm->context & 0xff);
+		}
+		__restore_flags(flags);
+	}
+}
+
+static void r4k_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	if(vma->vm_mm->context != 0) {
+		unsigned long flags;
+		int oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
+#endif
+		newpid = (vma->vm_mm->context & 0xff);
+		page &= (PAGE_MASK << 1);
+		save_and_cli(flags);
+		oldpid = (get_entryhi() & 0xff);
+		set_entryhi(page | newpid);
+		BARRIER;
+		tlb_probe();
+		BARRIER;
+		idx = get_index();
+		set_entrylo0(0);
+		set_entrylo1(0);
+		set_entryhi(KSEG0);
+		if(idx < 0)
+			goto finish;
+		BARRIER;
+		tlb_write_indexed();
+
+	finish:
+		BARRIER;
+		set_entryhi(oldpid);
+		restore_flags(flags);
+	}
+}
+
+#ifdef DEBUG_TLBUPDATE
+static unsigned long ehi_debug[NTLB_ENTRIES];
+static unsigned long el0_debug[NTLB_ENTRIES];
+static unsigned long el1_debug[NTLB_ENTRIES];
+#endif
+
+/* We will need multiple versions of update_mmu_cache(), one that just
+ * updates the TLB with the new pte(s), and another which also checks
+ * for the R4k "end of page" hardware bug and does the needy.
+ */
+static void r4k_update_mmu_cache(struct vm_area_struct * vma,
+				 unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	pid = (get_entryhi() & 0xff);
+
+#ifdef DEBUG_TLB
+	if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
+		       (int) (vma->vm_mm->context & 0xff), pid);
+	}
+#endif
+
+	__save_and_cli(flags);
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	BARRIER;
+	tlb_probe();
+	BARRIER;
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	BARRIER;
+	set_entrylo0(pte_val(*ptep++) >> 6);
+	set_entrylo1(pte_val(*ptep) >> 6);
+	set_entryhi(address | (pid));
+	BARRIER;
+	if(idx < 0) {
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	BARRIER;
+	set_entryhi(pid);
+	BARRIER;
+	__restore_flags(flags);
+}
+
+#if 0
+static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma,
+				       unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx;
+
+	__save_and_cli(flags);
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address | (get_entryhi() & 0xff));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	tlb_probe();
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	set_entrylo0(pte_val(*ptep++) >> 6);
+	set_entrylo1(pte_val(*ptep) >> 6);
+	BARRIER;
+	if(idx < 0)
+		tlb_write_random();
+	else
+		tlb_write_indexed();
+	BARRIER;
+	__restore_flags(flags);
+}
+#endif
+
+static void r4k_show_regs(struct pt_regs *regs)
+{
+	/* Saved main processor registers. */
+	printk("$0      : %016lx %016lx %016lx %016lx\n",
+	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
+	printk("$4      : %016lx %016lx %016lx %016lx\n",
+               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+	printk("$8      : %016lx %016lx %016lx %016lx\n",
+	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
+	printk("$12     : %016lx %016lx %016lx %016lx\n",
+               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+	printk("$16     : %016lx %016lx %016lx %016lx\n",
+	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
+	printk("$20     : %016lx %016lx %016lx %016lx\n",
+               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+	printk("$24     : %016lx %016lx\n",
+	       regs->regs[24], regs->regs[25]);
+	printk("$28     : %016lx %016lx %016lx %016lx\n",
+	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
+	printk("Hi      : %016lx\n", regs->hi);
+	printk("Lo      : %016lx\n", regs->lo);
+
+	/* Saved cp0 registers. */
+	printk("epc     : %016lx\nbadvaddr: %016lx\n",
+	       regs->cp0_epc, regs->cp0_badvaddr);
+	printk("Status  : %08x\nCause   : %08x\n",
+	       (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause);
+//{static int x = 3; x--; if(!x) while(1);}
+}
+
+/* Detect and size the various r4k caches. */
+static void __init probe_icache(unsigned long config)
+{
+	icache_size = 1 << (12 + ((config >> 9) & 7));
+	ic_lsize = 16 << ((config >> 5) & 1);
+
+	printk("Primary instruction cache %dkb, linesize %d bytes)\n",
+	       icache_size >> 10, ic_lsize);
+}
+
+static void __init probe_dcache(unsigned long config)
+{
+	dcache_size = 1 << (12 + ((config >> 6) & 7));
+	dc_lsize = 16 << ((config >> 4) & 1);
+
+	printk("Primary data cache %dkb, linesize %d bytes)\n",
+	       dcache_size >> 10, dc_lsize);
+}
+
+
+/* If you even _breathe_ on this function, look at the gcc output
+ * and make sure it does not pop things on and off the stack for
+ * the cache sizing loop that executes in KSEG1 space or else
+ * you will crash and burn badly.  You have been warned.
+ */
+static int __init probe_scache(unsigned long config)
+{
+	extern unsigned long stext;
+	unsigned long flags, addr, begin, end, pow2;
+	int tmp;
+
+	tmp = ((config >> 17) & 1);
+	if(tmp)
+		return 0;
+	tmp = ((config >> 22) & 3);
+	switch(tmp) {
+	case 0:
+		sc_lsize = 16;
+		break;
+	case 1:
+		sc_lsize = 32;
+		break;
+	case 2:
+		sc_lsize = 64;
+		break;
+	case 3:
+		sc_lsize = 128;
+		break;
+	}
+
+	begin = (unsigned long) &stext;
+	begin &= ~((4 * 1024 * 1024) - 1);
+	end = begin + (4 * 1024 * 1024);
+
+	/* This is such a bitch, you'd think they would make it
+	 * easy to do this.  Away you daemons of stupidity!
+	 */
+	__save_and_cli(flags);
+
+	/* Fill each size-multiple cache line with a valid tag. */
+	pow2 = (64 * 1024);
+	for(addr = begin; addr < end; addr = (begin + pow2)) {
+		unsigned long *p = (unsigned long *) addr;
+		__asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
+		pow2 <<= 1;
+	}
+
+	/* Load first line with zero (therefore invalid) tag. */
+	set_taglo(0);
+	set_taghi(0);
+	__asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     "cache 8, (%0)\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     "cache 9, (%0)\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     "cache 11, (%0)\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+
+	/* Now search for the wrap around point. */
+	pow2 = (128 * 1024);
+	tmp = 0;
+	for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
+		__asm__ __volatile__("\n\t.set noreorder\n\t"
+				     "cache 7, (%0)\n\t"
+				     ".set reorder\n\t" : : "r" (addr));
+		__asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
+		if(!get_taglo())
+			break;
+		pow2 <<= 1;
+	}
+	__restore_flags(flags);
+	addr -= begin;
+	printk("Secondary cache sized at %dK linesize %d\n",
+	       (int) (addr >> 10), sc_lsize);
+	scache_size = addr;
+	return 1;
+}
+
+static void __init setup_noscache_funcs(void)
+{
+	unsigned int prid;
+
+	switch(dc_lsize) {
+	case 16:
+		_clear_page = r4k_clear_page_d16;
+		_copy_page = r4k_copy_page_d16;
+		_flush_cache_all = r4k_flush_cache_all_d16i16;
+		_flush_cache_mm = r4k_flush_cache_mm_d16i16;
+		_flush_cache_range = r4k_flush_cache_range_d16i16;
+		_flush_cache_page = r4k_flush_cache_page_d16i16;
+		_flush_page_to_ram = r4k_flush_page_to_ram_d16i16;
+		break;
+	case 32:
+		prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0;
+		if (prid == 0x2010) {			/* R4600 V1.7 */
+			_clear_page = r4k_clear_page_r4600_v1;
+			_copy_page = r4k_copy_page_r4600_v1;
+		} else if (prid == 0x2020) {		/* R4600 V2.0 */
+			_clear_page = r4k_clear_page_r4600_v2;
+			_copy_page = r4k_copy_page_r4600_v2;
+		} else {
+			_clear_page = r4k_clear_page_d32;
+			_copy_page = r4k_copy_page_d32;
+		}
+		_flush_cache_all = r4k_flush_cache_all_d32i32;
+		_flush_cache_mm = r4k_flush_cache_mm_d32i32;
+		_flush_cache_range = r4k_flush_cache_range_d32i32;
+		_flush_cache_page = r4k_flush_cache_page_d32i32;
+		_flush_page_to_ram = r4k_flush_page_to_ram_d32i32;
+		break;
+	}
+	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc;
+	_dma_cache_wback = r4k_dma_cache_wback;
+	_dma_cache_inv = r4k_dma_cache_inv_pc;
+}
+
+static void __init setup_scache_funcs(void)
+{
+	switch(sc_lsize) {
+	case 16:
+		switch(dc_lsize) {
+		case 16:
+			_flush_cache_all = r4k_flush_cache_all_s16d16i16;
+			_flush_cache_mm = r4k_flush_cache_mm_s16d16i16;
+			_flush_cache_range = r4k_flush_cache_range_s16d16i16;
+			_flush_cache_page = r4k_flush_cache_page_s16d16i16;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s16d16i16;
+			break;
+		case 32:
+			panic("Invalid cache configuration detected");
+		};
+		_clear_page = r4k_clear_page_s16;
+		_copy_page = r4k_copy_page_s16;
+		break;
+	case 32:
+		switch(dc_lsize) {
+		case 16:
+			_flush_cache_all = r4k_flush_cache_all_s32d16i16;
+			_flush_cache_mm = r4k_flush_cache_mm_s32d16i16;
+			_flush_cache_range = r4k_flush_cache_range_s32d16i16;
+			_flush_cache_page = r4k_flush_cache_page_s32d16i16;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s32d16i16;
+			break;
+		case 32:
+			_flush_cache_all = r4k_flush_cache_all_s32d32i32;
+			_flush_cache_mm = r4k_flush_cache_mm_s32d32i32;
+			_flush_cache_range = r4k_flush_cache_range_s32d32i32;
+			_flush_cache_page = r4k_flush_cache_page_s32d32i32;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s32d32i32;
+			break;
+		};
+		_clear_page = r4k_clear_page_s32;
+		_copy_page = r4k_copy_page_s32;
+		break;
+	case 64:
+		switch(dc_lsize) {
+		case 16:
+			_flush_cache_all = r4k_flush_cache_all_s64d16i16;
+			_flush_cache_mm = r4k_flush_cache_mm_s64d16i16;
+			_flush_cache_range = r4k_flush_cache_range_s64d16i16;
+			_flush_cache_page = r4k_flush_cache_page_s64d16i16;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s64d16i16;
+			break;
+		case 32:
+			_flush_cache_all = r4k_flush_cache_all_s64d32i32;
+			_flush_cache_mm = r4k_flush_cache_mm_s64d32i32;
+			_flush_cache_range = r4k_flush_cache_range_s64d32i32;
+			_flush_cache_page = r4k_flush_cache_page_s64d32i32;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s64d32i32;
+			break;
+		};
+		_clear_page = r4k_clear_page_s64;
+		_copy_page = r4k_copy_page_s64;
+		break;
+	case 128:
+		switch(dc_lsize) {
+		case 16:
+			_flush_cache_all = r4k_flush_cache_all_s128d16i16;
+			_flush_cache_mm = r4k_flush_cache_mm_s128d16i16;
+			_flush_cache_range = r4k_flush_cache_range_s128d16i16;
+			_flush_cache_page = r4k_flush_cache_page_s128d16i16;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s128d16i16;
+			break;
+		case 32:
+			_flush_cache_all = r4k_flush_cache_all_s128d32i32;
+			_flush_cache_mm = r4k_flush_cache_mm_s128d32i32;
+			_flush_cache_range = r4k_flush_cache_range_s128d32i32;
+			_flush_cache_page = r4k_flush_cache_page_s128d32i32;
+			_flush_page_to_ram = r4k_flush_page_to_ram_s128d32i32;
+			break;
+		};
+		_clear_page = r4k_clear_page_s128;
+		_copy_page = r4k_copy_page_s128;
+		break;
+	}
+	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
+	_dma_cache_wback = r4k_dma_cache_wback;
+	_dma_cache_inv = r4k_dma_cache_inv_sc;
+}
+
+typedef int (*probe_func_t)(unsigned long);
+
+static inline void __init setup_scache(unsigned int config)
+{
+	probe_func_t probe_scache_kseg1;
+	int sc_present = 0;
+
+	/* Maybe the cpu knows about a l2 cache? */
+	probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
+	sc_present = probe_scache_kseg1(config);
+
+	if (sc_present) {
+		setup_scache_funcs();
+		return;
+	}
+
+	setup_noscache_funcs();
+}
+
+static int r4k_user_mode(struct pt_regs *regs)
+{
+	return (regs->cp0_status & ST0_KSU) == KSU_USER;
+}
+
+void __init ld_mmu_r4xx0(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
+
+	set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+
+	probe_icache(config);
+	probe_dcache(config);
+	setup_scache(config);
+
+	switch(mips_cputype) {
+	case CPU_R4600:			/* QED style two way caches? */
+	case CPU_R4700:
+	case CPU_R5000:
+	case CPU_NEVADA:
+		_flush_cache_page = r4k_flush_cache_page_d32i32_r4600;
+	}
+
+	_flush_cache_sigtramp = r4k_flush_cache_sigtramp;
+	if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) {
+		_flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp;
+	}
+
+	_flush_tlb_all = r4k_flush_tlb_all;
+	_flush_tlb_mm = r4k_flush_tlb_mm;
+	_flush_tlb_range = r4k_flush_tlb_range;
+	_flush_tlb_page = r4k_flush_tlb_page;
+
+	update_mmu_cache = r4k_update_mmu_cache;
+
+	_show_regs = r4k_show_regs;
+	_user_mode = r4k_user_mode;
+
+	flush_cache_all();
+	write_32bit_cp0_register(CP0_WIRED, 0);
+
+	/*
+	 * You should never change this register:
+	 *   - On R4600 1.7 the tlbp never hits for pages smaller than
+	 *     the value in the c0_pagemask register.
+	 *   - The entire mm handling assumes the c0_pagemask register to
+	 *     be set for 4kb pages.
+	 */
+	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
+	flush_tlb_all();
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/mm/umap.c linux/arch/mips64/mm/umap.c
--- v2.3.47/linux/arch/mips64/mm/umap.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mm/umap.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,211 @@
+/* $Id: umap.c,v 1.5 2000/02/04 07:40:24 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 Linus Torvalds
+ * Copyright (C) 1997 Miguel de Icaza
+ */
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/shm.h>
+#include <linux/errno.h>
+#include <linux/mman.h>
+#include <linux/string.h>
+#include <linux/vmalloc.h>
+#include <linux/swap.h>
+
+#include <asm/system.h>
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+
+static inline void
+remove_mapping_pte_range (pmd_t *pmd, unsigned long address, unsigned long size)
+{
+	pte_t *pte;
+	unsigned long end;
+
+	if (pmd_none (*pmd))
+		return;
+	if (pmd_bad (*pmd)){
+		printk ("remove_graphics_pte_range: bad pmd (%08lx)\n", pmd_val (*pmd));
+		pmd_clear (pmd);
+		return;
+	}
+	pte = pte_offset (pmd, address);
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	do {
+		pte_t entry = *pte;
+		if (pte_present (entry))
+			set_pte (pte, pte_modify (entry, PAGE_NONE));
+		address += PAGE_SIZE;
+		pte++;
+	} while (address < end);
+						  
+}
+
+static inline void
+remove_mapping_pmd_range (pgd_t *pgd, unsigned long address, unsigned long size)
+{
+	pmd_t *pmd;
+	unsigned long end;
+
+	if (pgd_none (*pgd))
+		return;
+
+	if (pgd_bad (*pgd)){
+		printk ("remove_graphics_pmd_range: bad pgd (%08lx)\n", pgd_val (*pgd));
+		pgd_clear (pgd);
+		return;
+	}
+	pmd = pmd_offset (pgd, address);
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	do {
+		remove_mapping_pte_range (pmd, address, end - address);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address < end);
+		
+}
+
+/*
+ * This routine is called from the page fault handler to remove a
+ * range of active mappings at this point
+ */
+void
+remove_mapping (struct task_struct *task, unsigned long start, unsigned long end)
+{
+	unsigned long beg = start;
+	pgd_t *dir;
+
+	down (&task->mm->mmap_sem);
+	dir = pgd_offset (task->mm, start);
+	flush_cache_range (task->mm, beg, end);
+	while (start < end){
+		remove_mapping_pmd_range (dir, start, end - start);
+		start = (start + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	}
+	flush_tlb_range (task->mm, beg, end);
+	up (&task->mm->mmap_sem);
+}
+
+void *vmalloc_uncached (unsigned long size)
+{
+	return vmalloc_prot (size, PAGE_KERNEL_UNCACHED);
+}
+
+static inline void free_pte(pte_t page)
+{
+	if (pte_present(page)) {
+		unsigned long nr = pte_pagenr(page);
+		if (nr >= max_mapnr || PageReserved(mem_map+nr))
+			return;
+		__free_page(pte_page(page));
+		if (current->mm->rss <= 0)
+			return;
+		current->mm->rss--;
+		return;
+	}
+	swap_free(pte_to_swp_entry(page));
+}
+
+static inline void forget_pte(pte_t page)
+{
+	if (!pte_none(page)) {
+		printk("forget_pte: old mapping existed!\n");
+		free_pte(page);
+	}
+}
+
+/*
+ * maps a range of vmalloc()ed memory into the requested pages. the old
+ * mappings are removed. 
+ */
+static inline void
+vmap_pte_range (pte_t *pte, unsigned long address, unsigned long size, unsigned long vaddr)
+{
+	unsigned long end;
+	pgd_t *vdir;
+	pmd_t *vpmd;
+	pte_t *vpte;
+	
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	do {
+		pte_t oldpage = *pte;
+		struct page * page;
+		pte_clear(pte);
+
+		vdir = pgd_offset_k (vaddr);
+		vpmd = pmd_offset (vdir, vaddr);
+		vpte = pte_offset (vpmd, vaddr);
+		page = pte_page (*vpte);
+
+		set_pte(pte, mk_pte(page, PAGE_USERIO));
+		forget_pte(oldpage);
+		address += PAGE_SIZE;
+		vaddr += PAGE_SIZE;
+		pte++;
+	} while (address < end);
+}
+
+static inline int
+vmap_pmd_range (pmd_t *pmd, unsigned long address, unsigned long size, unsigned long vaddr)
+{
+	unsigned long end;
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	vaddr -= address;
+	do {
+		pte_t * pte = pte_alloc(pmd, address);
+		if (!pte)
+			return -ENOMEM;
+		vmap_pte_range(pte, address, end - address, address + vaddr);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address < end);
+	return 0;
+}
+
+int
+vmap_page_range (unsigned long from, unsigned long size, unsigned long vaddr)
+{
+	int error = 0;
+	pgd_t * dir;
+	unsigned long beg = from;
+	unsigned long end = from + size;
+
+	vaddr -= from;
+	dir = pgd_offset(current->mm, from);
+	flush_cache_range(current->mm, beg, end);
+	while (from < end) {
+		pmd_t *pmd = pmd_alloc(dir, from);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		error = vmap_pmd_range(pmd, from, end - from, vaddr + from);
+		if (error)
+			break;
+		from = (from + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	}
+	flush_tlb_range(current->mm, beg, end);
+	return error;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/Makefile linux/arch/mips64/sgi-ip22/Makefile
--- v2.3.47/linux/arch/mips64/sgi-ip22/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/Makefile	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,16 @@
+# $Id: Makefile,v 1.4 2000/01/21 22:34:03 ralf Exp $
+#
+# Makefile for the SGI specific kernel interface routines
+# under Linux.
+#
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+L_TARGET = ip22.a
+L_OBJS  = ip22-berr.o ip22-mc.o ip22-sc.o ip22-hpc.o ip22-int.o ip22-rtc.o \
+        ip22-setup.o system.o ip22-timer.o ip22-irq.o ip22-reset.o time.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/ip22-berr.c linux/arch/mips64/sgi-ip22/ip22-berr.c
--- v2.3.47/linux/arch/mips64/sgi-ip22/ip22-berr.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/ip22-berr.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,96 @@
+/* $Id: ip22-berr.c,v 1.2 2000/02/24 00:12:41 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/uaccess.h>
+#include <asm/paccess.h>
+#include <asm/addrspace.h>
+#include <asm/ptrace.h>
+
+extern asmlinkage void handle_ibe(void);
+extern asmlinkage void handle_dbe(void);
+
+extern const struct exception_table_entry __start___dbe_table[];
+extern const struct exception_table_entry __stop___dbe_table[];
+
+static inline unsigned long
+search_one_table(const struct exception_table_entry *first,
+                 const struct exception_table_entry *last,
+                 unsigned long value)
+{
+	while (first <= last) {
+		const struct exception_table_entry *mid;
+		long diff;
+
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+		if (diff == 0)
+			return mid->nextinsn;
+		else if (diff < 0)
+			first = mid+1;
+		else
+			last = mid-1;
+	}
+	return 0;
+}
+
+static inline unsigned long
+search_dbe_table(unsigned long addr)
+{
+	unsigned long ret;
+
+	/* There is only the kernel to search.  */
+	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
+	if (ret) return ret;
+
+	return 0;
+}
+
+void do_ibe(struct pt_regs *regs)
+{
+	printk("Got ibe at 0x%lx\n", regs->cp0_epc);
+	show_regs(regs);
+	dump_tlb_addr(regs->cp0_epc);
+	force_sig(SIGBUS, current);
+	while(1);
+}
+
+void do_dbe(struct pt_regs *regs)
+{
+	unsigned long fixup;
+
+	fixup = search_dbe_table(regs->cp0_epc);
+	if (fixup) {
+		long new_epc;
+
+		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
+		regs->cp0_epc = new_epc;
+		return;
+	}
+
+	printk("Got dbe at 0x%lx\n", regs->cp0_epc);
+	show_regs(regs);
+	dump_tlb_all();
+	while(1);
+	force_sig(SIGBUS, current);
+}
+
+void __init
+bus_error_init(void)
+{
+	int dummy;
+
+	set_except_vector(6, handle_ibe);
+	set_except_vector(7, handle_dbe);
+
+	/* At this time nothing uses the DBE protection mechanism on the
+	   Indy, so this here is needed to make the kernel link.  */
+	get_dbe(dummy, (int *)KSEG0);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/ip22-hpc.c linux/arch/mips64/sgi-ip22/ip22-hpc.c
--- v2.3.47/linux/arch/mips64/sgi-ip22/ip22-hpc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/ip22-hpc.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,103 @@
+/* $Id: ip22-hpc.c,v 1.2 1999/12/04 03:59:01 ralf Exp $
+ *
+ * ip22-hpc.c: Routines for generic manipulation of the HPC controllers.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
+#include <asm/sgialib.h>
+
+#undef DEBUG_SGIHPC
+
+struct hpc3_regs *hpc3c0, *hpc3c1;
+struct hpc3_miscregs *hpc3mregs;
+
+/* We need software copies of these because they are write only. */
+unsigned int sgi_hpc_write1, sgi_hpc_write2;
+
+/* Machine specific identifier knobs. */
+int sgi_has_ioc2 = 0;
+int sgi_guiness = 0;
+int sgi_boardid;
+
+void __init sgihpc_init(void)
+{
+	unsigned long sid, crev, brev;
+
+	hpc3c0 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP0_PBASE);
+	hpc3c1 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP1_PBASE);
+	hpc3mregs = (struct hpc3_miscregs *) (KSEG1 + HPC3_MREGS_PBASE);
+	sid = hpc3mregs->sysid;
+
+	sid &= 0xff;
+	crev = (sid & 0xe0) >> 5;
+	brev = (sid & 0x1e) >> 1;
+
+#ifdef DEBUG_SGIHPC
+	prom_printf("sgihpc_init: crev<%2x> brev<%2x>\n", crev, brev);
+	prom_printf("sgihpc_init: ");
+#endif
+
+	/* This test works now thanks to William J. Earl */
+	if ((sid & 1) == 0 ) {
+#ifdef DEBUG_SGIHPC
+		prom_printf("GUINESS ");
+#endif
+		sgi_guiness = 1;
+	} else {
+#ifdef DEBUG_SGIHPC
+		prom_printf("FULLHOUSE ");
+#endif
+		sgi_guiness = 0;
+	}
+	sgi_boardid = brev;
+
+#ifdef DEBUG_SGIHPC
+	prom_printf("sgi_boardid<%d> ", sgi_boardid);
+#endif
+
+	if(crev == 1) {
+		if((sid & 1) || (brev >= 2)) {
+#ifdef DEBUG_SGIHPC
+			prom_printf("IOC2 ");
+#endif
+			sgi_has_ioc2 = 1;
+		} else {
+#ifdef DEBUG_SGIHPC
+			prom_printf("IOC1 revision 1 ");
+#endif
+		}
+	} else {
+#ifdef DEBUG_SGIHPC
+		prom_printf("IOC1 revision 0 ");
+#endif
+	}
+#ifdef DEBUG_SGIHPC
+	prom_printf("\n");
+#endif
+
+	sgi_hpc_write1 = (HPC3_WRITE1_PRESET |
+		  HPC3_WRITE1_KMRESET |
+		  HPC3_WRITE1_ERESET |
+		  HPC3_WRITE1_LC0OFF);
+
+	sgi_hpc_write2 = (HPC3_WRITE2_EASEL |
+		  HPC3_WRITE2_NTHRESH |
+		  HPC3_WRITE2_TPSPEED |
+		  HPC3_WRITE2_EPSEL |
+		  HPC3_WRITE2_U0AMODE |
+		  HPC3_WRITE2_U1AMODE);
+
+	if(!sgi_guiness)
+		sgi_hpc_write1 |= HPC3_WRITE1_GRESET;
+	hpc3mregs->write1 = sgi_hpc_write1;
+	hpc3mregs->write2 = sgi_hpc_write2;
+
+	hpc3c0->pbus_piocfgs[0][6] |= HPC3_PIOPCFG_HW;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/ip22-int.c linux/arch/mips64/sgi-ip22/ip22-int.c
--- v2.3.47/linux/arch/mips64/sgi-ip22/ip22-int.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/ip22-int.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,605 @@
+/* $Id: ip22-int.c,v 1.4 2000/02/04 07:40:24 ralf Exp $
+ *
+ * indy_int.c: Routines for generic manipulation of the INT[23] ASIC
+ *             found on INDY workstations..
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/malloc.h>
+#include <linux/random.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/sgi/sgi.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
+#include <asm/sgialib.h>
+
+struct sgi_int2_regs *sgi_i2regs;
+struct sgi_int3_regs *sgi_i3regs;
+struct sgi_ioc_ints *ioc_icontrol;
+struct sgi_ioc_timers *ioc_timers;
+volatile unsigned char *ioc_tclear;
+
+static char lc0msk_to_irqnr[256];
+static char lc1msk_to_irqnr[256];
+static char lc2msk_to_irqnr[256];
+static char lc3msk_to_irqnr[256];
+
+extern asmlinkage void indyIRQ(void);
+int (*irq_cannonicalize)(int irq);
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void rs_kgdb_hook(int);
+#endif
+
+unsigned int local_bh_count[NR_CPUS];
+unsigned int local_irq_count[NR_CPUS];
+unsigned long spurious_count = 0;
+
+/* Local IRQ's are layed out logically like this:
+ *
+ * 0  --> 7   ==   local 0 interrupts
+ * 8  --> 15  ==   local 1 interrupts
+ * 16 --> 23  ==   vectored level 2 interrupts
+ * 24 --> 31  ==   vectored level 3 interrupts (not used)
+ */
+void disable_local_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	switch(irq_nr) {
+	case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+		ioc_icontrol->imask0 &= ~(1 << irq_nr);
+		break;
+
+	case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
+		ioc_icontrol->imask1 &= ~(1 << (irq_nr - 8));
+		break;
+
+	case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
+		ioc_icontrol->cmeimask0 &= ~(1 << (irq_nr - 16));
+		break;
+
+	default:
+		/* This way we'll see if anyone would ever want vectored
+		 * level 3 interrupts.  Highly unlikely.
+		 */
+		printk("Yeeee, got passed irq_nr %d at disable_irq\n", irq_nr);
+		panic("INVALID IRQ level!");
+	};
+	restore_flags(flags);
+}
+
+void enable_local_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+	save_and_cli(flags);
+	switch(irq_nr) {
+	case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+		ioc_icontrol->imask0 |= (1 << irq_nr);
+		break;
+
+	case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
+		ioc_icontrol->imask1 |= (1 << (irq_nr - 8));
+		break;
+
+	case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
+		enable_local_irq(7);
+		ioc_icontrol->cmeimask0 |= (1 << (irq_nr - 16));
+		break;
+
+	default:
+		printk("Yeeee, got passed irq_nr %d at disable_irq\n", irq_nr);
+		panic("INVALID IRQ level!");
+	};
+	restore_flags(flags);
+}
+
+void disable_gio_irq(unsigned int irq_nr)
+{
+	/* XXX TODO XXX */
+}
+
+void enable_gio_irq(unsigned int irq_nr)
+{
+	/* XXX TODO XXX */
+}
+
+void disable_hpcdma_irq(unsigned int irq_nr)
+{
+	/* XXX TODO XXX */
+}
+
+void enable_hpcdma_irq(unsigned int irq_nr)
+{
+	/* XXX TODO XXX */
+}
+
+void disable_irq(unsigned int irq_nr)
+{
+	unsigned int n = irq_nr;
+	if(n >= SGINT_END) {
+		printk("whee, invalid irq_nr %d\n", irq_nr);
+		panic("IRQ, you lose...");
+	}
+	if(n >= SGINT_LOCAL0 && n < SGINT_GIO) {
+		disable_local_irq(n - SGINT_LOCAL0);
+	} else if(n >= SGINT_GIO && n < SGINT_HPCDMA) {
+		disable_gio_irq(n - SGINT_GIO);
+	} else if(n >= SGINT_HPCDMA && n < SGINT_END) {
+		disable_hpcdma_irq(n - SGINT_HPCDMA);
+	} else {
+		panic("how did I get here?");
+	}
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+	unsigned int n = irq_nr;
+	if(n >= SGINT_END) {
+		printk("whee, invalid irq_nr %d\n", irq_nr);
+		panic("IRQ, you lose...");
+	}
+	if(n >= SGINT_LOCAL0 && n < SGINT_GIO) {
+		enable_local_irq(n - SGINT_LOCAL0);
+	} else if(n >= SGINT_GIO && n < SGINT_HPCDMA) {
+		enable_gio_irq(n - SGINT_GIO);
+	} else if(n >= SGINT_HPCDMA && n < SGINT_END) {
+		enable_hpcdma_irq(n - SGINT_HPCDMA);
+	} else {
+		panic("how did I get here?");
+	}
+}
+
+#if 0
+/*
+ * Currently unused.
+ */
+static void local_unex(int irq, void *data, struct pt_regs *regs)
+{
+	printk("Whee: unexpected local IRQ at %08lx\n",
+	       (unsigned long) regs->cp0_epc);
+	printk("DUMP: stat0<%x> stat1<%x> vmeistat<%x>\n",
+	       ioc_icontrol->istat0, ioc_icontrol->istat1,
+	       ioc_icontrol->vmeistat);
+}
+#endif
+
+static struct irqaction *local_irq_action[24] = {
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL
+};
+
+int setup_indy_irq(int irq, struct irqaction * new)
+{
+	printk("setup_indy_irq: Yeee, don't know how to setup irq<%d> for %s  %p\n",
+	       irq, new->name, new->handler);
+	return 0;
+}
+
+static struct irqaction r4ktimer_action = {
+	NULL, 0, 0, "R4000 timer/counter", NULL, NULL,
+};
+
+static struct irqaction indy_berr_action = {
+	NULL, 0, 0, "IP22 Bus Error", NULL, NULL,
+};
+
+static struct irqaction *irq_action[16] = {
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, &indy_berr_action, &r4ktimer_action,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL
+};
+
+int get_irq_list(char *buf)
+{
+	int i, len = 0;
+	int num = 0;
+	struct irqaction * action;
+
+	for (i = 0 ; i < 16 ; i++, num++) {
+		action = irq_action[i];
+		if (!action) 
+			continue;
+		len += sprintf(buf+len, "%2d: %8d %c %s",
+			num, kstat.irqs[0][num],
+			(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, " [on-chip]\n");
+	}
+	for (i = 0 ; i < 24 ; i++, num++) {
+		action = local_irq_action[i];
+		if (!action) 
+			continue;
+		len += sprintf(buf+len, "%2d: %8d %c %s",
+			num, kstat.irqs[0][num],
+			(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, " [local]\n");
+	}
+	return len;
+}
+
+/*
+ * do_IRQ handles IRQ's that have been installed without the
+ * SA_INTERRUPT flag: it uses the full signal-handling return
+ * and runs with other interrupts enabled. All relatively slow
+ * IRQ's should use this format: notably the keyboard/timer
+ * routines.
+ */
+asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
+{
+	struct irqaction *action;
+	int do_random, cpu;
+
+	cpu = smp_processor_id();
+	irq_enter(cpu);
+	kstat.irqs[0][irq]++;
+
+	printk("Got irq %d, press a key.", irq);
+	prom_getchar();
+	ArcEnterInteractiveMode();
+
+	/*
+	 * mask and ack quickly, we don't want the irq controller
+	 * thinking we're snobs just because some other CPU has
+	 * disabled global interrupts (we have already done the
+	 * INT_ACK cycles, it's too late to try to pretend to the
+	 * controller that we aren't taking the interrupt).
+	 *
+	 * Commented out because we've already done this in the
+	 * machinespecific part of the handler.  It's reasonable to
+	 * do this here in a highlevel language though because that way
+	 * we could get rid of a good part of duplicated code ...
+	 */
+        /* mask_and_ack_irq(irq); */
+
+	action = *(irq + irq_action);
+	if (action) {
+		if (!(action->flags & SA_INTERRUPT))
+			__sti();
+		action = *(irq + irq_action);
+		do_random = 0;
+		do {
+			do_random |= action->flags;
+			action->handler(irq, action->dev_id, regs);
+			action = action->next;
+		} while (action);
+		if (do_random & SA_SAMPLE_RANDOM)
+			add_interrupt_randomness(irq);
+		__cli();
+	}
+	irq_exit(cpu);
+
+	/* unmasking and bottom half handling is done magically for us. */
+}
+
+int request_local_irq(unsigned int lirq, void (*func)(int, void *, struct pt_regs *),
+		      unsigned long iflags, const char *dname, void *devid)
+{
+	struct irqaction *action;
+
+	lirq -= SGINT_LOCAL0;
+	if(lirq >= 24 || !func)
+		return -EINVAL;
+
+	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if(!action)
+		return -ENOMEM;
+
+	action->handler = func;
+	action->flags = iflags;
+	action->mask = 0;
+	action->name = dname;
+	action->dev_id = devid;
+	action->next = 0;
+	local_irq_action[lirq] = action;
+	enable_irq(lirq + SGINT_LOCAL0);
+	return 0;
+}
+
+void free_local_irq(unsigned int lirq, void *dev_id)
+{
+	struct irqaction *action;
+
+	lirq -= SGINT_LOCAL0;
+	if(lirq >= 24) {
+		printk("Aieee: trying to free bogus local irq %d\n",
+		       lirq + SGINT_LOCAL0);
+		return;
+	}
+	action = local_irq_action[lirq];
+	local_irq_action[lirq] = NULL;
+	disable_irq(lirq + SGINT_LOCAL0);
+	kfree(action);
+}
+
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction * action;
+
+	if (irq >= SGINT_END)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	if((irq >= SGINT_LOCAL0) && (irq < SGINT_GIO))
+		return request_local_irq(irq, handler, irqflags, devname, dev_id);
+
+	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_indy_irq(irq, action);
+
+	if (retval)
+		kfree(action);
+	return retval;
+}
+		
+void free_irq(unsigned int irq, void *dev_id)
+{
+	struct irqaction * action, **p;
+	unsigned long flags;
+
+	if (irq >= SGINT_END) {
+		printk("Trying to free IRQ%d\n",irq);
+		return;
+	}
+	if((irq >= SGINT_LOCAL0) && (irq < SGINT_GIO)) {
+		free_local_irq(irq, dev_id);
+		return;
+	}
+	for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
+		if (action->dev_id != dev_id)
+			continue;
+
+		/* Found it - now free it */
+		save_and_cli(flags);
+		*p = action->next;
+		restore_flags(flags);
+		kfree(action);
+		return;
+	}
+	printk("Trying to free free IRQ%d\n",irq);
+}
+
+void indy_local0_irqdispatch(struct pt_regs *regs)
+{
+	struct irqaction *action;
+	unsigned char mask = ioc_icontrol->istat0;
+	unsigned char mask2 = 0;
+	int irq, cpu = smp_processor_id();;
+
+	mask &= ioc_icontrol->imask0;
+	if(mask & ISTAT0_LIO2) {
+		mask2 = ioc_icontrol->vmeistat;
+		mask2 &= ioc_icontrol->cmeimask0;
+		irq = lc2msk_to_irqnr[mask2];
+		action = local_irq_action[irq];
+	} else {
+		irq = lc0msk_to_irqnr[mask];
+		action = local_irq_action[irq];
+	}
+
+	irq_enter(cpu);
+	kstat.irqs[0][irq + 16]++;
+	action->handler(irq, action->dev_id, regs);
+	irq_exit(cpu);
+}
+
+void indy_local1_irqdispatch(struct pt_regs *regs)
+{
+	struct irqaction *action;
+	unsigned char mask = ioc_icontrol->istat1;
+	unsigned char mask2 = 0;
+	int irq, cpu = smp_processor_id();;
+
+	mask &= ioc_icontrol->imask1;
+	if(mask & ISTAT1_LIO3) {
+		printk("WHee: Got an LIO3 irq, winging it...\n");
+		mask2 = ioc_icontrol->vmeistat;
+		mask2 &= ioc_icontrol->cmeimask1;
+		irq = lc3msk_to_irqnr[ioc_icontrol->vmeistat];
+		action = local_irq_action[irq];
+	} else {
+		irq = lc1msk_to_irqnr[mask];
+		action = local_irq_action[irq];
+	}
+	irq_enter(cpu);
+	kstat.irqs[0][irq + 24]++;
+	action->handler(irq, action->dev_id, regs);
+	irq_exit(cpu);
+}
+
+void indy_buserror_irq(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	int irq = 6;
+
+	irq_enter(cpu);
+	kstat.irqs[0][irq]++;
+	printk("Got a bus error IRQ, shouldn't happen yet\n");
+	show_regs(regs);
+	printk("Spinning...\n");
+	while(1);
+	irq_exit(cpu);
+}
+
+/* Misc. crap just to keep the kernel linking... */
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+static inline void sgint_init(void)
+{
+	int i;
+#ifdef CONFIG_REMOTE_DEBUG
+	char *ctype;
+#endif
+
+	sgi_i2regs = (struct sgi_int2_regs *) (KSEG1 + SGI_INT2_BASE);
+	sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE);
+
+	/* Init local mask --> irq tables. */
+	for(i = 0; i < 256; i++) {
+		if(i & 0x80) {
+			lc0msk_to_irqnr[i] = 7;
+			lc1msk_to_irqnr[i] = 15;
+			lc2msk_to_irqnr[i] = 23;
+			lc3msk_to_irqnr[i] = 31;
+		} else if(i & 0x40) {
+			lc0msk_to_irqnr[i] = 6;
+			lc1msk_to_irqnr[i] = 14;
+			lc2msk_to_irqnr[i] = 22;
+			lc3msk_to_irqnr[i] = 30;
+		} else if(i & 0x20) {
+			lc0msk_to_irqnr[i] = 5;
+			lc1msk_to_irqnr[i] = 13;
+			lc2msk_to_irqnr[i] = 21;
+			lc3msk_to_irqnr[i] = 29;
+		} else if(i & 0x10) {
+			lc0msk_to_irqnr[i] = 4;
+			lc1msk_to_irqnr[i] = 12;
+			lc2msk_to_irqnr[i] = 20;
+			lc3msk_to_irqnr[i] = 28;
+		} else if(i & 0x08) {
+			lc0msk_to_irqnr[i] = 3;
+			lc1msk_to_irqnr[i] = 11;
+			lc2msk_to_irqnr[i] = 19;
+			lc3msk_to_irqnr[i] = 27;
+		} else if(i & 0x04) {
+			lc0msk_to_irqnr[i] = 2;
+			lc1msk_to_irqnr[i] = 10;
+			lc2msk_to_irqnr[i] = 18;
+			lc3msk_to_irqnr[i] = 26;
+		} else if(i & 0x02) {
+			lc0msk_to_irqnr[i] = 1;
+			lc1msk_to_irqnr[i] = 9;
+			lc2msk_to_irqnr[i] = 17;
+			lc3msk_to_irqnr[i] = 25;
+		} else if(i & 0x01) {
+			lc0msk_to_irqnr[i] = 0;
+			lc1msk_to_irqnr[i] = 8;
+			lc2msk_to_irqnr[i] = 16;
+			lc3msk_to_irqnr[i] = 24;
+		} else {
+			lc0msk_to_irqnr[i] = 0;
+			lc1msk_to_irqnr[i] = 0;
+			lc2msk_to_irqnr[i] = 0;
+			lc3msk_to_irqnr[i] = 0;
+		}
+	}
+
+	/* Indy uses an INT3, Indigo2 uses an INT2 */
+	if (sgi_guiness) {
+		ioc_icontrol = &sgi_i3regs->ints;
+		ioc_timers = &sgi_i3regs->timers;
+		ioc_tclear = &sgi_i3regs->tclear;
+	} else {
+		ioc_icontrol = &sgi_i2regs->ints;
+		ioc_timers = &sgi_i2regs->timers;
+		ioc_tclear = &sgi_i2regs->tclear;
+	}
+
+	/* Mask out all interrupts. */
+	ioc_icontrol->imask0 = 0;
+	ioc_icontrol->imask1 = 0;
+	ioc_icontrol->cmeimask0 = 0;
+	ioc_icontrol->cmeimask1 = 0;
+
+	/* Now safe to set the exception vector. */
+	set_except_vector(0, indyIRQ);
+
+#ifdef CONFIG_REMOTE_DEBUG
+	ctype = prom_getcmdline();
+	for(i = 0; i < strlen(ctype); i++) {
+		if(ctype[i]=='k' && ctype[i+1]=='g' &&
+		   ctype[i+2]=='d' && ctype[i+3]=='b' &&
+		   ctype[i+4]=='=' && ctype[i+5]=='t' &&
+		   ctype[i+6]=='t' && ctype[i+7]=='y' &&
+		   ctype[i+8]=='d' &&
+		   (ctype[i+9] == '1' || ctype[i+9] == '2')) {
+			printk("KGDB: Using serial line /dev/ttyd%d for "
+			       "session\n", (ctype[i+9] - '0'));
+				if(ctype[i+9]=='1')
+					rs_kgdb_hook(1);
+				else if(ctype[i+9]=='2')
+					rs_kgdb_hook(0);
+				else {
+					printk("KGDB: whoops bogon tty line "
+					       "requested, disabling session\n");
+				}
+
+		}
+	}
+#endif
+}
+
+static int indy_irq_cannonicalize(int irq)
+{
+	return irq;	/* Sane hardware, sane code ... */
+}
+
+void __init init_IRQ(void)
+{
+	irq_cannonicalize = indy_irq_cannonicalize;
+	sgint_init();
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/ip22-irq.S linux/arch/mips64/sgi-ip22/ip22-irq.S
--- v2.3.47/linux/arch/mips64/sgi-ip22/ip22-irq.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/ip22-irq.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,129 @@
+/* $Id: ip22-irq.S,v 1.2 1999/12/04 03:59:01 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * indyIRQ.S: Interrupt exception dispatch code for FullHouse and
+ *            Guiness.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/* A lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop and moving across
+ *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
+ *    common case is one pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register IRQ mask, that
+ *    would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
+ *    between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the INDY look basically (barring software IRQs
+ * which we don't use at all) like:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        Local IRQ level zero
+ *             3        Local IRQ level one
+ *             4        8254 Timer zero
+ *             5        8254 Timer one
+ *             6        Bus Error
+ *             7        R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ----     R4k Timer
+ *                  Local IRQ zero
+ *                  Local IRQ one
+ *                  Bus Error
+ *                  8254 Timer zero
+ * Lowest  ----     8254 Timer one
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+	.text
+	.set	noreorder
+	.set	noat
+	.align	5
+	NESTED(indyIRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	mfc0	s0, CP0_CAUSE		# get irq mask
+
+	/* First we check for r4k counter/timer IRQ. */
+	andi	a0, s0, CAUSEF_IP7
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP2	# delay slot, check local level zero
+
+	/* Wheee, a timer interrupt. */
+	move	a0, sp
+	jal	indy_timer_interrupt
+	 nop				# delay slot
+
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP3	# delay slot, check local level one
+
+	/* Wheee, local level zero interrupt. */
+	jal	indy_local0_irqdispatch
+	 move	a0, sp			# delay slot
+
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP6	# delay slot, check bus error
+
+	/* Wheee, local level one interrupt. */
+	move	a0, sp
+	jal	indy_local1_irqdispatch
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+	beq	a0, zero, 1f
+	 nop
+
+	/* Wheee, an asynchronous bus error... */
+	move	a0, sp
+	jal	indy_buserror_irq
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+	/* Here by mistake?  This is possible, what can happen
+	 * is that by the time we take the exception the IRQ
+	 * pin goes low, so just leave if this is the case.
+	 */
+	andi	a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
+	beq	a0, zero, 1f
+
+	/* Must be one of the 8254 timers... */
+	move	a0, sp
+	jal	indy_8254timer_irq
+	 nop
+1:
+	j	ret_from_irq
+	 nop
+	END(indyIRQ)
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/ip22-mc.c linux/arch/mips64/sgi-ip22/ip22-mc.c
--- v2.3.47/linux/arch/mips64/sgi-ip22/ip22-mc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/ip22-mc.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,161 @@
+/* $Id: ip22-mc.c,v 1.2 1999/12/04 03:59:01 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * indy_mc.c: Routines for manipulating the INDY memory controller.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/addrspace.h>
+#include <asm/ptrace.h>
+#include <asm/sgi/sgimc.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgialib.h>
+
+/* #define DEBUG_SGIMC */
+
+struct sgimc_misc_ctrl *mcmisc_regs;
+u32 *rpsscounter;
+struct sgimc_dma_ctrl *dmactrlregs;
+
+static inline char *mconfig_string(unsigned long val)
+{
+	switch(val & SGIMC_MCONFIG_RMASK) {
+	case SGIMC_MCONFIG_FOURMB:
+		return "4MB";
+
+	case SGIMC_MCONFIG_EIGHTMB:
+		return "8MB";
+
+	case SGIMC_MCONFIG_SXTEENMB:
+		return "16MB";
+
+	case SGIMC_MCONFIG_TTWOMB:
+		return "32MB";
+
+	case SGIMC_MCONFIG_SFOURMB:
+		return "64MB";
+
+	case SGIMC_MCONFIG_OTEIGHTMB:
+		return "128MB";
+
+	default:
+		return "wheee, unknown";
+	};
+}
+
+void __init sgimc_init(void)
+{
+	unsigned long tmpreg;
+
+	mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000);
+	rpsscounter = (u32 *) (KSEG1 + 0x1fa01004);
+	dmactrlregs = (struct sgimc_dma_ctrl *) (KSEG1+0x1fa02000);
+
+	printk("MC: SGI memory controller Revision %d\n",
+	       (int) mcmisc_regs->systemid & SGIMC_SYSID_MASKREV);
+
+#if 0 /* XXX Until I figure out what this bit really indicates XXX */
+	/* XXX Is this systemid bit reliable? */
+	if(mcmisc_regs->systemid & SGIMC_SYSID_EPRESENT) {
+		EISA_bus = 1;
+		printk("with EISA\n");
+	} else {
+		EISA_bus = 0;
+		printk("no EISA\n");
+	}
+#endif
+
+#ifdef DEBUG_SGIMC
+	prom_printf("sgimc_init: memconfig0<%s> mconfig1<%s>\n",
+		    mconfig_string(mcmisc_regs->mconfig0),
+		    mconfig_string(mcmisc_regs->mconfig1));
+
+	prom_printf("mcdump: cpuctrl0<%08lx> cpuctrl1<%08lx>\n",
+		    mcmisc_regs->cpuctrl0, mcmisc_regs->cpuctrl1);
+	prom_printf("mcdump: divider<%08lx>, gioparm<%04x>\n",
+		    mcmisc_regs->divider, mcmisc_regs->gioparm);
+#endif
+
+	/* Place the MC into a known state.  This must be done before
+	 * interrupts are first enabled etc.
+	 */
+
+	/* Step 1: The CPU/GIO error status registers will not latch
+	 *         up a new error status until the register has been
+	 *         cleared by the cpu.  These status registers are
+	 *         cleared by writing any value to them.
+	 */
+	mcmisc_regs->cstat = mcmisc_regs->gstat = 0;
+
+	/* Step 2: Enable all parity checking in cpu control register
+	 *         zero.
+	 */
+	tmpreg = mcmisc_regs->cpuctrl0;
+	tmpreg |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
+		   SGIMC_CCTRL0_R4KNOCHKPARR);
+	mcmisc_regs->cpuctrl0 = tmpreg;
+
+	/* Step 3: Setup the MC write buffer depth, this is controlled
+	 *         in cpu control register 1 in the lower 4 bits.
+	 */
+	tmpreg = mcmisc_regs->cpuctrl1;
+	tmpreg &= ~0xf;
+	tmpreg |= 0xd;
+	mcmisc_regs->cpuctrl1 = tmpreg;
+
+	/* Step 4: Initialize the RPSS divider register to run as fast
+	 *         as it can correctly operate.  The register is laid
+	 *         out as follows:
+	 *
+	 *         ----------------------------------------
+	 *         |  RESERVED  |   INCREMENT   | DIVIDER |
+	 *         ----------------------------------------
+	 *          31        16 15            8 7       0
+	 *
+	 *         DIVIDER determines how often a 'tick' happens,
+	 *         INCREMENT determines by how the RPSS increment
+	 *         registers value increases at each 'tick'. Thus,
+	 *         for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101
+	 */
+	mcmisc_regs->divider = 0x101;
+
+	/* Step 5: Initialize GIO64 arbitrator configuration register.
+	 *
+	 * NOTE: If you dork with startup code the HPC init code in
+	 *       sgihpc_init() must run before us because of how we
+	 *       need to know Guiness vs. FullHouse and the board
+	 *       revision on this machine.  You have been warned.
+	 */
+
+	/* First the basic invariants across all gio64 implementations. */
+	tmpreg = SGIMC_GIOPARM_HPC64;    /* All 1st HPC's interface at 64bits. */
+	tmpreg |= SGIMC_GIOPARM_ONEBUS;  /* Only one physical GIO bus exists. */
+
+	if(sgi_guiness) {
+		/* Guiness specific settings. */
+		tmpreg |= SGIMC_GIOPARM_EISA64;     /* MC talks to EISA at 64bits */
+		tmpreg |= SGIMC_GIOPARM_MASTEREISA; /* EISA bus can act as master */
+	} else {
+		/* Fullhouse specific settings. */
+		if(sgi_boardid < 2) {
+			tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC at 64bits */
+			tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp0 pipelines */
+			tmpreg |= SGIMC_GIOPARM_MASTEREXP1;/* exp1 masters */
+			tmpreg |= SGIMC_GIOPARM_RTIMEEXP0; /* exp0 is realtime */
+		} else {
+			tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC 64bits */
+			tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp[01] pipelined */
+			tmpreg |= SGIMC_GIOPARM_PLINEEXP1;
+			tmpreg |= SGIMC_GIOPARM_MASTEREISA;/* EISA masters */
+			/* someone forgot this poor little guy... */
+			tmpreg |= SGIMC_GIOPARM_GFX64; 	/* GFX at 64 bits */
+		}
+	}
+	mcmisc_regs->gioparm = tmpreg; /* poof */
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/ip22-reset.c linux/arch/mips64/sgi-ip22/ip22-reset.c
--- v2.3.47/linux/arch/mips64/sgi-ip22/ip22-reset.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/ip22-reset.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,241 @@
+/* $Id: ip22-reset.c,v 1.3 1999/12/04 03:59:01 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Reset an IP22.
+ *
+ * Copyright (C) 1997, 1998, 1999 by Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
+
+/*
+ * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds.
+ * I'm not shure if this feature is a good idea, for now it's here just to
+ * make the power button make behave just like under IRIX.
+ */
+#define POWERDOWN_TIMEOUT	120
+
+/*
+ * Blink frequency during reboot grace period and when paniced.
+ */
+#define POWERDOWN_FREQ		(HZ / 4)
+#define PANIC_FREQ		(HZ / 8)
+
+static unsigned char sgi_volume;
+
+static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer;
+static int shuting_down, has_paniced;
+
+void machine_restart(char *command) __attribute__((noreturn));
+void machine_halt(void) __attribute__((noreturn));
+void machine_power_off(void) __attribute__((noreturn));
+
+/* XXX How to pass the reboot command to the firmware??? */
+void machine_restart(char *command)
+{
+	if (shuting_down)
+		machine_power_off();
+	ArcReboot();
+}
+
+void machine_halt(void)
+{
+	if (shuting_down)
+		machine_power_off();
+	ArcEnterInteractiveMode();
+}
+
+void machine_power_off(void)
+{
+	struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS;
+
+	cli();
+
+	clock->cmd |= 0x08;	/* Disable watchdog */
+	clock->whsec = 0;
+	clock->wsec = 0;
+
+	while(1) {
+		hpc3mregs->panel=0xfe;
+		/* Good bye cruel world ...  */
+
+		/* If we're still running, we probably got sent an alarm
+		   interrupt.  Read the flag to clear it.  */
+		clock->halarm;
+	}
+}
+
+static void power_timeout(unsigned long data)
+{
+	machine_power_off();
+}
+
+static void blink_timeout(unsigned long data)
+{
+	/* XXX Fix this for Fullhouse  */
+	sgi_hpc_write1 ^= (HPC3_WRITE1_LC0OFF|HPC3_WRITE1_LC1OFF);
+	hpc3mregs->write1 = sgi_hpc_write1;
+
+	del_timer(&blink_timer);
+	blink_timer.expires = jiffies + data;
+	add_timer(&blink_timer);
+}
+
+static void debounce(unsigned long data)
+{
+	del_timer(&debounce_timer);
+	if (ioc_icontrol->istat1 & 2) { /* Interrupt still being sent.  */
+		debounce_timer.expires = jiffies + 5; /* 0.05s  */
+		add_timer(&debounce_timer);
+
+		hpc3mregs->panel = 0xf3;
+
+		return;
+	}
+
+	if (has_paniced)
+		ArcReboot();
+
+	enable_irq(9);
+}
+
+static inline void power_button(void)
+{
+	if (has_paniced)
+		return;
+
+	if (shuting_down || kill_proc(1, SIGINT, 1)) {
+		/* No init process or button pressed twice.  */
+		machine_power_off();
+	}
+
+	shuting_down = 1;
+	blink_timer.data = POWERDOWN_FREQ;
+	blink_timeout(POWERDOWN_FREQ);
+
+	init_timer(&power_timer);
+	power_timer.function = power_timeout;
+	power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ;
+	add_timer(&power_timer);
+}
+
+void inline ip22_volume_set(unsigned char volume)
+{
+	sgi_volume = volume;
+
+	hpc3c0->pbus_extregs[2][0] = sgi_volume;
+	hpc3c0->pbus_extregs[2][1] = sgi_volume;
+}
+
+void inline ip22_volume_get(unsigned char *volume)
+{
+	*volume = sgi_volume;
+}
+
+static inline void volume_up_button(unsigned long data)
+{
+	del_timer(&volume_timer);
+
+	if (sgi_volume < 0xff)
+		sgi_volume++;
+
+	hpc3c0->pbus_extregs[2][0] = sgi_volume;
+	hpc3c0->pbus_extregs[2][1] = sgi_volume;
+
+	if (ioc_icontrol->istat1 & 2) {
+		volume_timer.expires = jiffies + 1;
+		add_timer(&volume_timer);
+	}
+
+}
+
+static inline void volume_down_button(unsigned long data)
+{
+	del_timer(&volume_timer);
+
+	if (sgi_volume > 0)
+		sgi_volume--;
+
+	hpc3c0->pbus_extregs[2][0] = sgi_volume;
+	hpc3c0->pbus_extregs[2][1] = sgi_volume;
+
+	if (ioc_icontrol->istat1 & 2) {
+		volume_timer.expires = jiffies + 1;
+		add_timer(&volume_timer);
+	}
+}
+
+static void panel_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int buttons;
+
+	buttons = hpc3mregs->panel;
+	hpc3mregs->panel = 3; /* power_interrupt | power_supply_on */
+
+	if (ioc_icontrol->istat1 & 2) { /* Wait until interrupt goes away */
+		disable_irq(9);
+		init_timer(&debounce_timer);
+		debounce_timer.function = debounce;
+		debounce_timer.expires = jiffies + 5;
+		add_timer(&debounce_timer);
+	}
+
+	if (!(buttons & 2))		/* Power button was pressed */
+		power_button();
+	if (!(buttons & 0x40)) {	/* Volume up button was pressed */
+		init_timer(&volume_timer);
+		volume_timer.function = volume_up_button;
+		volume_timer.expires = jiffies + 1;
+		add_timer(&volume_timer);
+	}
+	if (!(buttons & 0x10)) {	/* Volume down button was pressed */
+		init_timer(&volume_timer);
+		volume_timer.function = volume_down_button;
+		volume_timer.expires = jiffies + 1;
+		add_timer(&volume_timer);
+	}
+}
+
+static int panic_event(struct notifier_block *this, unsigned long event,
+                      void *ptr)
+{
+	if (has_paniced)
+		return NOTIFY_DONE;
+	has_paniced = 1;
+
+	blink_timer.data = PANIC_FREQ;
+	blink_timeout(PANIC_FREQ);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+	panic_event,
+	NULL,
+	0
+};
+
+void ip22_reboot_setup(void)
+{
+	static int setup_done;
+
+	if (setup_done)
+		return;
+	setup_done = 1;
+
+	request_irq(9, panel_int, 0, "Front Panel", NULL);
+	init_timer(&blink_timer);
+	blink_timer.function = blink_timeout;
+	notifier_chain_register(&panic_notifier_list, &panic_block);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/ip22-rtc.c linux/arch/mips64/sgi-ip22/ip22-rtc.c
--- v2.3.47/linux/arch/mips64/sgi-ip22/ip22-rtc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/ip22-rtc.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,37 @@
+/* $Id: ip22-rtc.c,v 1.2 1999/12/04 03:59:01 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * RTC routines for Indy style attached Dallas chip.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/mc146818rtc.h>
+#include <asm/sgi/sgihpc.h>
+
+static unsigned char indy_rtc_read_data(unsigned long addr)
+{
+	volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS;
+
+	return rtcregs[addr];
+}
+
+static void indy_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS;
+
+	rtcregs[addr] = data;
+}
+
+static int indy_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops indy_rtc_ops = {
+	&indy_rtc_read_data,
+	&indy_rtc_write_data,
+	&indy_rtc_bcd_mode
+};
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/ip22-sc.c linux/arch/mips64/sgi-ip22/ip22-sc.c
--- v2.3.47/linux/arch/mips64/sgi-ip22/ip22-sc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/ip22-sc.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,168 @@
+/* $Id: ip22-sc.c,v 1.2 1999/12/04 03:59:01 ralf Exp $
+ *
+ * indy_sc.c: Indy cache managment functions.
+ *
+ * Copyright (C) 1997 Ralf Baechle (ralf@gnu.org),
+ * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/autoconf.h>
+
+#include <asm/bcache.h>
+#include <asm/sgi/sgimc.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/sgialib.h>
+#include <asm/mmu_context.h>
+
+/* Secondary cache size in bytes, if present.  */
+static unsigned long scache_size;
+
+#undef DEBUG_CACHE
+
+#define SC_SIZE 0x00080000
+#define SC_LINE 32
+#define CI_MASK (SC_SIZE - SC_LINE)
+#define SC_ROUND(n) ((n) + SC_LINE - 1)
+#define SC_INDEX(n) ((n) & CI_MASK)
+
+static inline void indy_sc_wipe(unsigned long first, unsigned long last)
+{
+	__asm__ __volatile__("
+		.set	noreorder
+		or	%0, %4		# first line to flush
+		or	%1, %4		# last line to flush
+1:		sw	$0, 0(%0)
+		bne	%0, %1, 1b
+		daddu	%0, 32
+		.set reorder"
+		: "=r" (first), "=r" (last)
+		: "0" (first), "1" (last), "r" (0x9000000080000000)
+		: "$1");
+}
+
+static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size)
+{
+	unsigned long first_line, last_line;
+	unsigned int flags;
+
+#ifdef DEBUG_CACHE
+	printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size);
+#endif
+	/* Which lines to flush?  */
+	first_line = SC_INDEX(addr);
+	last_line = SC_INDEX(SC_ROUND(addr + size));
+
+	__save_and_cli(flags);
+	if (first_line <= last_line) {
+		indy_sc_wipe(first_line, last_line);
+		goto out;
+	}
+
+	/* Cache index wrap around.  Due to the way the buddy system works
+	   this case should not happen.  We're prepared to handle it,
+	   though. */
+	indy_sc_wipe(last_line, SC_SIZE);
+	indy_sc_wipe(0, first_line);
+out:
+	__restore_flags(flags);
+}
+
+static void inline indy_sc_enable(void)
+{
+#ifdef DEBUG_CACHE
+	printk("Enabling R4600 SCACHE\n");
+#endif
+	*(volatile unsigned char *) 0x9000000080000000 = 0;
+}
+
+static void indy_sc_disable(void)
+{
+#ifdef DEBUG_CACHE
+	printk("Disabling R4600 SCACHE\n");
+#endif
+	*(volatile unsigned short *) 0x9000000080000000 = 0;
+}
+
+static inline __init int indy_sc_probe(void)
+{
+	volatile u32 *cpu_control;
+	unsigned short cmd = 0xc220;
+	unsigned long data = 0;
+	int i, n;
+
+#ifdef __MIPSEB__
+	cpu_control = (volatile u32 *) KSEG1ADDR(0x1fa00034);
+#else
+	cpu_control = (volatile u32 *) KSEG1ADDR(0x1fa00030);
+#endif
+#define DEASSERT(bit) (*(cpu_control) &= (~(bit)))
+#define ASSERT(bit) (*(cpu_control) |= (bit))
+#define DELAY  for(n = 0; n < 100000; n++) __asm__ __volatile__("")
+	DEASSERT(SGIMC_EEPROM_PRE);
+	DEASSERT(SGIMC_EEPROM_SDATAO);
+	DEASSERT(SGIMC_EEPROM_SECLOCK);
+	DEASSERT(SGIMC_EEPROM_PRE);
+	DELAY;
+	ASSERT(SGIMC_EEPROM_CSEL); ASSERT(SGIMC_EEPROM_SECLOCK);
+	for(i = 0; i < 11; i++) {
+		if(cmd & (1<<15))
+			ASSERT(SGIMC_EEPROM_SDATAO);
+		else
+			DEASSERT(SGIMC_EEPROM_SDATAO);
+		DEASSERT(SGIMC_EEPROM_SECLOCK);
+		ASSERT(SGIMC_EEPROM_SECLOCK);
+		cmd <<= 1;
+	}
+	DEASSERT(SGIMC_EEPROM_SDATAO);
+	for(i = 0; i < (sizeof(unsigned short) * 8); i++) {
+		unsigned int tmp;
+
+		DEASSERT(SGIMC_EEPROM_SECLOCK);
+		DELAY;
+		ASSERT(SGIMC_EEPROM_SECLOCK);
+		DELAY;
+		data <<= 1;
+		tmp = *cpu_control;
+		if(tmp & SGIMC_EEPROM_SDATAI)
+			data |= 1;
+	}
+	DEASSERT(SGIMC_EEPROM_SECLOCK);
+	DEASSERT(SGIMC_EEPROM_CSEL);
+	ASSERT(SGIMC_EEPROM_PRE);
+	ASSERT(SGIMC_EEPROM_SECLOCK);
+
+	data <<= PAGE_SHIFT;
+	if (data == 0)
+		return 0;
+
+	scache_size = data;
+
+	printk("R4600/R5000 SCACHE size %ldK, linesize 32 bytes.\n",
+	       scache_size >> 10);
+
+	return 1;
+}
+
+/* XXX Check with wje if the Indy caches can differenciate between
+   writeback + invalidate and just invalidate.  */
+static struct bcache_ops indy_sc_ops = {
+	indy_sc_enable,
+	indy_sc_disable,
+	indy_sc_wback_invalidate,
+	indy_sc_wback_invalidate
+};
+
+void __init indy_sc_init(void)
+{
+return;  /* Not for now, debugging ... */
+	if (indy_sc_probe()) {
+		indy_sc_enable();
+		bcops = &indy_sc_ops;
+	}
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/ip22-setup.c linux/arch/mips64/sgi-ip22/ip22-setup.c
--- v2.3.47/linux/arch/mips64/sgi-ip22/ip22-setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/ip22-setup.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,188 @@
+/* $Id: ip22-setup.c,v 1.5 2000/01/27 01:05:24 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SGI IP22 specific setup.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silcon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/console.h>
+#include <linux/sched.h>
+#include <linux/mc146818rtc.h>
+#include <linux/pc_keyb.h>
+#include <linux/tty.h>
+
+#include <asm/addrspace.h>
+#include <asm/bcache.h>
+#include <asm/keyboard.h>
+#include <asm/irq.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/sgi.h>
+#include <asm/sgi/sgimc.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
+
+extern struct rtc_ops indy_rtc_ops;
+extern void ip22_reboot_setup(void);
+extern void ip22_volume_set(unsigned char);
+
+#define sgi_kh ((struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64))
+
+#define KBD_STAT_IBF		0x02	/* Keyboard input buffer full */
+
+static void ip22_request_region(void)
+{
+	/* No I/O ports are being used on the Indy.  */
+}
+
+static int ip22_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+	/* Dirty hack, this get's called as a callback from the keyboard
+	   driver.  We piggyback the initialization of the front panel
+	   button handling on it even though they're technically not
+	   related with the keyboard driver in any way.  Doing it from
+	   indy_setup wouldn't work since kmalloc isn't initialized yet.  */
+	ip22_reboot_setup();
+
+	return request_irq(SGI_KEYBOARD_IRQ, handler, 0, "keyboard", NULL);
+}
+
+static int ip22_aux_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+	/* Nothing to do, interrupt is shared with the keyboard hw  */
+	return 0;
+}
+
+static void ip22_aux_free_irq(void)
+{
+	/* Nothing to do, interrupt is shared with the keyboard hw  */
+}
+
+static unsigned char ip22_read_input(void)
+{
+	return sgi_kh->data;
+}
+
+static void ip22_write_output(unsigned char val)
+{
+	int status;
+
+	do {
+		status = sgi_kh->command;
+	} while (status & KBD_STAT_IBF);
+	sgi_kh->data = val;
+}
+
+static void ip22_write_command(unsigned char val)
+{
+	int status;
+
+	do {
+		status = sgi_kh->command;
+	} while (status & KBD_STAT_IBF);
+	sgi_kh->command = val;
+}
+
+static unsigned char ip22_read_status(void)
+{
+	return sgi_kh->command;
+}
+
+struct kbd_ops sgi_kbd_ops = {
+	ip22_request_region,
+	ip22_request_irq,
+
+	ip22_aux_request_irq,
+	ip22_aux_free_irq,
+
+	ip22_read_input,
+	ip22_write_output,
+	ip22_write_command,
+	ip22_read_status
+};
+
+int __init page_is_ram(unsigned long pagenr)
+{
+	if (pagenr < MAP_NR(PAGE_OFFSET + 0x2000UL))
+		return 1;
+	if (pagenr > MAP_NR(PAGE_OFFSET + 0x08002000))
+		return 1;
+	return 0;
+}
+
+void __init ip22_setup(void)
+{
+#ifdef CONFIG_SERIAL_CONSOLE
+	char *ctype;
+#endif
+
+	/* Init the INDY HPC I/O controller.  Need to call this before
+	 * fucking with the memory controller because it needs to know the
+	 * boardID and whether this is a Guiness or a FullHouse machine.
+	 */
+	sgihpc_init();
+
+	/* Init INDY memory controller. */
+	sgimc_init();
+
+	/* Now enable boardcaches, if any. */
+	indy_sc_init();
+
+#ifdef CONFIG_SERIAL_CONSOLE
+	/* ARCS console environment variable is set to "g?" for
+	 * graphics console, it is set to "d" for the first serial
+	 * line and "d2" for the second serial line.
+	 */
+	ctype = ArcArcGetEnvironmentVariable("console");
+	if(*ctype == 'd') {
+		if(*(ctype+1)=='2')
+			console_setup ("ttyS1");
+		else
+			console_setup ("ttyS0");
+	}
+#endif
+#ifdef CONFIG_SGI_PROM_CONSOLE
+	console_setup("ttyS0");
+#endif
+
+	ip22_volume_set(simple_strtoul(ArcGetEnvironmentVariable("volume"),
+	                              NULL, 10));
+
+#ifdef CONFIG_VT
+#ifdef CONFIG_SGI_NEWPORT_CONSOLE
+	conswitchp = &newport_con;
+
+	screen_info = (struct screen_info) {
+		0, 0,		/* orig-x, orig-y */
+		0,		/* unused */
+		0,		/* orig_video_page */
+		0,		/* orig_video_mode */
+		160,		/* orig_video_cols */
+		0, 0, 0,	/* unused, ega_bx, unused */
+		64,		/* orig_video_lines */
+		0,		/* orig_video_isVGA */
+		16		/* orig_video_points */
+	};
+#else
+	conswitchp = &dummy_con;
+#endif
+#endif
+	rtc_ops = &indy_rtc_ops;
+	kbd_ops = &sgi_kbd_ops;
+#ifdef CONFIG_PSMOUSE
+	aux_device_present = 0xaa;
+#endif
+#ifdef CONFIG_VIDEO_VINO
+	init_vino();
+#endif
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/ip22-timer.c linux/arch/mips64/sgi-ip22/ip22-timer.c
--- v2.3.47/linux/arch/mips64/sgi-ip22/ip22-timer.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/ip22-timer.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,295 @@
+/* $Id: ip22-timer.c,v 1.6 2000/02/04 07:40:24 ralf Exp $
+ *
+ * indy_timer.c: Setting up the clock on the INDY 8254 controller.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copytight (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/sgi/sgi.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
+#include <asm/sgialib.h>
+
+
+/* Because of a bug in the i8254 timer we need to use the onchip r4k
+ * counter as our system wide timer interrupt running at 100HZ.
+ */
+static unsigned long r4k_offset; /* Amount to increment compare reg each time */
+static unsigned long r4k_cur;    /* What counter should be at next timer irq */
+
+extern rwlock_t xtime_lock;
+
+static inline void ack_r4ktimer(unsigned long newval)
+{
+	write_32bit_cp0_register(CP0_COMPARE, newval);
+}
+
+static int set_rtc_mmss(unsigned long nowtime)
+{
+	struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS;
+	int retval = 0;
+	int real_seconds, real_minutes, clock_minutes;
+
+#define FROB_FROM_CLOCK(x) (((x) & 0xf) | ((((x) & 0xf0) >> 4) * 10));
+#define FROB_TO_CLOCK(x)  ((((((x) & 0xff) / 10)<<4) | (((x) & 0xff) % 10)) & 0xff)
+
+	clock->cmd &= ~(0x80);
+	clock_minutes = clock->min;
+	clock->cmd |= (0x80);
+
+	clock_minutes = FROB_FROM_CLOCK(clock_minutes);
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+
+	if(((abs(real_minutes - clock_minutes) + 15)/30) & 1)
+		real_minutes += 30; /* correct for half hour time zone */
+
+	real_minutes %= 60;
+	if(abs(real_minutes - clock_minutes) < 30) {
+		/* Force clock oscillator to be on. */
+		clock->month &= ~(0x80);
+
+		/* Write real_seconds and real_minutes into the Dallas. */
+		clock->cmd &= ~(0x80);
+		clock->sec = real_seconds;
+		clock->min = real_minutes;
+		clock->cmd |= (0x80);
+	} else
+		return -1;
+
+#undef FROB_FROM_CLOCK
+#undef FROB_TO_CLOCK
+
+	return retval;
+}
+
+static long last_rtc_update = 0;
+unsigned long missed_heart_beats = 0;
+
+void indy_timer_interrupt(struct pt_regs *regs)
+{
+	unsigned long count;
+	int irq = 7;
+
+	write_lock(&xtime_lock);
+	/* Ack timer and compute new compare. */
+	count = read_32bit_cp0_register(CP0_COUNT);
+	/* This has races.  */
+	if ((count - r4k_cur) >= r4k_offset) {
+		/* If this happens to often we'll need to compensate.  */
+		missed_heart_beats++;
+		r4k_cur = count + r4k_offset;
+	}
+        else
+            r4k_cur += r4k_offset;
+	ack_r4ktimer(r4k_cur);
+	kstat.irqs[0][irq]++;
+	do_timer(regs);
+
+	/* We update the Dallas time of day approx. every 11 minutes,
+	 * because of how the numbers work out we need to make
+	 * absolutely sure we do this update within 500ms before the
+	 * next second starts, thus the following code.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec >= 500000 - (tick >> 1) &&
+	    xtime.tv_usec <= 500000 + (tick >> 1)) {
+		if (set_rtc_mmss(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			/* do it again in 60s  */
+			last_rtc_update = xtime.tv_sec - 600;
+	}
+	write_unlock(&xtime_lock);
+}
+
+static unsigned long dosample(volatile unsigned char *tcwp,
+                              volatile unsigned char *tc2p)
+{
+	unsigned long ct0, ct1;
+	unsigned char msb, lsb;
+
+	/* Start the counter. */
+	*tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MRGEN);
+	*tc2p = (SGINT_TCSAMP_COUNTER & 0xff);
+	*tc2p = (SGINT_TCSAMP_COUNTER >> 8);
+
+	/* Get initial counter invariant */
+	ct0 = read_32bit_cp0_register(CP0_COUNT);
+
+	/* Latch and spin until top byte of counter2 is zero */
+	do {
+		*tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT);
+		lsb = *tc2p;
+		msb = *tc2p;
+		ct1 = read_32bit_cp0_register(CP0_COUNT);
+	} while(msb);
+
+	/* Stop the counter. */
+	*tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST);
+
+	/* Return the difference, this is how far the r4k counter increments
+	 * for every one HZ.
+	 */
+	return ct1 - ct0;
+}
+
+/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * WARNING: this function will overflow on 2106-02-07 06:28:16 on
+ * machines were long is 32-bit! (However, as time_t is signed, we
+ * will already get problems at other places on 2038-01-19 03:14:08)
+ */
+static inline unsigned long mktime(unsigned int year, unsigned int mon,
+	unsigned int day, unsigned int hour,
+	unsigned int min, unsigned int sec)
+{
+	if (0 >= (int) (mon -= 2)) {	/* 1..12 -> 11,12,1..10 */
+		mon += 12;	/* Puts Feb last since it has leap day */
+		year -= 1;
+	}
+	return (((
+	    (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
+	      year*365 - 719499
+	    )*24 + hour /* now have hours */
+	   )*60 + min /* now have minutes */
+	  )*60 + sec; /* finally seconds */
+}
+
+static unsigned long __init get_indy_time(void)
+{
+	struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS;
+	unsigned int year, mon, day, hour, min, sec;
+
+	/* Freeze it. */
+	clock->cmd &= ~(0x80);
+
+	/* Read regs. */
+	sec = clock->sec;
+	min = clock->min;
+	hour = (clock->hr & 0x3f);
+	day = (clock->date & 0x3f);
+	mon = (clock->month & 0x1f);
+	year = clock->year;
+
+	/* Unfreeze clock. */
+	clock->cmd |= 0x80;
+
+	/* Frob the bits. */
+#define FROB1(x)  (((x) & 0xf) + ((((x) & 0xf0) >> 4) * 10));
+#define FROB2(x)  (((x) & 0xf) + (((((x) & 0xf0) >> 4) & 0x3) * 10));
+
+	/* XXX Should really check that secs register is the same
+	 * XXX as when we first read it and if not go back and
+	 * XXX read the regs above again.
+	 */
+	sec = FROB1(sec); min = FROB1(min); day = FROB1(day);
+	mon = FROB1(mon); year = FROB1(year);
+	hour = FROB2(hour);
+
+#undef FROB1
+#undef FROB2
+
+	/* Wheee... */
+	if(year < 45)
+		year += 30;
+	if ((year += 1940) < 1970)
+		year += 100;
+
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+
+void __init indy_timer_init(void)
+{
+	struct sgi_ioc_timers *p;
+	volatile unsigned char *tcwp, *tc2p;
+
+	/* Figure out the r4k offset, the algorithm is very simple and works
+	 * in _all_ cases as long as the 8254 counter register itself works ok
+	 * (as an interrupt driving timer it does not because of bug, this is
+	 * why we are using the onchip r4k counter/compare register to serve
+	 * this purpose, but for r4k_offset calculation it will work ok for us).
+	 * There are other very complicated ways of performing this calculation
+	 * but this one works just fine so I am not going to futz around. ;-)
+	 */
+	p = ioc_timers;
+	tcwp = &p->tcword;
+	tc2p = &p->tcnt2;
+
+	printk("calculating r4koff... ");
+	dosample(tcwp, tc2p);			/* First sample. */
+	dosample(tcwp, tc2p);			/* Eat one.	*/
+	r4k_offset = dosample(tcwp, tc2p);	/* Second sample. */
+
+	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
+
+	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
+	write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
+	set_cp0_status(ST0_IM, ALLINTS);
+	sti();
+
+	write_lock_irq(&xtime_lock);
+	xtime.tv_sec = get_indy_time();		/* Read time from RTC. */
+	xtime.tv_usec = 0;
+	write_unlock_irq(&xtime_lock);
+}
+
+void indy_8254timer_irq(void)
+{
+	int cpu = smp_processor_id();
+	int irq = 4;
+
+	irq_enter(cpu);
+	kstat.irqs[0][irq]++;
+	printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
+	prom_getchar();
+	ArcEnterInteractiveMode();
+	irq_exit(cpu);
+}
+
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+
+	read_lock_irqsave(&xtime_lock, flags);
+	*tv = xtime;
+	read_unlock_irqrestore(&xtime_lock, flags);
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq(&xtime_lock);
+	xtime = *tv;
+	time_state = TIME_BAD;
+	time_maxerror = MAXPHASE;
+	time_esterror = MAXPHASE;
+	write_unlock_irq(&xtime_lock);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/system.c linux/arch/mips64/sgi-ip22/system.c
--- v2.3.47/linux/arch/mips64/sgi-ip22/system.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/system.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,135 @@
+/* $Id: system.c,v 1.3 1999/12/04 03:59:01 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * system.c: Probe the system type using ARCS prom interface library.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/sgi/sgi.h>
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+
+enum sgi_mach sgimach;
+
+struct smatch {
+	char *name;
+	int type;
+};
+
+static struct smatch sgi_cputable[] = {
+	{ "MIPS-R2000", CPU_R2000 },
+	{ "MIPS-R3000", CPU_R3000 },
+	{ "MIPS-R3000A", CPU_R3000A },
+	{ "MIPS-R4000", CPU_R4000SC },
+	{ "MIPS-R4400", CPU_R4400SC },
+	{ "MIPS-R4600", CPU_R4600 },
+	{ "MIPS-R8000", CPU_R8000 },
+	{ "MIPS-R5000", CPU_R5000 },
+	{ "MIPS-R5000A", CPU_R5000A }
+};
+
+#define NUM_CPUS 9 /* for now */
+
+static int __init string_to_cpu(char *s)
+{
+	int i;
+
+	for(i = 0; i < NUM_CPUS; i++) {
+		if(!strcmp(s, sgi_cputable[i].name))
+			return sgi_cputable[i].type;
+	}
+	prom_printf("\nYeee, could not determine MIPS cpu type <%s>\n", s);
+	prom_printf("press a key to reboot\n");
+	prom_getchar();
+	ArcEnterInteractiveMode();
+	return 0;
+}
+
+/*
+ * We' call this early before loadmmu().  If we do the other way around
+ * the firmware will crash and burn.
+ */
+void __init sgi_sysinit(void)
+{
+	pcomponent *p, *toplev, *cpup = 0;
+	int cputype = -1;
+
+
+	/* The root component tells us what machine architecture we
+	 * have here.
+	 */
+	p = ArcGetChild(PROM_NULL_COMPONENT);
+
+	/* Now scan for cpu(s). */
+	toplev = p = ArcGetChild(p);
+	while(p) {
+		int ncpus = 0;
+
+		if(p->type == Cpu) {
+			if(++ncpus > 1) {
+				prom_printf("\nYeee, SGI MP not ready yet\n");
+				prom_printf("press a key to reboot\n");
+				prom_getchar();
+				ArcEnterInteractiveMode();
+			}
+			printk("CPU: %s ", p->iname);
+			cpup = p;
+			cputype = string_to_cpu(cpup->iname);
+		}
+		p = ArcGetPeer(p);
+	}
+	if(cputype == -1) {
+		prom_printf("\nYeee, could not find cpu ARCS component\n");
+		prom_printf("press a key to reboot\n");
+		prom_getchar();
+		ArcEnterInteractiveMode();
+	}
+	p = ArcGetChild(cpup);
+	while(p) {
+		switch(p->class) {
+		case processor:
+			switch(p->type) {
+			case Fpu:
+				printk("FPU<%s> ", p->iname);
+				break;
+
+			default:
+				break;
+			};
+			break;
+
+		case cache:
+			switch(p->type) {
+			case picache:
+				printk("ICACHE ");
+				break;
+
+			case pdcache:
+				printk("DCACHE ");
+				break;
+
+			case sccache:
+				printk("SCACHE ");
+				break;
+
+			default:
+				break;
+
+			};
+			break;
+
+		default:
+			break;
+		};
+		p = ArcGetPeer(p);
+	}
+	printk("\n");
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip22/time.c linux/arch/mips64/sgi-ip22/time.c
--- v2.3.47/linux/arch/mips64/sgi-ip22/time.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip22/time.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,20 @@
+/* $Id: time.c,v 1.2 1999/12/04 03:59:01 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * time.c: Generic SGI time_init() code, this will dispatch to the
+ *         appropriate per-architecture time/counter init code.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+
+extern void indy_timer_init(void);
+
+void __init time_init(void)
+{
+	/* XXX assume INDY for now XXX */
+	indy_timer_init();
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/Makefile linux/arch/mips64/sgi-ip27/Makefile
--- v2.3.47/linux/arch/mips64/sgi-ip27/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/Makefile	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,16 @@
+# $Id: Makefile,v 1.4 2000/02/18 00:24:31 ralf Exp $
+#
+# Makefile for the IP27 specific kernel interface routines under Linux.
+#
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+L_TARGET = ip27.a
+L_OBJS  = ip27-berr.o ip27-irq.o ip27-irq-glue.o ip27-klconfig.o \
+	  ip27-memory.o ip27-pci.o ip27-pci-dma.o ip27-reset.o ip27-setup.o \
+	  ip27-timer.o ip27-init.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/TODO linux/arch/mips64/sgi-ip27/TODO
--- v2.3.47/linux/arch/mips64/sgi-ip27/TODO	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/TODO	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,11 @@
+1. Need to figure out why PCI writes to the IOC3 hang, and if it is okay
+not to write to the IOC3 ever.
+2. Need to figure out RRB allocation in bridge_startup().
+3. Need to figure out why address swaizzling is needed in inw/outw for 
+Qlogic scsi controllers.
+4. Need to integrate ip27-klconfig.c:find_lboard and 
+ip27-init.c:find_lbaord_real.
+5. Is it okay to set calias space on all nodes as 0, instead of 8k as
+in irix?
+6. Investigate why things do not work without the setup_test() call
+being invoked on all nodes in ip27-memory.c.
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/ip27-berr.c linux/arch/mips64/sgi-ip27/ip27-berr.c
--- v2.3.47/linux/arch/mips64/sgi-ip27/ip27-berr.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/ip27-berr.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,101 @@
+/* $Id: ip27-berr.c,v 1.1 2000/01/20 23:50:27 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/uaccess.h>
+
+extern asmlinkage void handle_ibe(void);
+extern asmlinkage void handle_dbe(void);
+
+extern const struct exception_table_entry __start___dbe_table[];
+extern const struct exception_table_entry __stop___dbe_table[];
+
+static inline unsigned long
+search_one_table(const struct exception_table_entry *first,
+                 const struct exception_table_entry *last,
+                 unsigned long value)
+{
+	while (first <= last) {
+		const struct exception_table_entry *mid;
+		long diff;
+
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+		if (diff == 0)
+			return mid->nextinsn;
+		else if (diff < 0)
+			first = mid+1;
+		else
+			last = mid-1;
+	}
+	return 0;
+}
+
+static inline unsigned long
+search_dbe_table(unsigned long addr)
+{
+	unsigned long ret;
+
+	/* There is only the kernel to search.  */
+	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
+	if (ret) return ret;
+
+	return 0;
+}
+
+void do_ibe(struct pt_regs *regs)
+{
+	printk("Got ibe at 0x%lx\n", regs->cp0_epc);
+	show_regs(regs);
+	dump_tlb_addr(regs->cp0_epc);
+	force_sig(SIGBUS, current);
+	while(1);
+}
+
+void do_dbe(struct pt_regs *regs)
+{
+	unsigned long fixup;
+
+	fixup = search_dbe_table(regs->cp0_epc);
+	if (fixup) {
+		long new_epc;
+
+		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
+		regs->cp0_epc = new_epc;
+		return;
+	}
+
+	printk("Got dbe at 0x%lx\n", regs->cp0_epc);
+	show_regs(regs);
+	dump_tlb_all();
+	while(1);
+	force_sig(SIGBUS, current);
+}
+
+void __init
+bus_error_init(void)
+{
+	/* XXX Initialize all the Hub & Bridge error handling here.  */
+	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
+	int cpuoff = cpu << 8;
+
+	set_except_vector(6, handle_ibe);
+	set_except_vector(7, handle_dbe);
+
+	LOCAL_HUB_S(PI_ERR_INT_PEND,
+	            cpu ? PI_ERR_CLEAR_ALL_A : PI_ERR_CLEAR_ALL_B);
+	LOCAL_HUB_S(PI_ERR_INT_MASK_A + cpuoff, 0);
+	LOCAL_HUB_S(PI_ERR_STACK_ADDR_A + cpuoff, 0);
+	LOCAL_HUB_S(PI_ERR_STACK_SIZE, 0);	/* Disable error stack */
+	LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/ip27-init.c linux/arch/mips64/sgi-ip27/ip27-init.c
--- v2.3.47/linux/arch/mips64/sgi-ip27/ip27-init.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/ip27-init.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,228 @@
+#include <linux/kernel.h>
+#include <linux/mmzone.h>	/* for numnodes */
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/klconfig.h>
+#include <asm/ioc3.h>
+#include <asm/mipsregs.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/gda.h>
+
+typedef unsigned long cpumask_t;	/* into asm/sn/types.h */
+typedef unsigned long cpuid_t;
+
+#define	CPUMASK_CLRALL(p)	(p) = 0
+#define CPUMASK_SETB(p, bit)	(p) |= 1 << (bit)
+
+cpumask_t	boot_cpumask;
+hubreg_t	region_mask = 0;
+static int	fine_mode = 0;
+
+cnodeid_t	nasid_to_compact_node[MAX_NASIDS];
+nasid_t		compact_to_nasid_node[MAX_COMPACT_NODES];
+cnodeid_t	cpuid_to_compact_node[MAXCPUS];
+
+hubreg_t get_region(cnodeid_t cnode)
+{
+	if (fine_mode)
+		return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT;
+	else
+		return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT;
+}
+
+static void gen_region_mask(hubreg_t *region_mask, int maxnodes)
+{
+	cnodeid_t cnode;
+
+	(*region_mask) = 0;
+	for (cnode = 0; cnode < maxnodes; cnode++) {
+		(*region_mask) |= 1ULL << get_region(cnode);
+	}
+}
+
+int is_fine_dirmode(void)
+{
+	return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK)
+		>> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE);
+}
+
+lboard_t * find_lboard_real(lboard_t *start, unsigned char brd_type)
+{
+	/* Search all boards stored on this node. */
+	while (start) {
+		if (start->brd_type == brd_type)
+			return start;
+		start = KLCF_NEXT(start);
+	}
+	/* Didn't find it. */
+	return (lboard_t *)NULL;
+}
+
+klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
+{
+	int index, j;
+
+	if (kli == (klinfo_t *)NULL) {
+		index = 0;
+	} else {
+		for (j = 0; j < KLCF_NUM_COMPS(brd); j++)
+			if (kli == KLCF_COMP(brd, j))
+				break;
+		index = j;
+		if (index == KLCF_NUM_COMPS(brd)) {
+			printk("find_component: Bad pointer: 0x%p\n", kli);
+			return (klinfo_t *)NULL;
+		}
+		index++;		/* next component */
+	}
+
+	for (; index < KLCF_NUM_COMPS(brd); index++) {
+		kli = KLCF_COMP(brd, index);
+		if (KLCF_COMP_TYPE(kli) == struct_type)
+			return kli;
+	}
+
+	/* Didn't find it. */
+	return (klinfo_t *)NULL;
+}
+
+klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type)
+{
+	return find_component(brd, (klinfo_t *)NULL, struct_type);
+}
+
+nasid_t get_actual_nasid(lboard_t *brd)
+{
+	klhub_t *hub;
+
+	if (!brd)
+		return INVALID_NASID;
+
+	/* find out if we are a completely disabled brd. */
+	hub  = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
+	if (!hub)
+		return INVALID_NASID;
+	if (!(hub->hub_info.flags & KLINFO_ENABLE))	/* disabled node brd */
+		return hub->hub_info.physid;
+	else
+		return brd->brd_nasid;
+}
+
+int do_cpumask(cnodeid_t cnode, nasid_t nasid, cpumask_t *boot_cpumask, 
+							int *highest)
+{
+	lboard_t *brd;
+	klcpu_t *acpu;
+	int cpus_found = 0;
+	cpuid_t cpuid;
+
+	brd = find_lboard_real((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
+
+	do {
+		acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
+		while (acpu) {
+			cpuid = acpu->cpu_info.virtid;
+			/* cnode is not valid for completely disabled brds */
+			if (get_actual_nasid(brd) == brd->brd_nasid)
+				cpuid_to_compact_node[cpuid] = cnode;
+			if (cpuid > *highest)
+				*highest = cpuid;
+			/* Only let it join in if it's marked enabled */
+			if (acpu->cpu_info.flags & KLINFO_ENABLE) {
+				CPUMASK_SETB(*boot_cpumask, cpuid);
+				cpus_found++;
+			}
+			acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, 
+								KLSTRUCT_CPU);
+		}
+		brd = KLCF_NEXT(brd);
+		if (brd)
+			brd = find_lboard_real(brd,KLTYPE_IP27);
+		else
+			break;
+	} while (brd);
+
+	return cpus_found;
+}
+
+cpuid_t cpu_node_probe(cpumask_t *boot_cpumask, int *numnodes)
+{
+	int i, cpus = 0, highest = 0;
+	gda_t *gdap = GDA;
+	nasid_t nasid;
+
+	/*
+	 * Initialize the arrays to invalid nodeid (-1)
+	 */
+	for (i = 0; i < MAX_COMPACT_NODES; i++)
+		compact_to_nasid_node[i] = INVALID_NASID;
+	for (i = 0; i < MAX_NASIDS; i++)
+		nasid_to_compact_node[i] = INVALID_CNODEID;
+	for (i = 0; i < MAXCPUS; i++)
+		cpuid_to_compact_node[i] = INVALID_CNODEID;
+
+	*numnodes = 0;
+	for (i = 0; i < MAX_COMPACT_NODES; i++) {
+		if ((nasid = gdap->g_nasidtable[i]) == INVALID_NASID) {
+			break;
+		} else {
+			compact_to_nasid_node[i] = nasid;
+			nasid_to_compact_node[nasid] = i;
+			(*numnodes)++;
+			cpus += do_cpumask(i, nasid, boot_cpumask, &highest);
+		}
+	}
+
+	/*
+	 * Cpus are numbered in order of cnodes. Currently, disabled
+	 * cpus are not numbered.
+	 */
+
+	return(highest + 1);
+}
+
+void mlreset (void)
+{
+	int i, maxcpus;
+
+	fine_mode = is_fine_dirmode();
+
+	/*
+	 * Probe for all CPUs - this creates the cpumask and
+	 * sets up the mapping tables.
+	 */
+	CPUMASK_CLRALL(boot_cpumask);
+	maxcpus = cpu_node_probe(&boot_cpumask, &numnodes);
+
+	gen_region_mask(&region_mask, numnodes);
+
+	/*
+	 * Set all nodes' calias sizes to 8k
+	 */
+	for (i = 0; i < numnodes; i++) {
+		nasid_t nasid;
+
+		nasid = COMPACT_TO_NASID_NODEID(i);
+
+		/*
+		 * Always have node 0 in the region mask, otherwise
+		 * CALIAS accesses get exceptions since the hub
+		 * thinks it is a node 0 address.
+		 */
+		REMOTE_HUB_S(nasid, PI_REGION_PRESENT, (region_mask | 1));
+		REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_0);
+
+#ifdef LATER
+		/*
+		 * Set up all hubs to have a big window pointing at
+		 * widget 0. Memory mode, widget 0, offset 0
+		 */
+		REMOTE_HUB_S(nasid, IIO_ITTE(SWIN0_BIGWIN),
+			((HUB_PIO_MAP_TO_MEM << IIO_ITTE_IOSP_SHIFT) |
+			(0 << IIO_ITTE_WIDGET_SHIFT)));
+#endif
+	}
+}
+
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/ip27-irq-glue.S linux/arch/mips64/sgi-ip27/ip27-irq-glue.S
--- v2.3.47/linux/arch/mips64/sgi-ip27/ip27-irq-glue.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/ip27-irq-glue.S	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,65 @@
+/* $Id: ip27-irq-glue.S,v 1.1 2000/01/17 23:32:47 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.text
+	.set	noat
+	.align	5
+NESTED(ip27_irq, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+
+	/* IP27 may signal interrupt which we're not interested in.
+	   Mask them out.  */
+	mfc0	s0, CP0_CAUSE
+	mfc0	t0, CP0_STATUS
+	and	s0, t0
+
+	/* First check for RT interrupt.  */
+	andi	a0, s0, CAUSEF_IP4
+	beqz	a0, 1f
+
+	/* Ok, a timer interrupt. */
+	move	a0, sp
+	jal	rt_timer_interrupt
+
+	j	ret_from_irq
+
+1:	andi	a0, s0, (CAUSEF_IP2 | CAUSEF_IP3)
+	beqz	a0, 1f
+
+	/* ... a device interrupt ...  */
+	move	a0, sp
+	jal	ip27_do_irq
+
+	j	ret_from_irq
+
+1:
+#if 1
+	mfc0	a1, CP0_STATUS
+	srl	a1, a1, 8
+	andi	a1, 0xff
+
+	mfc0	a2, CP0_CAUSE
+	srl	a2, a2, 8
+	andi	a2, 0xff
+
+	move	a3, s0
+	PRINT("Spurious interrupt, c0_status = %02x, c0_cause = %02x, pending %02x.\n")
+	ld	a1, PT_EPC(sp)
+0:	b	0b
+#endif
+
+	j	ret_from_irq
+	END(ip27_irq)
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/ip27-irq.c linux/arch/mips64/sgi-ip27/ip27-irq.c
--- v2.3.47/linux/arch/mips64/sgi-ip27/ip27-irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/ip27-irq.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,370 @@
+/* $Id: ip27-irq.c,v 1.6 2000/02/10 05:58:56 dagum Exp $
+ *
+ * ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
+ *
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/malloc.h>
+#include <linux/random.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/pci/bridge.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/arch.h>
+
+extern asmlinkage void ip27_irq(void);
+int (*irq_cannonicalize)(int irq);
+
+unsigned int local_bh_count[NR_CPUS];
+unsigned int local_irq_count[NR_CPUS];
+unsigned long spurious_count = 0;
+
+void disable_irq(unsigned int irq_nr)
+{
+	panic("disable_irq() called ...");
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+	panic("enable_irq() called ...");
+}
+
+/* This is stupid for an Origin which can have thousands of IRQs ...  */
+static struct irqaction *irq_action[NR_IRQS];
+
+int get_irq_list(char *buf)
+{
+	int i, len = 0;
+	struct irqaction * action;
+
+	for (i = 0 ; i < 32 ; i++) {
+		action = irq_action[i];
+		if (!action) 
+			continue;
+		len += sprintf(buf+len, "%2d: %8d %c %s", i, kstat.irqs[0][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;
+}
+
+/*
+ * do_IRQ handles all normal device IRQ's (the special SMP cross-CPU interrupts
+ * have their own specific handlers).
+ */
+asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
+{
+	struct irqaction *action;
+	int do_random, cpu;
+
+	cpu = smp_processor_id();
+	irq_enter(cpu);
+	kstat.irqs[cpu][irq]++;
+
+	action = *(irq + irq_action);
+	if (action) {
+		if (!(action->flags & SA_INTERRUPT))
+			__sti();
+		action = *(irq + irq_action);
+		do_random = 0;
+        	do {
+			do_random |= action->flags;
+			action->handler(irq, action->dev_id, regs);
+			action = action->next;
+        	} while (action);
+		if (do_random & SA_SAMPLE_RANDOM)
+			add_interrupt_randomness(irq);
+		__cli();
+	}
+	irq_exit(cpu);
+
+	/* unmasking and bottom half handling is done magically for us. */
+}
+
+/*
+ * Find first bit set
+ */
+static int ms1bit(unsigned long x)
+{
+	int	b;
+
+	if (x >> 32) 	b = 32, x >>= 32;
+	else		b  =  0;
+	if (x >> 16)	b += 16, x >>= 16;
+	if (x >>  8)	b +=  8, x >>=  8;
+	if (x >>  4)	b +=  4, x >>=  4;
+	if (x >>  2)	b +=  2, x >>=  2;
+
+	return b + (int) (x >> 1);
+}
+	
+/* For now ...  */
+void ip27_do_irq(struct pt_regs *regs)
+{
+	int irq;
+	hubreg_t pend0, mask0;
+
+	/* copied from Irix intpend0() */
+	while (((pend0 = LOCAL_HUB_L(PI_INT_PEND0)) & 
+				(mask0 = LOCAL_HUB_L(PI_INT_MASK0_A))) != 0) {
+		do {
+			irq = ms1bit(pend0);
+			LOCAL_HUB_S(PI_INT_MASK0_A, mask0 & ~(1 << irq));
+			LOCAL_HUB_S(PI_INT_PEND_MOD, irq);
+			LOCAL_HUB_L(PI_INT_MASK0_A);		/* Flush */
+			do_IRQ(irq, regs);
+			LOCAL_HUB_S(PI_INT_MASK0_A, mask0);
+			pend0 ^= 1ULL << irq;
+		} while (pend0);
+	}
+}
+
+
+/* Startup one of the (PCI ...) IRQs routes over a bridge.  */
+static unsigned int bridge_startup(unsigned int irq)
+{
+	bridge_t *bridge = (bridge_t *) 0x9200000008000000;
+	bridgereg_t br;
+	int pin;
+
+	/* FIIIIIXME ...  Temporary kludge.  This knows how interrupts are
+	   setup in _my_ Origin.  */
+	switch (irq) {
+	case IOC3_SERIAL_INT:	pin = 3; break;
+	case IOC3_ETH_INT:	pin = 2; break;
+	case SCSI1_INT:		pin = 1; break;
+	case SCSI0_INT:		pin = 0; break;
+	default:		panic("bridge_startup: whoops?");
+	}
+
+	br = LOCAL_HUB_L(PI_INT_MASK0_A);
+	LOCAL_HUB_S(PI_INT_MASK0_A, br | (1 << irq));
+	LOCAL_HUB_L(PI_INT_MASK0_A);			/* Flush */
+
+	bridge->b_int_addr[pin].addr = 0x20000 | irq;
+	bridge->b_int_enable |= (1 << pin);
+	if (irq < 2) {
+		bridgereg_t device;
+#if 0
+		/*
+	 	 * Allocate enough RRBs on the bridge for the DMAs.
+	 	 * Right now allocating 2 RRBs on the normal channel
+	 	 * and 2 on the virtual channel for slot 0 on the bus.
+		 * And same for slot 1, to get ioc3 eth working.
+	 	 */
+		Not touching b_even_resp	  /* boot doesn't go far */
+		bridge->b_even_resp = 0xdd99cc88; /* boot doesn't go far */
+		bridge->b_even_resp = 0xcccc8888; /* breaks eth0 */
+		bridge->b_even_resp = 0xcc88;	  /* breaks eth0 */
+#endif
+		/* Turn on bridge swapping */
+		device = bridge->b_device[irq].reg;
+		device |= BRIDGE_DEV_SWAP_DIR;
+		bridge->b_device[irq].reg = device;
+	}
+	bridge->b_widget.w_tflush;			/* Flush */
+
+	return 0;	/* Never anything pending.  */
+}
+
+/* Startup one of the (PCI ...) IRQs routes over a bridge.  */
+static unsigned int bridge_shutdown(unsigned int irq)
+{
+	bridge_t *bridge = (bridge_t *) 0x9200000008000000;
+	bridgereg_t br;
+	int pin;
+
+	/* FIIIIIXME ...  Temporary kludge.  This knows how interrupts are
+	   setup in _my_ Origin.  */
+	switch (irq) {
+	case IOC3_SERIAL_INT:	pin = 3; break;
+	case IOC3_ETH_INT:	pin = 2; break;
+	case SCSI1_INT:		pin = 1; break;
+	case SCSI0_INT:		pin = 0; break;
+	default:		panic("bridge_startup: whoops?");
+	}
+
+	br = LOCAL_HUB_L(PI_INT_MASK0_A);
+	LOCAL_HUB_S(PI_INT_MASK0_A, br & ~(1 << irq));
+	LOCAL_HUB_L(PI_INT_MASK0_A);			/* Flush */
+
+	bridge->b_int_enable &= ~(1 << pin);
+	bridge->b_widget.w_tflush;			/* Flush */
+
+	return 0;	/* Never anything pending.  */
+}
+
+static void bridge_init(void)
+{
+	bridge_t *bridge = (bridge_t *) 0x9200000008000000;
+
+	/* Hmm...  IRIX sets additional bits in the address which are
+	   documented as reserved in the bridge docs ...  */
+	bridge->b_int_mode = 0x0;			/* Don't clear ints */
+#if 0
+	bridge->b_wid_int_upper = 0x000a8000;           /* Ints to node 0 */
+	bridge->b_wid_int_lower = 0x01000090;
+	bridge->b_dir_map = 0xa00000;			/* DMA */
+#endif /* shouldn't lower= 0x01800090 ??? */
+        bridge->b_wid_int_upper = 0x00098000;           /* Ints to node 0 */
+        bridge->b_wid_int_lower = 0x01800090;
+        bridge->b_dir_map = 0x900000;                   /* DMA */
+
+	bridge->b_int_enable = 0;
+	bridge->b_widget.w_tflush;			/* Flush */
+	set_cp0_status(SRB_DEV0 | SRB_DEV1, SRB_DEV0 | SRB_DEV1);
+}
+
+void irq_debug(void)
+{
+	bridge_t *bridge = (bridge_t *) 0x9200000008000000;
+
+	printk("bridge->b_int_status = 0x%x\n", bridge->b_int_status);
+	printk("bridge->b_int_enable = 0x%x\n", bridge->b_int_enable);
+	printk("PI_INT_PEND0   = 0x%x\n", LOCAL_HUB_L(PI_INT_PEND0));
+	printk("PI_INT_MASK0_A = 0x%x\n", LOCAL_HUB_L(PI_INT_MASK0_A));
+}
+
+int setup_irq(int irq, struct irqaction *new)
+{
+	int shared = 0;
+	struct irqaction *old, **p;
+	unsigned long flags;
+
+	if (new->flags & SA_SAMPLE_RANDOM)
+		rand_initialize_irq(irq);
+
+	save_and_cli(flags);
+	p = irq_action + irq;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ)) {
+			restore_flags(flags);
+			return -EBUSY;
+		}
+
+		/* Add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	*p = new;
+
+	if (!shared) {
+		bridge_startup(irq);
+	}
+	restore_flags(flags);
+
+	return 0;
+}
+
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, const char * devname, void *dev_id)
+{
+	int retval;
+	struct irqaction *action;
+
+	if (irq > 9)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action = (struct irqaction *)kmalloc(sizeof(*action), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_irq(irq, action);
+	if (retval)
+		kfree(action);
+	return retval;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	struct irqaction * action, **p;
+	unsigned long flags;
+
+	if (irq > 9) {
+		printk("Trying to free IRQ%d\n", irq);
+		return;
+	}
+	for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
+		if (action->dev_id != dev_id)
+			continue;
+
+		/* Found it - now free it */
+		save_and_cli(flags);
+		*p = action->next;
+		if (!irq[irq_action])
+			bridge_shutdown(irq);
+		restore_flags(flags);
+		kfree(action);
+		return;
+	}
+	printk("Trying to free free IRQ%d\n",irq);
+}
+
+/* Useless ISA nonsense.  */
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+static int indy_irq_cannonicalize(int irq)
+{
+	return irq;	/* Sane hardware, sane code ... */
+}
+
+void __init init_IRQ(void)
+{
+	irq_cannonicalize = indy_irq_cannonicalize;
+
+	bridge_init();
+	set_except_vector(0, ip27_irq);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/ip27-klconfig.c linux/arch/mips64/sgi-ip27/ip27-klconfig.c
--- v2.3.47/linux/arch/mips64/sgi-ip27/ip27-klconfig.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/ip27-klconfig.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,33 @@
+/* $Id: ip27-klconfig.c,v 1.1 2000/01/17 23:32:47 ralf Exp $
+ *
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#include <linux/timex.h>
+#include <linux/mm.h>		
+
+#include <asm/sn/klconfig.h>
+
+lboard_t *find_lboard(unsigned int type)
+{
+	lboard_t *b;
+
+	for (
+b = KL_CONFIG_INFO(get_nasid());
+b;
+b = KLCF_NEXT(b)) {
+		if (KLCF_REMOTE(b))
+			continue;		/* Skip remote boards. */
+
+		if (b->brd_type == type)
+			return (lboard_t *) b;
+	}
+
+	return NULL;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/ip27-memory.c linux/arch/mips64/sgi-ip27/ip27-memory.c
--- v2.3.47/linux/arch/mips64/sgi-ip27/ip27-memory.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/ip27-memory.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,388 @@
+/* $Id: ip27-memory.c,v 1.9 2000/02/10 09:07:31 kanoj Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 by Ralf Baechle
+ * Copyright (C) 2000 by Silicon Graphics, Inc.
+ *
+ * On SGI IP27 the ARC memory configuration data is completly bogus but
+ * alternate easier to use mechanisms are available.
+ */
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/swap.h>
+
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+#include <asm/pgtable.h>
+#include <asm/sn/types.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/arch.h>
+#include <asm/mmzone.h>
+
+typedef unsigned long pfn_t;			/* into <asm/sn/types.h> */
+#define KDM_TO_PHYS(x)	((x) & TO_PHYS_MASK)	/* into asm/addrspace.h */
+
+extern char _end;
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define SLOT_IGNORED	0xffff
+
+short slot_lastfilled_cache[MAX_COMPACT_NODES];
+unsigned short slot_psize_cache[MAX_COMPACT_NODES][MAX_MEM_SLOTS];
+static pfn_t numpages;
+static pfn_t pagenr = 0;
+
+plat_pg_data_t *plat_node_data[MAX_COMPACT_NODES];
+bootmem_data_t plat_node_bdata[MAX_COMPACT_NODES];
+
+int numa_debug(void)
+{
+	printk("NUMA debug\n");
+	*(int *)0 = 0;
+	return(0);
+}
+
+/*
+ * Return pfn of first free page of memory on a node. PROM may allocate
+ * data structures on the first couple of pages of the first slot of each 
+ * node. If this is the case, getfirstfree(node) > getslotstart(node, 0).
+ */
+pfn_t node_getfirstfree(cnodeid_t cnode)
+{
+#ifdef LATER
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+	if (cnode == 0)
+		return KDM_TO_PHYS((unsigned long)(&_end));
+	return KDM_TO_PHYS(SYMMON_STK_ADDR(nasid, 0));
+#endif
+	if (cnode == 0)
+		return (KDM_TO_PHYS(PAGE_ALIGN((unsigned long)(&_end)) - 
+					(CKSEG0 - K0BASE)) >> PAGE_SHIFT);
+	return slot_getbasepfn(cnode, 0);
+}
+
+/*
+ * Return the number of pages of memory provided by the given slot
+ * on the specified node.
+ */
+pfn_t slot_getsize(cnodeid_t node, int slot)
+{
+	return (pfn_t) slot_psize_cache[node][slot];
+}
+
+/*
+ * Return highest slot filled
+ */
+int node_getlastslot(cnodeid_t node)
+{
+	return (int) slot_lastfilled_cache[node];
+}
+
+/*
+ * Return the pfn of the last free page of memory on a node.
+ */
+pfn_t node_getmaxclick(cnodeid_t node)
+{
+	pfn_t	slot_psize;
+	int	slot;
+
+	/*
+	 * Start at the top slot. When we find a slot with memory in it,
+	 * that's the winner.
+	 */
+	for (slot = (node_getnumslots(node) - 1); slot >= 0; slot--) {
+		if ((slot_psize = slot_getsize(node, slot))) {
+			if (slot_psize == SLOT_IGNORED)
+				continue;
+			/* Return the basepfn + the slot size, minus 1. */
+			return slot_getbasepfn(node, slot) + slot_psize - 1;
+		}
+	}
+
+	/*
+	 * If there's no memory on the node, return 0. This is likely
+	 * to cause problems.
+	 */
+	return (pfn_t)0;
+}
+
+static pfn_t slot_psize_compute(cnodeid_t node, int slot)
+{
+	nasid_t nasid;
+	lboard_t *brd;
+	klmembnk_t *banks;
+	unsigned long size;
+
+	nasid = COMPACT_TO_NASID_NODEID(node);
+	/* Find the node board */
+	brd = find_lboard_real((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
+	if (!brd)
+		return 0;
+
+	/* Get the memory bank structure */
+	banks = (klmembnk_t *)find_first_component(brd, KLSTRUCT_MEMBNK);
+	if (!banks)
+		return 0;
+
+	/* Size in _Megabytes_ */
+	size = (unsigned long)banks->membnk_bnksz[slot/4];
+
+	/* hack for 128 dimm banks */
+	if (size <= 128) {
+		if (slot%4 == 0) {
+			size <<= 20;		/* size in bytes */
+			return(size >> PAGE_SHIFT);
+		} else {
+			return 0;
+		}
+	} else {
+		size /= 4;
+		size <<= 20;
+		return(size >> PAGE_SHIFT);
+	}
+}
+
+pfn_t szmem(pfn_t fpage, pfn_t maxpmem)
+{
+	cnodeid_t node;
+	int slot, numslots;
+	pfn_t num_pages = 0, slot_psize;
+	pfn_t slot0sz = 0, nodebytes;	/* Hack to detect problem configs */
+	int ignore;
+
+	for (node = 0; node < numnodes; node++) {
+		numslots = node_getnumslots(node);
+		ignore = nodebytes = 0;
+		for (slot = 0; slot < numslots; slot++) {
+			slot_psize = slot_psize_compute(node, slot);
+			if (slot == 0) slot0sz = slot_psize;
+			/* 
+			 * We need to refine the hack when we have replicated
+			 * kernel text.
+			 */
+			nodebytes += SLOT_SIZE;
+			if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) >
+						(slot0sz << PAGE_SHIFT))
+				ignore = 1;
+			if (ignore && slot_psize) {
+				printk("Ignoring slot %d onwards on node %d\n",
+								slot, node);
+				slot_psize_cache[node][slot] = SLOT_IGNORED;
+				slot = numslots;
+				continue;
+			}
+			num_pages += slot_psize;
+			slot_psize_cache[node][slot] = 
+					(unsigned short) slot_psize;
+			if (slot_psize)
+				slot_lastfilled_cache[node] = slot;
+		}
+	}
+	if (maxpmem)
+		return((maxpmem > num_pages) ? num_pages : maxpmem);
+	else
+		return num_pages;
+}
+
+/*
+ * HACK ALERT - Things do not work if this is not here. Maybe this is
+ * acting as a pseudocacheflush operation. The write pattern seems to
+ * be important, writing a 0 does not help.
+ */
+void setup_test(cnodeid_t node, pfn_t start, pfn_t end)
+{
+	unsigned long *ptr = __va(start << PAGE_SHIFT);
+	unsigned long size = 4 * 1024 * 1024;	/* 4M L2 caches */
+
+	while (size) {
+		size -= sizeof(unsigned long);
+		*ptr = (0xdeadbeefbabeb000UL|node);
+		/* *ptr = 0; */
+		ptr++;
+	}
+}
+
+/*
+ * Currently, the intranode memory hole support assumes that each slot
+ * contains at least 32 MBytes of memory. We assume all bootmem data
+ * fits on the first slot.
+ */
+void __init prom_meminit(void)
+{
+	extern void mlreset(void);
+	cnodeid_t node;
+	pfn_t slot_firstpfn, slot_lastpfn, slot_freepfn;
+	unsigned long bootmap_size;
+	int node_datasz;
+
+	node_datasz = PFN_UP(sizeof(plat_pg_data_t));
+	mlreset();
+	numpages = szmem(0, 0);
+	for (node = (numnodes - 1); node >= 0; node--) {
+		slot_firstpfn = slot_getbasepfn(node, 0);
+		slot_lastpfn = slot_firstpfn + slot_getsize(node, 0);
+		slot_freepfn = node_getfirstfree(node);
+		/* Foll line hack for non discontigmem; remove once discontigmem
+		 * becomes the default. */
+		max_low_pfn = (slot_lastpfn - slot_firstpfn);
+		if (node != 0) 
+			setup_test(node, slot_freepfn, slot_lastpfn);
+		/*
+		 * Allocate the node data structure on the node first.
+		 */
+		plat_node_data[node] = (plat_pg_data_t *)(__va(slot_freepfn \
+							<< PAGE_SHIFT));
+		NODE_DATA(node)->bdata = plat_node_bdata + node;
+		slot_freepfn += node_datasz;
+	  	bootmap_size = init_bootmem_node(node, slot_freepfn, 
+						slot_firstpfn, slot_lastpfn);
+		free_bootmem_node(node, slot_firstpfn << PAGE_SHIFT, 
+				(slot_lastpfn - slot_firstpfn) << PAGE_SHIFT);
+		reserve_bootmem_node(node, slot_firstpfn << PAGE_SHIFT,
+		  ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size);
+	}
+	printk("Total memory probed : 0x%lx pages\n", numpages);
+}
+
+int __init page_is_ram(unsigned long pagenr)
+{
+        return 1;
+}
+
+void __init
+prom_free_prom_memory (void)
+{
+	/* We got nothing to free here ...  */
+}
+
+#ifdef CONFIG_DISCONTIGMEM
+
+void __init paging_init(void)
+{
+	cnodeid_t node;
+	unsigned int zones_size[MAX_NR_ZONES] = {0, 0, 0};
+
+	/* Initialize the entire pgd.  */
+	pgd_init((unsigned long)swapper_pg_dir);
+	pgd_init((unsigned long)swapper_pg_dir + PAGE_SIZE / 2);
+	pmd_init((unsigned long)invalid_pmd_table);
+
+	for (node = 0; node < numnodes; node++) {
+		pfn_t start_pfn = slot_getbasepfn(node, 0);
+		pfn_t end_pfn = node_getmaxclick(node);
+
+		zones_size[ZONE_DMA] = end_pfn + 1 - start_pfn;
+		PLAT_NODE_DATA(node)->physstart = (start_pfn << PAGE_SHIFT);
+		PLAT_NODE_DATA(node)->size = (zones_size[ZONE_DMA] << PAGE_SHIFT);
+		free_area_init_node(node, NODE_DATA(node), zones_size, 
+						start_pfn << PAGE_SHIFT);
+		PLAT_NODE_DATA(node)->start_mapnr = 
+					(NODE_DATA(node)->node_mem_map - mem_map);
+		if ((PLAT_NODE_DATA(node)->start_mapnr + 
+					PLAT_NODE_DATA(node)->size) > pagenr)
+			pagenr = PLAT_NODE_DATA(node)->start_mapnr +
+					PLAT_NODE_DATA(node)->size;
+	}
+}
+
+void __init mem_init(void)
+{
+	extern char _ftext, _etext, _fdata, _edata;
+	extern char __init_begin, __init_end;
+	extern unsigned long totalram_pages;
+	extern unsigned long setup_zero_pages(void);
+	cnodeid_t nid;
+	unsigned long tmp, ram;
+	unsigned long codesize, reservedpages, datasize, initsize;
+	int slot, numslots;
+	struct page *pg, *pslot;
+	pfn_t pgnr;
+
+	num_physpages = numpages;	/* memory already sized by szmem */
+	max_mapnr = pagenr;		/* already found during paging_init */
+	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
+
+	for (nid = 0; nid < numnodes; nid++) {
+
+		/*
+	 	 * This will free up the bootmem, ie, slot 0 memory.
+	 	 */
+		totalram_pages += free_all_bootmem_node(nid);
+
+		/*
+		 * We need to manually do the other slots.
+		 */
+		pg = NODE_DATA(nid)->node_mem_map + slot_getsize(nid, 0);
+		pgnr = PLAT_NODE_DATA(nid)->start_mapnr + slot_getsize(nid, 0);
+		numslots = node_getlastslot(nid);
+		for (slot = 1; slot <= numslots; slot++) {
+			pslot = NODE_DATA(nid)->node_mem_map + 
+			   slot_getbasepfn(nid, slot) - slot_getbasepfn(nid, 0);
+
+			/*
+			 * Mark holes in previous slot. May also want to
+			 * free up the pages that hold the memmap entries.
+			 */
+			while (pg < pslot) {
+				pg->flags |= (1<<PG_skip);
+				pg++; pgnr++;
+			}
+
+			/*
+			 * Free valid memory in current slot.
+			 */
+			pslot += slot_getsize(nid, slot);
+			while (pg < pslot) {
+				if (!page_is_ram(pgnr))
+					continue;
+				ClearPageReserved(pg);
+				atomic_set(&pg->count, 1);
+				__free_page(pg);
+				totalram_pages++;
+				pg++; pgnr++;
+			}
+		}
+	}
+
+	totalram_pages -= setup_zero_pages();	/* This comes from node 0 */
+
+	reservedpages = ram = 0;
+	for (nid = 0; nid < numnodes; nid++) {
+		for (tmp = PLAT_NODE_DATA(nid)->start_mapnr; tmp < 
+			((PLAT_NODE_DATA(nid)->start_mapnr) + 
+			(PLAT_NODE_DATA(nid)->size >> PAGE_SHIFT)); tmp++) {
+			/* Ignore holes */
+			if (PageSkip(mem_map+tmp))
+				continue;
+			if (page_is_ram(tmp)) {
+				ram++;
+				if (PageReserved(mem_map+tmp))
+					reservedpages++;
+			}
+		}
+	}
+
+	codesize =  (unsigned long) &_etext - (unsigned long) &_ftext;
+	datasize =  (unsigned long) &_edata - (unsigned long) &_fdata;
+	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
+		"%ldk data, %ldk init)\n",
+		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+		ram << (PAGE_SHIFT-10),
+		codesize >> 10,
+		reservedpages << (PAGE_SHIFT-10),
+		datasize >> 10,
+		initsize >> 10);
+}
+
+#endif /* CONFIG_DISCONTIGMEM */
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/ip27-pci-dma.c linux/arch/mips64/sgi-ip27/ip27-pci-dma.c
--- v2.3.47/linux/arch/mips64/sgi-ip27/ip27-pci-dma.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/ip27-pci-dma.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,55 @@
+/* $Id: ip27-pci-dma.c,v 1.1 2000/02/18 00:24:31 ralf Exp $
+ *
+ * Dynamic DMA mapping support.
+ *
+ * On the Origin there is dynamic DMA address translation for all PCI DMA.
+ * However we don't use this facility yet but rely on the 2gb direct
+ * mapped DMA window for PCI64.  So consistent alloc/free are merely page
+ * allocation/freeing.  The rest of the dynamic DMA mapping interface is
+ * implemented in <asm/pci.h>.  So this code will fail with more than
+ * 2gb of memory.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+/* Pure 2^n version of get_order */
+extern __inline__ int __get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t *dma_handle)
+{
+	void *ret;
+	int gfp = GFP_ATOMIC;
+	int order = __get_order(size);
+
+	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
+		gfp |= GFP_DMA;
+	ret = (void *)__get_free_pages(gfp, order);
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_bus(ret);
+	}
+
+	return ret;
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	free_pages((unsigned long)vaddr, __get_order(size));
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/ip27-pci.c linux/arch/mips64/sgi-ip27/ip27-pci.c
--- v2.3.47/linux/arch/mips64/sgi-ip27/ip27-pci.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/ip27-pci.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,258 @@
+/* $Id: ip27-pci.c,v 1.8 2000/02/16 01:07:30 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/sn/arch.h>
+#include <asm/pci/bridge.h>
+#include <asm/paccess.h>
+
+/*
+ * The Bridge ASIC supports both type 0 and type 1 access.  Type 1 is
+ * not really documented, so right now I can't write code which uses it.
+ * Therefore we use type 0 accesses for now even though they won't work
+ * correcly for PCI-to-PCI bridges.
+ */
+#define CF0_READ_PCI_CFG(dev,where,value,bm,mask)			\
+do {									\
+	bridge_t *bridge = (bridge_t *) 0x9200000008000000;		\
+	int slot = PCI_SLOT(dev->devfn);				\
+	int fn = PCI_FUNC(dev->devfn);					\
+	volatile u32 *addr;						\
+	u32 cf, __bit;							\
+									\
+	if (dev->bus->number)						\
+		return PCIBIOS_DEVICE_NOT_FOUND;			\
+									\
+	__bit = (((where) & (bm)) << 3);				\
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];	\
+	if (get_dbe(cf, addr))						\
+		return PCIBIOS_DEVICE_NOT_FOUND;			\
+	*value = (cf >> __bit) & (mask);				\
+	return PCIBIOS_SUCCESSFUL;					\
+} while (0)
+
+static int
+pci_conf0_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	CF0_READ_PCI_CFG(dev,where,value,3,0xff);
+}
+
+static int
+pci_conf0_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	CF0_READ_PCI_CFG(dev,where,value,2,0xffff);
+}
+
+static int
+pci_conf0_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	CF0_READ_PCI_CFG(dev,where,value,0,0xffffffff);
+}
+
+#define CF0_WRITE_PCI_CFG(dev,where,value,bm,mask)			\
+do {									\
+	bridge_t *bridge = (bridge_t *) 0x9200000008000000;		\
+	int slot = PCI_SLOT(dev->devfn);				\
+	int fn = PCI_FUNC(dev->devfn);					\
+	volatile u32 *addr;						\
+	u32 cf, __bit;							\
+									\
+	if (dev->bus->number)						\
+		return PCIBIOS_DEVICE_NOT_FOUND;			\
+									\
+	if (dev->vendor == PCI_VENDOR_ID_SGI				\
+	    && dev->device == PCI_DEVICE_ID_SGI_IOC3)			\
+		return PCIBIOS_SUCCESSFUL;				\
+									\
+	__bit = (((where) & (bm)) << 3);				\
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];	\
+	if (get_dbe(cf, addr))						\
+		return PCIBIOS_DEVICE_NOT_FOUND;			\
+	cf &= (~mask);							\
+	cf |= (value);							\
+	put_dbe(cf, addr);						\
+	return PCIBIOS_SUCCESSFUL;					\
+} while (0)
+
+static int
+pci_conf0_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	CF0_WRITE_PCI_CFG(dev,where,value,3,0xff);
+}
+
+static int
+pci_conf0_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	CF0_WRITE_PCI_CFG(dev,where,value,2,0xffff);
+}
+
+static int
+pci_conf0_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	CF0_WRITE_PCI_CFG(dev,where,value,0,0xffffffff);
+}
+
+
+static struct pci_ops bridge_pci_ops = {
+	pci_conf0_read_config_byte,
+	pci_conf0_read_config_word,
+	pci_conf0_read_config_dword,
+	pci_conf0_write_config_byte,
+	pci_conf0_write_config_word,
+	pci_conf0_write_config_dword
+};
+
+void __init pcibios_init(void)
+{
+	struct pci_ops *ops = &bridge_pci_ops;
+	nasid_t nid = get_nasid();
+
+	ioport_resource.end = ~0UL;
+
+	printk("PCI: Probing PCI hardware on host bus 0, node %d.\n", nid);
+	pci_scan_bus(0, ops, NULL);
+}
+
+static inline u8
+bridge_swizzle(u8 pin, u8 slot) 
+{
+	return (((pin-1) + slot) % 4) + 1;
+}
+
+static u8 __init
+pci_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	u8 pin = *pinp;
+
+	while (dev->bus->self) {	/* Move up the chain of bridges. */
+		pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+		dev = dev->bus->self;
+	}
+	*pinp = pin;
+
+	return PCI_SLOT(dev->devfn);
+}
+
+/* XXX This should include the node ID into the final interrupt number.  */
+static int __init
+pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return (slot + (((pin-1) & 1) << 2)) & 7;
+}
+
+void __init
+pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+void __init
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+                        struct resource *res, int resource)
+{
+	unsigned long where, size;
+	u32 reg;
+
+	where = PCI_BASE_ADDRESS_0 + (resource * 4);
+	size = res->end - res->start;
+	pci_read_config_dword(dev, where, &reg);
+	reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
+	pci_write_config_dword(dev, where, reg);
+}
+
+void __init
+pcibios_fixup_bus(struct pci_bus *b)
+{
+	unsigned short command;
+	struct list_head *ln;
+	struct pci_dev *dev;
+
+	pci_fixup_irqs(pci_swizzle, pci_map_irq);
+
+	/*
+	 * Older qlogicisp driver expects to have the IO space enable 
+	 * bit set. Make that happen for qlogic in slots 0 and 1. Things
+	 * stop working if we program the controllers as not having
+	 * PCI_COMMAND_MEMORY, so we have to fudge the mem_flags.
+	 */
+	for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
+		dev = pci_dev_b(ln);
+		if (PCI_FUNC(dev->devfn) == 0) {
+			if ((PCI_SLOT(dev->devfn) == 0) || 
+						(PCI_SLOT(dev->devfn) == 1)) {
+				if (pci_read_config_word(dev, PCI_COMMAND, 
+								&command) == 0) {
+					command |= PCI_COMMAND_IO;
+					pci_write_config_word(dev, PCI_COMMAND, 
+									command);
+					dev->resource[1].flags |= 1;
+				}
+			}
+		}
+	}
+}
+
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus * bus,
+                          struct pbus_set_ranges_data * ranges)
+{
+	ranges->io_start -= bus->resource[0]->start;
+	ranges->io_end -= bus->resource[0]->start;
+	ranges->mem_start -= bus->resource[1]->start;
+	ranges->mem_end -= bus->resource[1]->start;
+}
+
+int __init
+pcibios_enable_device(struct pci_dev *dev)
+{
+	/* Not needed, since we enable all devices at startup.  */
+	return 0;
+}
+
+void __init
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+}
+
+char * __init
+pcibios_setup(char *str)
+{
+	/* Nothing to do for now.  */
+
+	return str;
+}
+
+static void __init
+pci_fixup_ioc3(struct pci_dev *d)
+{
+	int i;
+
+	/* IOC3 only decodes 0x20 bytes of the config space, so we end up
+	   with tons of bogus information in the pci_dev.  On Origins the
+	   INTA, INTB and INTC pins are all wired together as if it'd only
+	   use INTA.  */
+	printk("PCI: Fixing base addresses for device %s\n", d->slot_name);
+
+	for (i = 1; i <= PCI_ROM_RESOURCE; i++) {
+		d->resource[i].start = 0UL;
+		d->resource[i].end = 0UL;
+		d->resource[i].flags = 0UL;
+	}
+	d->subsystem_vendor = 0;
+	d->subsystem_device = 0;
+	d->irq = 1;
+}
+
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
+	  pci_fixup_ioc3 },
+	{ 0 }
+};
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/ip27-reset.c linux/arch/mips64/sgi-ip27/ip27-reset.c
--- v2.3.47/linux/arch/mips64/sgi-ip27/ip27-reset.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/ip27-reset.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,45 @@
+/* $Id: ip27-reset.c,v 1.1 2000/01/17 23:32:47 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Reset an IP27.
+ *
+ * Copyright (C) 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
+
+void machine_restart(char *command) __attribute__((noreturn));
+void machine_halt(void) __attribute__((noreturn));
+void machine_power_off(void) __attribute__((noreturn));
+
+/* XXX How to pass the reboot command to the firmware??? */
+void machine_restart(char *command)
+{
+	ArcReboot();
+}
+
+void machine_halt(void)
+{
+	ArcEnterInteractiveMode();
+}
+
+void machine_power_off(void)
+{
+	/* To do ...  */
+}
+
+void ip27_reboot_setup(void)
+{
+	/* Nothing to do on IP27.  */
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/ip27-rtc.c linux/arch/mips64/sgi-ip27/ip27-rtc.c
--- v2.3.47/linux/arch/mips64/sgi-ip27/ip27-rtc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/ip27-rtc.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,332 @@
+/*
+ *	Driver for the SGS-Thomson M48T35 Timekeeper RAM chip
+ *
+ *	Real Time Clock interface for Linux	
+ *
+ *	TODO: Implement periodic interrupts.
+ *
+ *	Copyright (C) 2000 Silicon Graphics, Inc.
+ *	Written by Ulf Carlsson (ulfc@engr.sgi.com)
+ *
+ *	Based on code written by Paul Gortmaker.
+ *
+ *	This driver allows use of the real time clock (built into
+ *	nearly all computers) from user space. It exports the /dev/rtc
+ *	interface supporting various ioctl() and also the /proc/rtc
+ *	pseudo-file for status information.
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ */
+
+#define RTC_VERSION		"1.09b"
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+
+#include <asm/m48t35.h>
+#include <asm/ioc3.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hub.h>
+
+static int rtc_ioctl(struct inode *inode, struct file *file,
+		     unsigned int cmd, unsigned long arg);
+
+static int rtc_read_proc(char *page, char **start, off_t off,
+                         int count, int *eof, void *data);
+
+static void get_rtc_time(struct rtc_time *rtc_tm);
+
+/*
+ *	Bits in rtc_status. (6 bits of room for future expansion)
+ */
+
+#define RTC_IS_OPEN		0x01	/* means /dev/rtc is in use	*/
+#define RTC_TIMER_ON		0x02	/* missed irq timer active	*/
+
+static unsigned char rtc_status = 0;	/* bitmapped status byte.	*/
+static unsigned long rtc_freq = 0;	/* Current periodic IRQ rate	*/
+static struct m48t35_rtc *rtc;
+
+/*
+ *	If this driver ever becomes modularised, it will be really nice
+ *	to make the epoch retain its value across module reload...
+ */
+
+static unsigned long epoch = 1970;	/* year corresponding to 0x00	*/
+
+static const unsigned char days_in_mo[] = 
+{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		     unsigned long arg)
+{
+
+	struct rtc_time wtime; 
+
+	switch (cmd) {
+	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
+	{
+		get_rtc_time(&wtime);
+		break;
+	}
+	case RTC_SET_TIME:	/* Set the RTC */
+	{
+		struct rtc_time rtc_tm;
+		unsigned char mon, day, hrs, min, sec, leap_yr;
+		unsigned int yrs;
+		unsigned long flags;
+			
+		if (!capable(CAP_SYS_TIME))
+			return -EACCES;
+
+		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
+				   sizeof(struct rtc_time)))
+			return -EFAULT;
+
+		yrs = rtc_tm.tm_year + 1900;
+		mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
+		day = rtc_tm.tm_mday;
+		hrs = rtc_tm.tm_hour;
+		min = rtc_tm.tm_min;
+		sec = rtc_tm.tm_sec;
+
+		if (yrs < 1970)
+			return -EINVAL;
+
+		leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
+
+		if ((mon > 12) || (day == 0))
+			return -EINVAL;
+
+		if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
+			return -EINVAL;
+			
+		if ((hrs >= 24) || (min >= 60) || (sec >= 60))
+			return -EINVAL;
+
+		if ((yrs -= epoch) > 255)    /* They are unsigned */
+			return -EINVAL;
+
+		save_flags(flags);
+		cli();
+		if (yrs > 169) {
+			restore_flags(flags);
+			return -EINVAL;
+		}
+		if (yrs >= 100)
+			yrs -= 100;
+
+		BIN_TO_BCD(sec);
+		BIN_TO_BCD(min);
+		BIN_TO_BCD(hrs);
+		BIN_TO_BCD(day);
+		BIN_TO_BCD(mon);
+		BIN_TO_BCD(yrs);
+
+		rtc->control &= ~M48T35_RTC_SET;
+		rtc->year = yrs;
+		rtc->month = mon;
+		rtc->date = day;
+		rtc->hour = hrs;
+		rtc->min = min;
+		rtc->sec = sec;
+		rtc->control &= ~M48T35_RTC_SET;
+
+		restore_flags(flags);
+		return 0;
+	}
+	default:
+		return -EINVAL;
+	}
+	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
+}
+
+/*
+ *	We enforce only one user at a time here with the open/close.
+ *	Also clear the previous interrupt data on an open, and clean
+ *	up things on a close.
+ */
+
+static int rtc_open(struct inode *inode, struct file *file)
+{
+	if(rtc_status & RTC_IS_OPEN)
+		return -EBUSY;
+
+	MOD_INC_USE_COUNT;
+
+	rtc_status |= RTC_IS_OPEN;
+	return 0;
+}
+
+static int rtc_release(struct inode *inode, struct file *file)
+{
+	/*
+	 * Turn off all interrupts once the device is no longer
+	 * in use, and clear the data.
+	 */
+
+	MOD_DEC_USE_COUNT;
+
+	rtc_status &= ~RTC_IS_OPEN;
+	return 0;
+}
+
+/*
+ *	The various file operations we support.
+ */
+
+static struct file_operations rtc_fops = {
+	NULL,		/* No llseek (yet) */
+	NULL,		/* No read (yet) */
+	NULL,		/* No write */
+	NULL,		/* No readdir */
+	NULL,		/* No poll (yet) */
+	rtc_ioctl,
+	NULL,		/* No mmap */
+	rtc_open,
+	NULL,		/* flush */
+	rtc_release
+};
+
+static struct miscdevice rtc_dev=
+{
+	RTC_MINOR,
+	"rtc",
+	&rtc_fops
+};
+
+static int __init rtc_init(void)
+{
+	unsigned long flags;
+	nasid_t nid;
+
+	nid = get_nasid();
+	rtc = (struct m48t35_rtc *)
+	    KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0;
+
+	printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION);
+	misc_register(&rtc_dev);
+	create_proc_read_entry ("rtc", 0, NULL, rtc_read_proc, NULL);
+
+	save_flags(flags);
+	cli();
+	restore_flags(flags);
+	rtc_freq = 1024;
+	return 0;
+}
+
+static void __exit rtc_exit (void)
+{
+	/* interrupts and timer disabled at this point by rtc_release */
+
+	remove_proc_entry ("rtc", NULL);
+	misc_deregister(&rtc_dev);
+}
+
+module_init(rtc_init);
+module_exit(rtc_exit);
+EXPORT_NO_SYMBOLS;
+
+/*
+ *	Info exported via "/proc/rtc".
+ */
+
+static int rtc_get_status(char *buf)
+{
+	char *p;
+	struct rtc_time tm;
+
+	/*
+	 * Just emulate the standard /proc/rtc
+	 */
+
+	p = buf;
+
+	get_rtc_time(&tm);
+
+	/*
+	 * There is no way to tell if the luser has the RTC set for local
+	 * time or for Universal Standard Time (GMT). Probably local though.
+	 */
+	p += sprintf(p,
+		     "rtc_time\t: %02d:%02d:%02d\n"
+		     "rtc_date\t: %04d-%02d-%02d\n"
+	 	     "rtc_epoch\t: %04lu\n"
+		     "24hr\t\t: yes\n",
+		     tm.tm_hour, tm.tm_min, tm.tm_sec,
+		     tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
+
+	return  p - buf;
+}
+
+static int rtc_read_proc(char *page, char **start, off_t off,
+                                 int count, int *eof, void *data)
+{
+        int len = rtc_get_status(page);
+        if (len <= off+count) *eof = 1;
+        *start = page + off;
+        len -= off;
+        if (len>count) len = count;
+        if (len<0) len = 0;
+        return len;
+}
+
+static void get_rtc_time(struct rtc_time *rtc_tm)
+{
+
+	unsigned long flags;
+
+	/*
+	 * Do we need to wait for the last update to finish?
+	 */
+
+	/*
+	 * Only the values that we read from the RTC are set. We leave
+	 * tm_wday, tm_yday and tm_isdst untouched. Even though the
+	 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
+	 * by the RTC when initially set to a non-zero value.
+	 */
+	save_flags(flags);
+	cli();
+        rtc->control |= M48T35_RTC_READ;
+	rtc_tm->tm_sec = rtc->sec;
+	rtc_tm->tm_min = rtc->min;
+	rtc_tm->tm_hour = rtc->hour;
+	rtc_tm->tm_mday = rtc->date;
+	rtc_tm->tm_mon = rtc->month;
+	rtc_tm->tm_year = rtc->year;
+	rtc->control &= ~M48T35_RTC_READ;
+	restore_flags(flags);
+
+	BCD_TO_BIN(rtc_tm->tm_sec);
+	BCD_TO_BIN(rtc_tm->tm_min);
+	BCD_TO_BIN(rtc_tm->tm_hour);
+	BCD_TO_BIN(rtc_tm->tm_mday);
+	BCD_TO_BIN(rtc_tm->tm_mon);
+	BCD_TO_BIN(rtc_tm->tm_year);
+
+	/*
+	 * Account for differences between how the RTC uses the values
+	 * and how they are defined in a struct rtc_time;
+	 */
+	if ((rtc_tm->tm_year += (epoch - 1900)) <= 69)
+		rtc_tm->tm_year += 100;
+
+	rtc_tm->tm_mon--;
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/ip27-setup.c linux/arch/mips64/sgi-ip27/ip27-setup.c
--- v2.3.47/linux/arch/mips64/sgi-ip27/ip27-setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/ip27-setup.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,112 @@
+/* $Id: ip27-setup.c,v 1.6 2000/02/05 02:12:32 kanoj Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SGI IP27 specific setup.
+ *
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silcon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/klconfig.h>
+#include <asm/ioc3.h>
+#include <asm/mipsregs.h>
+#include <asm/sn/klconfig.h>
+
+/* Check against user dumbness.  */
+#ifdef CONFIG_VT
+#error CONFIG_VT not allowed for IP27.
+#endif
+
+/*
+ * get_nasid() returns the physical node id number of the caller.
+ */
+nasid_t
+get_nasid(void)
+{
+	return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
+	                 >> NSRI_NODEID_SHFT);
+}
+
+/* Extracted from the IOC3 meta driver.  FIXME.  */
+static inline void ioc3_sio_init(void)
+{
+	struct ioc3 *ioc3;
+	nasid_t nid;
+        long loops;
+
+	nid = get_nasid();
+	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
+
+	ioc3->sscr_a = 0;			/* PIO mode for uarta.  */
+	ioc3->sscr_b = 0;			/* PIO mode for uartb.  */
+	ioc3->sio_iec = ~0;
+	ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT);
+
+	loops=1000000; while(loops--);
+	ioc3->sregs.uarta.iu_fcr = 0;
+	ioc3->sregs.uartb.iu_fcr = 0;
+	loops=1000000; while(loops--);
+}
+
+static inline void ioc3_eth_init(void)
+{
+	struct ioc3 *ioc3;
+	nasid_t nid;
+
+	nid = get_nasid();
+	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
+
+	ioc3->eier = 0;
+}
+
+/* Try to catch kernel missconfigurations and give user an indication what
+   option to select.  */
+static void __init verify_mode(void)
+{
+	int n_mode;
+
+	n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK;
+	printk("Machine is in %c mode.\n", n_mode ? 'N' : 'M');
+#ifdef CONFIG_SGI_SN0_N_MODE
+	if (!n_mode)
+		panic("Kernel compiled for M mode.");
+#else
+	if (n_mode)
+		panic("Kernel compiled for N mode.");
+#endif
+}
+
+void __init ip27_setup(void)
+{
+	nasid_t nid;
+	hubreg_t p, e;
+
+	set_cp0_status(ST0_IM, 0);
+	nid = get_nasid();
+	printk("IP27: Running on node %d.\n", nid);
+
+	p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;
+	e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;
+	printk("Node %d has %s primary CPU%s.\n", nid,
+	       p ? "a" : "no",
+	       e ? ", CPU is running" : "");
+
+	p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;
+	e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;
+	printk("Node %d has %s secondary CPU%s.\n", nid,
+	       p ? "a" : "no",
+	       e ? ", CPU is running" : "");
+
+	verify_mode();
+	ioc3_sio_init();
+	ioc3_eth_init();
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/sgi-ip27/ip27-timer.c linux/arch/mips64/sgi-ip27/ip27-timer.c
--- v2.3.47/linux/arch/mips64/sgi-ip27/ip27-timer.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip27/ip27-timer.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,255 @@
+/* $Id: ip27-timer.c,v 1.3 2000/02/18 09:54:40 ulfc Exp $
+ *
+ * Copytight (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copytight (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#include <linux/timex.h>
+#include <linux/mm.h>		
+
+#include <asm/pgtable.h>
+#include <asm/sgialib.h>
+#include <asm/ioc3.h>
+#include <asm/m48t35.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hub.h>
+
+/* This is a hack; we really need to figure these values out dynamically
+ * 
+ * Since 800 ns works very well with various HUB frequencies, such as
+ * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
+ *
+ * Ralf: which clock rate is used to feed the counter?
+ */
+#define NSEC_PER_CYCLE		800
+#define NSEC_PER_SEC		1000000000
+#define CYCLES_PER_SEC		(NSEC_PER_SEC/NSEC_PER_CYCLE)
+#define CYCLES_PER_JIFFY	(CYCLES_PER_SEC/HZ)
+
+static unsigned long ct_cur;		/* What counter should be at next timer irq */
+static long last_rtc_update = 0;	/* Last time the rtc clock got updated */
+
+extern rwlock_t xtime_lock;
+
+
+static int set_rtc_mmss(unsigned long nowtime)
+{               
+        int retval = 0;
+        int real_seconds, real_minutes, cmos_minutes;
+        unsigned char save_control, save_freq_select;
+	struct m48t35_rtc *rtc;
+	nasid_t nid;
+
+	nid = get_nasid();
+	rtc = (struct m48t35_rtc *)
+	    KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0;
+                
+	rtc->control |= M48T35_RTC_READ;
+	cmos_minutes = rtc->min;
+	BCD_TO_BIN(cmos_minutes);
+	rtc->control &= ~M48T35_RTC_READ;
+         
+        /*      
+         * Since we're only adjusting minutes and seconds,
+         * don't interfere with hour overflow. This avoids
+         * messing with unknown time zones but requires your
+         * RTC not to be off by more than 15 minutes
+         */     
+        real_seconds = nowtime % 60;
+        real_minutes = nowtime / 60;
+        if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+                real_minutes += 30;             /* correct for half hour time zone */           
+        real_minutes %= 60;
+                
+        if (abs(real_minutes - cmos_minutes) < 30) {
+		BIN_TO_BCD(real_seconds);
+		BIN_TO_BCD(real_minutes);
+		rtc->control |= M48T35_RTC_SET;
+                rtc->sec = real_seconds;
+                rtc->min = real_minutes;
+		rtc->control &= ~M48T35_RTC_SET;
+        } else {
+                printk(KERN_WARNING
+                       "set_rtc_mmss: can't update from %d to %d\n",
+                       cmos_minutes, real_minutes);
+                retval = -1;
+        }
+
+                
+        return retval;
+}
+
+void rt_timer_interrupt(struct pt_regs *regs)
+{
+	int irq = 7;				/* XXX Assign number */
+
+	write_lock(&xtime_lock);
+
+again:
+	LOCAL_HUB_S(PI_RT_PEND_A, 0);		/* Ack  */
+	ct_cur += CYCLES_PER_JIFFY;
+	LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur);
+
+	if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur)
+		goto again;
+
+	kstat.irqs[0][irq]++;
+	do_timer(regs);
+	
+        /*
+         * If we have an externally synchronized Linux clock, then update
+         * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+         * called as close as possible to when a second starts.
+         */
+
+        if ((time_status & STA_UNSYNC) == 0 &&
+            xtime.tv_sec > last_rtc_update + 660) {
+		if (xtime.tv_usec >= 1000000 - ((unsigned) tick) / 2) {
+			if (set_rtc_mmss(xtime.tv_sec + 1) == 0)
+				last_rtc_update = xtime.tv_sec;
+			else    
+				last_rtc_update = xtime.tv_sec - 600;
+		} else if (xtime.tv_usec <= ((unsigned) tick) / 2) {
+			if (set_rtc_mmss(xtime.tv_sec) == 0)
+				last_rtc_update = xtime.tv_sec;
+			else    
+				last_rtc_update = xtime.tv_sec - 600;
+		}
+        }
+
+	write_unlock(&xtime_lock);
+}
+
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+
+	read_lock_irqsave(&xtime_lock, flags);
+	*tv = xtime;
+	read_unlock_irqrestore(&xtime_lock, flags);
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq(&xtime_lock);
+	xtime = *tv;
+	time_state = TIME_BAD;
+	time_maxerror = MAXPHASE;
+	time_esterror = MAXPHASE;
+	write_unlock_irq(&xtime_lock);
+}
+
+/* Includes for ioc3_init().  */
+#include <linux/init.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/klconfig.h>
+#include <asm/ioc3.h>
+#include <asm/pci/bridge.h>
+
+/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * WARNING: this function will overflow on 2106-02-07 06:28:16 on
+ * machines were long is 32-bit! (However, as time_t is signed, we
+ * will already get problems at other places on 2038-01-19 03:14:08)
+ */
+static inline unsigned long mktime(unsigned int year, unsigned int mon,
+        unsigned int day, unsigned int hour,
+        unsigned int min, unsigned int sec)
+{       
+        if (0 >= (int) (mon -= 2)) {    /* 1..12 -> 11,12,1..10 */
+                mon += 12;      /* Puts Feb last since it has leap day */
+                year -= 1;
+        }
+        return (((
+            (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
+              year*365 - 719499
+            )*24 + hour /* now have hours */
+           )*60 + min /* now have minutes */
+          )*60 + sec; /* finally seconds */
+}
+
+#define DEBUG_RTC
+
+static unsigned long __init get_m48t35_time(void)
+{       
+        unsigned int year, month, date, hour, min, sec;
+	struct m48t35_rtc *rtc;
+	nasid_t nid;
+
+	nid = get_nasid();
+	rtc = KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0;
+
+        rtc->control |= M48T35_RTC_READ;
+	sec = rtc->sec;
+	min = rtc->min;
+	hour = rtc->hour;
+	date = rtc->date;
+	month = rtc->month;
+	year = rtc->year;
+	rtc->control &= ~M48T35_RTC_READ;
+
+        BCD_TO_BIN(sec);
+        BCD_TO_BIN(min);
+        BCD_TO_BIN(hour);
+        BCD_TO_BIN(date);
+        BCD_TO_BIN(month);
+        BCD_TO_BIN(year);
+
+        year += 1970;
+
+        return mktime(year, month, date, hour, min, sec);
+}
+
+extern void ioc3_eth_init(void);
+
+void __init time_init(void)
+{
+	lboard_t *board;
+	klcpu_t *cpu;
+	int cpuid;
+	
+	xtime.tv_sec = get_m48t35_time();
+	xtime.tv_usec = 0;
+
+	/* Don't use ARCS.  ARCS is fragile.  Klconfig is simple and sane.  */
+	board = find_lboard(KLTYPE_IP27);
+	if (!board)
+		panic("Can't find board info for myself.");
+
+	cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX;
+	cpu = (klcpu_t *) KLCF_COMP(board, cpuid);
+	if (!cpu)
+		panic("No information about myself?");
+
+	printk("CPU clock is %dMHz.\n", cpu->cpu_speed);
+
+	/* Don't worry about second CPU, it's disabled.  */
+	LOCAL_HUB_S(PI_RT_EN_A, 1);
+	LOCAL_HUB_S(PI_PROF_EN_A, 0);
+	ct_cur = CYCLES_PER_JIFFY;
+	LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur);
+	LOCAL_HUB_S(PI_RT_COUNT, 0);
+	LOCAL_HUB_S(PI_RT_PEND_A, 0);
+
+	set_cp0_status(SRB_TIMOCLK, SRB_TIMOCLK);
+}
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/tools/Makefile linux/arch/mips64/tools/Makefile
--- v2.3.47/linux/arch/mips64/tools/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/tools/Makefile	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,29 @@
+# $Id: Makefile,v 1.2 1999/12/04 03:59:01 ralf Exp $
+#
+# Makefile for MIPS kernel build tools.
+#
+# Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+# Copyright (C) 1997, 1999 Ralf Baechle (ralf@gnu.org)
+# Copyright (C) 1999 Silicon Graphics, Inc.
+#
+TARGET	:= $(TOPDIR)/include/asm-$(ARCH)/offset.h
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+all: $(TARGET)
+
+$(TARGET): offset.h
+	cmp -s $^ $@ || (cp $^ $(TARGET).new && mv $(TARGET).new $(TARGET))
+
+offset.h: offset.s
+	sed -n '/^@@@/s///p' $^ >$@
+
+offset.s: offset.c
+
+clean:
+	rm -f offset.[hs] $(TARGET).new
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.47/linux/arch/mips64/tools/offset.c linux/arch/mips64/tools/offset.c
--- v2.3.47/linux/arch/mips64/tools/offset.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/tools/offset.c	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,149 @@
+/* $Id: offset.c,v 1.4 1999/12/04 03:59:01 ralf Exp $
+ *
+ * offset.c: Calculate pt_regs and task_struct offsets.
+ *
+ * Copyright (C) 1996 David S. Miller
+ * Copyright (C) 1997, 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/types.h>
+#include <linux/sched.h>
+
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+
+#define text(t) __asm__("\n@@@" t)
+#define _offset(type, member) (&(((type *)NULL)->member))
+
+#define offset(string, ptr, member) \
+	__asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)))
+#define size(string, size) \
+	__asm__("\n@@@" string "%0" : : "i" (sizeof(size)))
+#define linefeed text("")
+
+text("/* DO NOT TOUCH, AUTOGENERATED BY OFFSET.C */");
+linefeed;
+text("#ifndef _MIPS_OFFSET_H");
+text("#define _MIPS_OFFSET_H");
+linefeed;
+
+void output_ptreg_defines(void)
+{
+	text("/* MIPS pt_regs offsets. */");
+	offset("#define PT_R0     ", struct pt_regs, regs[0]);
+	offset("#define PT_R1     ", struct pt_regs, regs[1]);
+	offset("#define PT_R2     ", struct pt_regs, regs[2]);
+	offset("#define PT_R3     ", struct pt_regs, regs[3]);
+	offset("#define PT_R4     ", struct pt_regs, regs[4]);
+	offset("#define PT_R5     ", struct pt_regs, regs[5]);
+	offset("#define PT_R6     ", struct pt_regs, regs[6]);
+	offset("#define PT_R7     ", struct pt_regs, regs[7]);
+	offset("#define PT_R8     ", struct pt_regs, regs[8]);
+	offset("#define PT_R9     ", struct pt_regs, regs[9]);
+	offset("#define PT_R10    ", struct pt_regs, regs[10]);
+	offset("#define PT_R11    ", struct pt_regs, regs[11]);
+	offset("#define PT_R12    ", struct pt_regs, regs[12]);
+	offset("#define PT_R13    ", struct pt_regs, regs[13]);
+	offset("#define PT_R14    ", struct pt_regs, regs[14]);
+	offset("#define PT_R15    ", struct pt_regs, regs[15]);
+	offset("#define PT_R16    ", struct pt_regs, regs[16]);
+	offset("#define PT_R17    ", struct pt_regs, regs[17]);
+	offset("#define PT_R18    ", struct pt_regs, regs[18]);
+	offset("#define PT_R19    ", struct pt_regs, regs[19]);
+	offset("#define PT_R20    ", struct pt_regs, regs[20]);
+	offset("#define PT_R21    ", struct pt_regs, regs[21]);
+	offset("#define PT_R22    ", struct pt_regs, regs[22]);
+	offset("#define PT_R23    ", struct pt_regs, regs[23]);
+	offset("#define PT_R24    ", struct pt_regs, regs[24]);
+	offset("#define PT_R25    ", struct pt_regs, regs[25]);
+	offset("#define PT_R26    ", struct pt_regs, regs[26]);
+	offset("#define PT_R27    ", struct pt_regs, regs[27]);
+	offset("#define PT_R28    ", struct pt_regs, regs[28]);
+	offset("#define PT_R29    ", struct pt_regs, regs[29]);
+	offset("#define PT_R30    ", struct pt_regs, regs[30]);
+	offset("#define PT_R31    ", struct pt_regs, regs[31]);
+	offset("#define PT_LO     ", struct pt_regs, lo);
+	offset("#define PT_HI     ", struct pt_regs, hi);
+	offset("#define PT_EPC    ", struct pt_regs, cp0_epc);
+	offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr);
+	offset("#define PT_STATUS ", struct pt_regs, cp0_status);
+	offset("#define PT_CAUSE  ", struct pt_regs, cp0_cause);
+	size("#define PT_SIZE   ", struct pt_regs);
+	linefeed;
+}
+
+void output_task_defines(void)
+{
+	text("/* MIPS task_struct offsets. */");
+	offset("#define TASK_STATE         ", struct task_struct, state);
+	offset("#define TASK_FLAGS         ", struct task_struct, flags);
+	offset("#define TASK_SIGPENDING    ", struct task_struct, sigpending);
+	offset("#define TASK_NEED_RESCHED  ", struct task_struct, need_resched);
+	offset("#define TASK_COUNTER       ", struct task_struct, counter);
+	offset("#define TASK_PRIORITY      ", struct task_struct, priority);
+	offset("#define TASK_MM            ", struct task_struct, mm);
+	size("#define TASK_STRUCT_SIZE   ", struct task_struct);
+	linefeed;
+}
+
+void output_thread_defines(void)
+{
+	text("/* MIPS specific thread_struct offsets. */");
+	offset("#define THREAD_REG16   ", struct task_struct, thread.reg16);
+	offset("#define THREAD_REG17   ", struct task_struct, thread.reg17);
+	offset("#define THREAD_REG18   ", struct task_struct, thread.reg18);
+	offset("#define THREAD_REG19   ", struct task_struct, thread.reg19);
+	offset("#define THREAD_REG20   ", struct task_struct, thread.reg20);
+	offset("#define THREAD_REG21   ", struct task_struct, thread.reg21);
+	offset("#define THREAD_REG22   ", struct task_struct, thread.reg22);
+	offset("#define THREAD_REG23   ", struct task_struct, thread.reg23);
+	offset("#define THREAD_REG29   ", struct task_struct, thread.reg29);
+	offset("#define THREAD_REG30   ", struct task_struct, thread.reg30);
+	offset("#define THREAD_REG31   ", struct task_struct, thread.reg31);
+	offset("#define THREAD_STATUS  ", struct task_struct, \
+	       thread.cp0_status);
+	offset("#define THREAD_FPU     ", struct task_struct, thread.fpu);
+	offset("#define THREAD_BVADDR  ", struct task_struct, \
+	       thread.cp0_badvaddr);
+	offset("#define THREAD_BUADDR  ", struct task_struct, \
+	       thread.cp0_baduaddr);
+	offset("#define THREAD_ECODE   ", struct task_struct, \
+	       thread.error_code);
+	offset("#define THREAD_TRAPNO  ", struct task_struct, thread.trap_no);
+	offset("#define THREAD_MFLAGS  ", struct task_struct, thread.mflags);
+	offset("#define THREAD_CURDS   ", struct task_struct, \
+	       thread.current_ds);
+	offset("#define THREAD_TRAMP   ", struct task_struct, \
+	       thread.irix_trampoline);
+	offset("#define THREAD_OLDCTX  ", struct task_struct, \
+	       thread.irix_oldctx);
+	linefeed;
+}
+
+void output_mm_defines(void)
+{
+	text("/* Linux mm_struct offsets. */");
+	offset("#define MM_USERS      ", struct mm_struct, mm_users);
+	offset("#define MM_PGD        ", struct mm_struct, pgd);
+	offset("#define MM_CONTEXT    ", struct mm_struct, context);
+	linefeed;
+}
+
+void output_sc_defines(void)
+{
+	text("/* Linux sigcontext offsets. */");
+	offset("#define SC_REGS       ", struct sigcontext, sc_regs);
+	offset("#define SC_FPREGS     ", struct sigcontext, sc_fpregs);
+	offset("#define SC_MDHI       ", struct sigcontext, sc_mdhi);
+	offset("#define SC_MDLO       ", struct sigcontext, sc_mdlo);
+	offset("#define SC_PC         ", struct sigcontext, sc_pc);
+	offset("#define SC_STATUS     ", struct sigcontext, sc_status);
+	offset("#define SC_OWNEDFP    ", struct sigcontext, sc_ownedfp);
+	offset("#define SC_FPC_CSR    ", struct sigcontext, sc_fpc_csr);
+	offset("#define SC_FPC_EIR    ", struct sigcontext, sc_fpc_eir);
+	offset("#define SC_CAUSE      ", struct sigcontext, sc_cause);
+	offset("#define SC_BADVADDR   ", struct sigcontext, sc_badvaddr);
+	linefeed;
+}
+
+text("#endif /* !(_MIPS_OFFSET_H) */");
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/chrpboot/main.c linux/arch/ppc/chrpboot/main.c
--- v2.3.47/linux/arch/ppc/chrpboot/main.c	Thu Feb 10 17:11:04 2000
+++ linux/arch/ppc/chrpboot/main.c	Tue Feb 22 22:27:43 2000
@@ -10,7 +10,6 @@
 #include "../coffboot/zlib.h"
 #include <asm/bootinfo.h>
 #include <asm/processor.h>
-#define __KERNEL__
 #include <asm/page.h>
 
 extern void *finddevice(const char *);
@@ -49,17 +48,8 @@
     
     printf("chrpboot starting: loaded at 0x%x\n\r", &_start);
 
-    if (initrd_len) {
-	initrd_size = initrd_len;
-	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
-	a1 = initrd_start;
-	a2 = initrd_size;
-	printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n\r", initrd_start,
-	       initrd_data,initrd_size);
-	memcpy((char *)initrd_start, initrd_data, initrd_size);
-	end_avail = (char *)initrd_start;
-    } else
-	end_avail = (char *) RAM_END;
+    end_avail = (char *) RAM_END;
+
     im = image_data;
     len = image_len;
     dst = (void *) PROG_START;
@@ -98,7 +88,7 @@
 	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
 	    
 	    rec->tag = BI_SYSMAP;
-	    rec->data[0] = sysmap_data;
+	    rec->data[0] = (unsigned long)sysmap_data;
 	    rec->data[1] = sysmap_len;
 	    rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
 	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
@@ -129,6 +119,10 @@
 
 void zfree(void *x, void *addr, unsigned nb)
 {
+    nb = (nb + 7) & -8;
+    if (addr == (avail_ram - nb)) {
+	avail_ram -= nb;
+    }
 }
 
 #define HEAD_CRC	2
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/chrpboot/piggyback.c linux/arch/ppc/chrpboot/piggyback.c
--- v2.3.47/linux/arch/ppc/chrpboot/piggyback.c	Mon Jan 12 15:18:13 1998
+++ linux/arch/ppc/chrpboot/piggyback.c	Tue Feb 22 22:27:43 2000
@@ -1,8 +1,9 @@
 #include <stdio.h>
+#include <unistd.h>
 
 extern long ce_exec_config[];
 
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
 {
 	int i, cnt, pos, len;
 	unsigned int cksum, val;
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/coffboot/piggyback.c linux/arch/ppc/coffboot/piggyback.c
--- v2.3.47/linux/arch/ppc/coffboot/piggyback.c	Tue Dec  7 09:32:41 1999
+++ linux/arch/ppc/coffboot/piggyback.c	Tue Feb 22 22:27:43 2000
@@ -1,8 +1,9 @@
 #include <stdio.h>
+#include <unistd.h>
 
 extern long ce_exec_config[];
 
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
 {
 	int i, cnt, pos, len;
 	unsigned int cksum, val;
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v2.3.47/linux/arch/ppc/config.in	Wed Feb 16 17:03:51 2000
+++ linux/arch/ppc/config.in	Tue Feb 22 22:27:43 2000
@@ -47,12 +47,9 @@
 fi
 if [ "$CONFIG_6xx" = "y" ]; then
   choice 'Machine Type'		\
-	"PowerMac	CONFIG_PMAC		\
-	 PReP/MTX	CONFIG_PREP		\
-	 CHRP		CONFIG_CHRP		\
-	 PowerMac/PReP/CHRP	CONFIG_ALL_PPC	\
+	"PowerMac/PReP/MTX/CHRP	CONFIG_ALL_PPC	\
 	 Gemini		CONFIG_GEMINI		\
-	 APUS		CONFIG_APUS"		PowerMac
+	 APUS		CONFIG_APUS"		PowerMac/PReP/MTX/CHRP
 fi
 
 if [ "$CONFIG_PPC64" = "y" ]; then
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/configs/common_defconfig linux/arch/ppc/configs/common_defconfig
--- v2.3.47/linux/arch/ppc/configs/common_defconfig	Sun Feb 13 19:29:03 2000
+++ linux/arch/ppc/configs/common_defconfig	Tue Feb 22 22:27:43 2000
@@ -17,9 +17,6 @@
 # CONFIG_PPC64 is not set
 # CONFIG_82xx is not set
 # CONFIG_8xx is not set
-# CONFIG_PMAC is not set
-# CONFIG_PREP is not set
-# CONFIG_CHRP is not set
 CONFIG_ALL_PPC=y
 # CONFIG_GEMINI is not set
 # CONFIG_APUS is not set
@@ -286,30 +283,29 @@
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_RTL8139 is not set
-# CONFIG_DM9102 is not set
 # CONFIG_AT1700 is not set
 # CONFIG_DEPCA is not set
 # CONFIG_NET_ISA is not set
-CONFIG_NET_EISA=y
+CONFIG_NET_PCI=y
 CONFIG_PCNET32=y
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_AC3200 is not set
 # CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
 CONFIG_DE4X5=y
-# CONFIG_DEC_ELCP is not set
+# CONFIG_TULIP is not set
 # CONFIG_DGRS is not set
-# CONFIG_EEXPRESS_PRO100 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_NE3210 is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO is not set
 # CONFIG_SIS900 is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_ES3210 is not set
 # CONFIG_EPIC100 is not set
-# CONFIG_ZNET is not set
 # CONFIG_NET_POCKET is not set
 
 #
@@ -499,6 +495,7 @@
 # CONFIG_USB_DC2XX is not set
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_DABUSB is not set
+# CONFIG_USB_PLUSB is not set
 
 #
 # USB HID
@@ -508,13 +505,15 @@
 CONFIG_USB_MOUSE=y
 # CONFIG_USB_GRAPHIRE is not set
 # CONFIG_USB_WMFORCE is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_MIX is not set
+# CONFIG_INPUT_MOUSEDEV_DIGITIZER is not set
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 
 #
-# Filesystems
+# File systems
 #
 # CONFIG_QUOTA is not set
 CONFIG_AUTOFS_FS=y
@@ -535,6 +534,7 @@
 # CONFIG_NTFS_FS is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/defconfig linux/arch/ppc/defconfig
--- v2.3.47/linux/arch/ppc/defconfig	Sun Feb 13 19:29:03 2000
+++ linux/arch/ppc/defconfig	Tue Feb 22 22:27:42 2000
@@ -17,9 +17,6 @@
 # CONFIG_PPC64 is not set
 # CONFIG_82xx is not set
 # CONFIG_8xx is not set
-# CONFIG_PMAC is not set
-# CONFIG_PREP is not set
-# CONFIG_CHRP is not set
 CONFIG_ALL_PPC=y
 # CONFIG_GEMINI is not set
 # CONFIG_APUS is not set
@@ -286,30 +283,29 @@
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_RTL8139 is not set
-# CONFIG_DM9102 is not set
 # CONFIG_AT1700 is not set
 # CONFIG_DEPCA is not set
 # CONFIG_NET_ISA is not set
-CONFIG_NET_EISA=y
+CONFIG_NET_PCI=y
 CONFIG_PCNET32=y
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_AC3200 is not set
 # CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
 CONFIG_DE4X5=y
-# CONFIG_DEC_ELCP is not set
+# CONFIG_TULIP is not set
 # CONFIG_DGRS is not set
-# CONFIG_EEXPRESS_PRO100 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_NE3210 is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO is not set
 # CONFIG_SIS900 is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_ES3210 is not set
 # CONFIG_EPIC100 is not set
-# CONFIG_ZNET is not set
 # CONFIG_NET_POCKET is not set
 
 #
@@ -499,6 +495,7 @@
 # CONFIG_USB_DC2XX is not set
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_DABUSB is not set
+# CONFIG_USB_PLUSB is not set
 
 #
 # USB HID
@@ -508,13 +505,15 @@
 CONFIG_USB_MOUSE=y
 # CONFIG_USB_GRAPHIRE is not set
 # CONFIG_USB_WMFORCE is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_MIX is not set
+# CONFIG_INPUT_MOUSEDEV_DIGITIZER is not set
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 
 #
-# Filesystems
+# File systems
 #
 # CONFIG_QUOTA is not set
 CONFIG_AUTOFS_FS=y
@@ -535,6 +534,7 @@
 # CONFIG_NTFS_FS is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile
--- v2.3.47/linux/arch/ppc/kernel/Makefile	Thu Feb 10 17:11:04 2000
+++ linux/arch/ppc/kernel/Makefile	Thu Feb 24 22:43:13 2000
@@ -88,24 +88,14 @@
 ifeq ($(CONFIG_NVRAM),y)
   O_OBJS += pmac_nvram.o
 endif
-ifeq ($(CONFIG_6xx),y)
-  O_OBJS += open_pic.o indirect_pci.o
-endif
-ifeq ($(CONFIG_PPC64),y)
-  O_OBJS += open_pic.o indirect_pci.o
-endif
 ifeq ($(CONFIG_APUS),y)
   O_OBJS += apus_setup.o
 endif
-ifeq ($(CONFIG_PMAC),y)
-  O_OBJS += pmac_pic.o pmac_setup.o pmac_time.o feature.o pmac_pci.o prom.o
-endif
-ifeq ($(CONFIG_CHRP),y)
-  O_OBJS += chrp_pci.o pmac_pci.o chrp_setup.o i8259.o \
-	chrp_time.o pmac_time.o prom.o
-endif
-ifeq ($(CONFIG_PREP),y)
-  O_OBJS += prep_pci.o i8259.o prep_setup.o prep_nvram.o prep_time.o residual.o
+ifeq ($(CONFIG_ALL_PPC),y)
+  O_OBJS += pmac_pic.o pmac_setup.o pmac_time.o feature.o pmac_pci.o prom.o \
+	chrp_setup.o chrp_time.o chrp_pci.o open_pic.o indirect_pci.o \
+	prep_pci.o i8259.o prep_nvram.o prep_time.o residual.o
+  OX_OBJS += prep_setup.o
 endif
 ifeq ($(CONFIG_GEMINI),y)
   O_OBJS += gemini_prom.o gemini_pci.o gemini_setup.o
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/apus_setup.c linux/arch/ppc/kernel/apus_setup.c
--- v2.3.47/linux/arch/ppc/kernel/apus_setup.c	Thu Feb 10 17:11:04 2000
+++ linux/arch/ppc/kernel/apus_setup.c	Tue Feb 22 22:27:43 2000
@@ -10,7 +10,7 @@
  * TODO:
  *  This file needs a *really* good cleanup. Restructure and optimize.
  *  Make sure it can be compiled for non-APUS configs. Begin to move
- *  Amiga specific stuff into linux/machine/amiga.
+ *  Amiga specific stuff into mach/amiga.
  */
 
 #include <linux/config.h>
@@ -27,6 +27,10 @@
 #include <asm/logging.h>
 #endif
 
+/* Needs INITSERIAL call in head.S! */
+#undef APUS_DEBUG
+
+
 #include <linux/ide.h>
 #define T_CHAR          (0x0000)        /* char:  don't touch  */
 #define T_SHORT         (0x4000)        /* short: 12 -> 21     */
@@ -60,37 +64,6 @@
 
 #define num_driveid_types       (sizeof(driveid_types)/sizeof(*driveid_types))
 
-#if 0 /* Get rid of this crud */
-/* Get the IDE stuff from the 68k file */
-#define ide_init_hwif_ports m68k_ide_init_hwif_ports
-#define ide_default_irq m68k_ide_default_irq
-#undef ide_request_irq
-#define ide_request_irq m68k_ide_request_irq
-#undef ide_free_irq
-#define ide_free_irq m68k_ide_free_irq
-#define ide_default_io_base m68k_ide_default_io_base
-#define ide_check_region m68k_ide_check_region
-#define ide_request_region m68k_ide_request_region
-#define ide_release_region m68k_ide_release_region
-#define ide_fix_driveid m68k_ide_fix_driveid
-#define ide_init_default_hwifs m68k_ide_init_default_hwifs
-#define select_t m68k_select_t
-//#include <asm/hdreg.h>
-#include <asm-m68k/ide.h>
-#undef ide_free_irq
-#undef select_t
-#undef ide_request_irq
-#undef ide_init_default_hwifs
-#undef ide_init_hwif_ports
-#undef ide_default_irq
-#undef ide_default_io_base
-#undef ide_check_region
-#undef ide_request_region
-#undef ide_release_region
-#undef ide_fix_driveid
-/*-------------------------------------------*/
-#endif
-
 #include <asm/bootinfo.h>
 #include <asm/setup.h>
 #include <asm/amigahw.h>
@@ -764,6 +737,12 @@
 /****************************************************** IRQ stuff */
 
 __apus
+static unsigned int apus_irq_cannonicalize(unsigned int irq)
+{
+	return irq;
+}
+
+__apus
 int apus_get_irq_list(char *buf)
 {
 #ifdef CONFIG_APUS
@@ -922,6 +901,114 @@
 }
 
 
+/****************************************************** debugging */
+
+/* some serial hardware definitions */
+#define SDR_OVRUN   (1<<15)
+#define SDR_RBF     (1<<14)
+#define SDR_TBE     (1<<13)
+#define SDR_TSRE    (1<<12)
+
+#define AC_SETCLR   (1<<15)
+#define AC_UARTBRK  (1<<11)
+
+#define SER_DTR     (1<<7)
+#define SER_RTS     (1<<6)
+#define SER_DCD     (1<<5)
+#define SER_CTS     (1<<4)
+#define SER_DSR     (1<<3)
+
+static __inline__ void ser_RTSon(void)
+{
+    ciab.pra &= ~SER_RTS; /* active low */
+}
+
+__apus
+int __debug_ser_out( unsigned char c )
+{
+	custom.serdat = c | 0x100;
+	mb();
+	while (!(custom.serdatr & 0x2000))
+		barrier();
+	return 1;
+}
+
+__apus
+unsigned char __debug_ser_in( void )
+{
+	unsigned char c;
+
+	/* XXX: is that ok?? derived from amiga_ser.c... */
+	while( !(custom.intreqr & IF_RBF) )
+		barrier();
+	c = custom.serdatr;
+	/* clear the interrupt, so that another character can be read */
+	custom.intreq = IF_RBF;
+	return c;
+}
+
+__apus
+int __debug_serinit( void )
+{	
+	unsigned long flags;
+	
+	save_flags (flags);
+	cli();
+
+	/* turn off Rx and Tx interrupts */
+	custom.intena = IF_RBF | IF_TBE;
+
+	/* clear any pending interrupt */
+	custom.intreq = IF_RBF | IF_TBE;
+
+	restore_flags (flags);
+
+	/*
+	 * set the appropriate directions for the modem control flags,
+	 * and clear RTS and DTR
+	 */
+	ciab.ddra |= (SER_DTR | SER_RTS);   /* outputs */
+	ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR);  /* inputs */
+	
+#ifdef CONFIG_KGDB
+	/* turn Rx interrupts on for GDB */
+	custom.intena = IF_SETCLR | IF_RBF;
+	ser_RTSon();
+#endif
+
+	return 0;
+}
+
+__apus
+void __debug_print_hex(unsigned long x)
+{
+	int i;
+	char hexchars[] = "0123456789ABCDEF";
+
+	for (i = 0; i < 8; i++) {
+		__debug_ser_out(hexchars[(x >> 28) & 15]);
+		x <<= 4;
+	}
+	__debug_ser_out('\n');
+	__debug_ser_out('\r');
+}
+
+__apus
+void __debug_print_string(char* s)
+{
+	unsigned char c;
+	while((c = *s++))
+		__debug_ser_out(c);
+	__debug_ser_out('\n');
+	__debug_ser_out('\r');
+}
+
+__apus
+static void apus_progress(char *s, unsigned short value)
+{
+	__debug_print_string(s);
+}
+
 /****************************************************** init */
 
 /* The number of spurious interrupts */
@@ -970,7 +1057,7 @@
 	int i;
 
 	for ( i = 0 ; i < NR_IRQS ; i++ )
-		irq_desc[i].ctl = &amiga_irqctrl;
+		irq_desc[i].handler = &amiga_irqctrl;
 
 	for (i = 0; i < NUM_IRQ_NODES; i++)
 		nodes[i].handler = NULL;
@@ -1015,13 +1102,17 @@
 	ppc_md.setup_arch     = apus_setup_arch;
 	ppc_md.setup_residual = NULL;
 	ppc_md.get_cpuinfo    = apus_get_cpuinfo;
-	ppc_md.irq_cannonicalize = NULL;
+	ppc_md.irq_cannonicalize = apus_irq_cannonicalize;
 	ppc_md.init_IRQ       = apus_init_IRQ;
 	ppc_md.get_irq        = apus_get_irq;
 	ppc_md.post_irq       = apus_post_irq;
 #ifdef CONFIG_HEARTBEAT
 	ppc_md.heartbeat      = apus_heartbeat;
 	ppc_md.heartbeat_count = 1;
+#endif
+#ifdef APUS_DEBUG
+	__debug_serinit();
+	ppc_md.progress       = apus_progress;
 #endif
 	ppc_md.init           = NULL;
 
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/entry.S linux/arch/ppc/kernel/entry.S
--- v2.3.47/linux/arch/ppc/kernel/entry.S	Sun Feb 13 19:29:03 2000
+++ linux/arch/ppc/kernel/entry.S	Tue Feb 22 22:27:42 2000
@@ -435,7 +435,7 @@
  * here so it's easy to add arch-specific sections later.
  * -- Cort
  */
-#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_ALL_PPC)
 /*
  * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
  * called with the MMU off.
@@ -475,4 +475,4 @@
 	mtspr	SRR0,r8
 	mtspr	SRR1,r9
 	rfi			/* return to caller */
-#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */
+#endif /* CONFIG_ALL_PPC */
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/hashtable.S linux/arch/ppc/kernel/hashtable.S
--- v2.3.47/linux/arch/ppc/kernel/hashtable.S	Fri Oct 15 15:25:13 1999
+++ linux/arch/ppc/kernel/hashtable.S	Tue Feb 22 22:27:43 2000
@@ -115,11 +115,6 @@
 	stw	r6,0(r2)		/* update PTE (accessed/dirty bits) */
 
 	/* Convert linux-style PTE to low word of PPC-style PTE */
-#ifdef CONFIG_PPC64
-	/* clear the high 32 bits just in case */
-	clrldi	r6,r6,32
-	clrldi	r4,r4,32
-#endif /* CONFIG_PPC64 */
 	rlwinm	r4,r6,32-9,31,31	/* _PAGE_HWWRITE -> PP lsb */
 	rlwimi	r6,r6,32-1,31,31	/* _PAGE_USER -> PP (both bits now) */
 	ori	r4,r4,0xe04		/* clear out reserved bits */
@@ -151,10 +146,6 @@
 	.globl	hash_page_patch_A
 hash_page_patch_A:
 	lis	r4,Hash_base@h		/* base address of hash table */
-#ifdef CONFIG_PPC64
-	/* just in case */
-	clrldi	r4,r4,32
-#endif	
 	rlwimi	r4,r5,32-1,26-Hash_bits,25	/* (VSID & hash_mask) << 6 */
 	rlwinm	r0,r3,32-6,26-Hash_bits,25	/* (PI & hash_mask) << 6 */
 	xor	r4,r4,r0		/* make primary hash */
@@ -169,43 +160,89 @@
 	/* Search the primary PTEG for a PTE whose 1st word matches r5 */
 	mtctr	r2
 	addi	r3,r4,-8
-1:	lwzu	r0,8(r3)		/* get next PTE */
+1:		
+#ifdef CONFIG_PPC64	
+	lwzu	r0,16(r3)		/* get next PTE */
+#else	
+	lwzu	r0,8(r3)		/* get next PTE */
+#endif	
 	cmp	0,r0,r5
 	bdnzf	2,1b			/* loop while ctr != 0 && !cr0.eq */
 	beq+	found_slot
 
 	/* Search the secondary PTEG for a matching PTE */
+#ifdef CONFIG_PPC64
+	ori	r5,r5,0x2		/* set H (secondary hash) bit */
+#else	
 	ori	r5,r5,0x40		/* set H (secondary hash) bit */
+#endif	
 	.globl	hash_page_patch_B
 hash_page_patch_B:
 	xoris	r3,r4,Hash_msk>>16	/* compute secondary hash */
 	xori	r3,r3,0xffc0
+#ifdef CONFIG_PPC64
+	addi	r3,r3,-16
+#else	
 	addi	r3,r3,-8
+#endif	
 	mtctr	r2
-2:	lwzu	r0,8(r3)
+2:
+#ifdef CONFIG_PPC64
+	lwzu	r0,16(r3)
+#else	
+	lwzu	r0,8(r3)
+#endif	
 	cmp	0,r0,r5
 	bdnzf	2,2b
 	beq+	found_slot
+#ifdef CONFIG_PPC64
+	xori	r5,r5,0x2		/* clear H bit again */
+#else	
 	xori	r5,r5,0x40		/* clear H bit again */
+#endif	
 
 	/* Search the primary PTEG for an empty slot */
 10:	mtctr	r2
+#ifdef CONFIG_PPC64
+	addi	r3,r4,-16		/* search primary PTEG */
+#else	
 	addi	r3,r4,-8		/* search primary PTEG */
-1:	lwzu	r0,8(r3)		/* get next PTE */
+#endif	
+1:
+#ifdef CONFIG_PPC64
+	lwzu	r0,16(r3)		/* get next PTE */
+	andi.	r0,r0,1
+#else	
+	lwzu	r0,8(r3)		/* get next PTE */
 	rlwinm.	r0,r0,0,0,0		/* only want to check valid bit */
+#endif	
 	bdnzf	2,1b			/* loop while ctr != 0 && !cr0.eq */
 	beq+	found_empty
 
 	/* Search the secondary PTEG for an empty slot */
+#ifdef CONFIG_PPC64
+	ori	r5,r5,0x2		/* set H (secondary hash) bit */
+#else	
 	ori	r5,r5,0x40		/* set H (secondary hash) bit */
+#endif	
 	.globl	hash_page_patch_C
 hash_page_patch_C:
 	xoris	r3,r4,Hash_msk>>16	/* compute secondary hash */
 	xori	r3,r3,0xffc0
+#ifdef CONFIG_PPC64
+	addi	r3,r3,-16
+#else	
 	addi	r3,r3,-8
+#endif	
 	mtctr	r2
-2:	lwzu	r0,8(r3)
+2:
+#ifdef CONFIG_PPC64
+	lwzu	r0,16(r3)
+	andi.	r0,r0,1
+#else	
+	lwzu	r0,8(r3)
 	rlwinm.	r0,r0,0,0,0		/* only want to check valid bit */
+#endif	
 	bdnzf	2,2b
 	beq+	found_empty
 
@@ -218,12 +255,21 @@
 	 * advantage to putting the PTE in the primary PTEG, we always
 	 * put the PTE in the primary PTEG.
 	 */
+#ifdef CONFIG_PPC64
+	xori	r5,r5,0x2		/* clear H bit again */
+#else
 	xori	r5,r5,0x40		/* clear H bit again */
+#endif		
 	lis	r3,next_slot@ha
 	tophys(r3,r3)
 	lwz	r2,next_slot@l(r3)
+#ifdef CONFIG_PPC64	
+	addi	r2,r2,16
+	andi.	r2,r2,0x78
+#else
 	addi	r2,r2,8
 	andi.	r2,r2,0x38
+#endif	
 	stw	r2,next_slot@l(r3)
 	add	r3,r4,r2
 11:		
@@ -237,9 +283,17 @@
 #ifndef __SMP__
 	/* Store PTE in PTEG */
 found_empty:
+#ifdef CONFIG_PPC64
+	std	r5,0(r3)
+#else		
 	stw	r5,0(r3)
+#endif	
 found_slot:
+#ifdef CONFIG_PPC64
+	std	r6,8(r3)
+#else
 	stw	r6,4(r3)
+#endif	
 	sync
 
 #else /* __SMP__ */
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
--- v2.3.47/linux/arch/ppc/kernel/head.S	Sun Feb 13 19:29:03 2000
+++ linux/arch/ppc/kernel/head.S	Tue Feb 22 22:27:43 2000
@@ -1328,18 +1328,15 @@
 	/* Load the SDR1 register (hash table base & size) */
 	lis	r6,_SDR1@ha
 	tophys(r6,r6)
-#ifdef CONFIG_PPC64	
-	ld	r6,_SDR1@l(r6)
+	lwz	r6,_SDR1@l(r6)
 	mtspr	SDR1,r6
+#ifdef CONFIG_PPC64	
 	/* clear the v bit in the ASR so we can
 	 * behave as if we have segment registers 
 	 * -- Cort
 	 */
 	clrldi	r6,r6,63
 	mtasr	r6
-#else
-	lwz	r6,_SDR1@l(r6)
-	mtspr	SDR1,r6
 #endif /* CONFIG_PPC64 */
 	li	r0,16		/* load up segment register values */
 	mtctr	r0		/* for context 0 */
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- v2.3.47/linux/arch/ppc/kernel/irq.c	Sun Feb 13 19:29:03 2000
+++ linux/arch/ppc/kernel/irq.c	Tue Feb 22 22:27:43 2000
@@ -70,8 +70,6 @@
 
 #define MAXCOUNT 10000000
 
-#define NR_MASK_WORDS	((NR_IRQS + 31) / 32)
-
 irq_desc_t irq_desc[NR_IRQS];
 int ppc_spurious_interrupts = 0;
 unsigned int local_bh_count[NR_CPUS];
@@ -80,7 +78,6 @@
 unsigned int ppc_cached_irq_mask[NR_MASK_WORDS];
 unsigned int ppc_lost_interrupts[NR_MASK_WORDS];
 atomic_t ppc_n_lost_interrupts;
-
 
 /* nasty hack for shared irq's since we need to do kmalloc calls but
  * can't very early in the boot when we need to do a request irq.
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
--- v2.3.47/linux/arch/ppc/kernel/misc.S	Wed Feb 16 17:03:51 2000
+++ linux/arch/ppc/kernel/misc.S	Tue Feb 22 22:27:43 2000
@@ -241,12 +241,21 @@
 	rlwinm	r5,r5,16,16,31
 	cmpi	0,r5,1
 	beqlr				/* for 601, do nothing */
+	li	r4,0x0FFF
+	andc	r3,r3,r4		/* Get page base address */
 	li	r4,4096/CACHE_LINE_SIZE	/* Number of lines in a page */
 	mtctr	r4
+	mr	r6,r3
 0:	dcbst	0,r3			/* Write line to ram */
 	addi	r3,r3,CACHE_LINE_SIZE
 	bdnz	0b
 	sync
+	mtctr	r4
+1:	icbi	0,r6
+	addi	r6,r6,CACHE_LINE_SIZE
+	bdnz	1b
+	sync
+	isync
 	blr
 
 /*
@@ -270,7 +279,7 @@
 	sync
 	isync
 	blr
-
+	
 /*
  * Clear a page using the dcbz instruction, which doesn't cause any
  * memory traffic (except to write out any cache lines which get
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/mk_defs.c linux/arch/ppc/kernel/mk_defs.c
--- v2.3.47/linux/arch/ppc/kernel/mk_defs.c	Wed Feb 16 17:03:51 2000
+++ linux/arch/ppc/kernel/mk_defs.c	Tue Feb 22 22:27:43 2000
@@ -99,6 +99,7 @@
 	DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr));
 	DEFINE(_LINK, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, link));
 	DEFINE(_CCR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ccr));
+	DEFINE(_MQ, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, mq));
 	DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
 	DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
 	DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/pmac_pic.c linux/arch/ppc/kernel/pmac_pic.c
--- v2.3.47/linux/arch/ppc/kernel/pmac_pic.c	Sun Feb 13 19:29:03 2000
+++ linux/arch/ppc/kernel/pmac_pic.c	Tue Feb 22 22:27:43 2000
@@ -39,6 +39,17 @@
 extern int pmac_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
                                       unsigned char offset, unsigned short val);
 
+/*
+ * Mark an irq as "lost".  This is only used on the pmac
+ * since it can lose interrupts (see pmac_set_irq_mask).
+ * -- Cort
+ */
+void __pmac __no_use_set_lost(unsigned long irq_nr)
+{
+	if (!test_and_set_bit(irq_nr, ppc_lost_interrupts))
+		atomic_inc(&ppc_n_lost_interrupts);
+}
+
 static void pmac_openpic_mask_irq(unsigned int irq_nr)
 {
 	openpic_disable_irq(irq_nr);
@@ -105,10 +116,8 @@
          */
         if ((bit & ppc_cached_irq_mask[i])
             && (ld_le32(&pmac_irq_hw[i]->level) & bit)
-            && !(ld_le32(&pmac_irq_hw[i]->flag) & bit)) {
-                if (!test_and_set_bit(irq_nr, ppc_lost_interrupts))
-                        atomic_inc(&ppc_n_lost_interrupts);
-        }
+            && !(ld_le32(&pmac_irq_hw[i]->flag) & bit))
+		__set_lost((ulong)irq_nr);
 }
 
 static void __pmac pmac_mask_irq(unsigned int irq_nr)
@@ -174,6 +183,8 @@
 	unsigned long bits = 0;
 
 #ifdef __SMP__
+	void pmac_smp_message_recv(void);
+	
         /* IPI's are a hack on the powersurge -- Cort */
         if ( smp_processor_id() != 0 )
         {
@@ -182,12 +193,12 @@
 		if (xmon_2nd)
 			xmon(regs);
 #endif
-		smp_message_recv();
+		pmac_smp_message_recv();
 		return -2;	/* ignore, already handled */
         }
 #endif /* __SMP__ */
 
-	/* Yeah, I know, this could be a separate do_IRQ function */
+	/* Yeah, I know, this could be a separate get_irq function */
 	if (has_openpic)
 	{
 		irq = openpic_irq(smp_processor_id());
@@ -376,6 +387,7 @@
 		irqctrler = NULL;
 	}
 
+	int_control.int_set_lost = __no_use_set_lost;
 	/*
 	 * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,
 	 * 1998 G3 Series PowerBooks have 128, 
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/ppc_htab.c linux/arch/ppc/kernel/ppc_htab.c
--- v2.3.47/linux/arch/ppc/kernel/ppc_htab.c	Thu Feb 10 17:11:05 2000
+++ linux/arch/ppc/kernel/ppc_htab.c	Sat Feb 26 20:33:02 2000
@@ -44,17 +44,10 @@
 extern unsigned long pte_misses;
 extern unsigned long pte_errors;
 
-static struct file_operations ppc_htab_operations = {
+struct file_operations ppc_htab_operations = {
 	llseek:		ppc_htab_lseek,
 	read:		ppc_htab_read,
 	write:		ppc_htab_write,
-};
-
-/*
- * proc files can do almost nothing..
- */
-struct inode_operations proc_ppc_htab_inode_operations = {
-    &ppc_htab_operations,  /* default proc file-ops */
 };
 
 /* these will go into processor.h when I'm done debugging -- Cort */
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c
--- v2.3.47/linux/arch/ppc/kernel/ppc_ksyms.c	Wed Feb 16 17:03:51 2000
+++ linux/arch/ppc/kernel/ppc_ksyms.c	Tue Feb 22 22:27:43 2000
@@ -34,6 +34,7 @@
 #include <asm/feature.h>
 #include <asm/dma.h>
 #include <asm/machdep.h>
+#include <asm/hw_irq.h>
 #ifdef __SMP__
 #include <asm/smplock.h>
 #endif /* __SMP__ */
@@ -50,7 +51,6 @@
 extern void ProgramCheckException(struct pt_regs *regs);
 extern void SingleStepException(struct pt_regs *regs);
 extern int sys_sigreturn(struct pt_regs *regs);
-extern atomic_t ppc_n_lost_interrupts;
 extern void do_lost_interrupts(unsigned long);
 extern int do_signal(sigset_t *, struct pt_regs *);
 
@@ -69,6 +69,7 @@
 EXPORT_SYMBOL(SingleStepException);
 EXPORT_SYMBOL(sys_sigreturn);
 EXPORT_SYMBOL(ppc_n_lost_interrupts);
+EXPORT_SYMBOL(ppc_lost_interrupts);
 EXPORT_SYMBOL(do_lost_interrupts);
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
@@ -88,7 +89,7 @@
 EXPORT_SYMBOL(DMA_MODE_READ);
 EXPORT_SYMBOL(DMA_MODE_WRITE);
 #ifndef CONFIG_8xx
-#if defined(CONFIG_PREP) || defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_ALL_PPC)
 EXPORT_SYMBOL(_prep_type);
 EXPORT_SYMBOL(ucSystemType);
 #endif
@@ -125,7 +126,6 @@
 EXPORT_SYMBOL(strstr);
 EXPORT_SYMBOL(strlen);
 EXPORT_SYMBOL(strnlen);
-EXPORT_SYMBOL(strspn);
 EXPORT_SYMBOL(strcmp);
 EXPORT_SYMBOL(strncmp);
 
@@ -227,7 +227,7 @@
 EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
 EXPORT_SYMBOL(pmu_enable_irled);
 #endif CONFIG_PMAC_PBOOK
-#if defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_ALL_PPC)
 EXPORT_SYMBOL(find_devices);
 EXPORT_SYMBOL(find_type_devices);
 EXPORT_SYMBOL(find_compatible_devices);
@@ -243,8 +243,8 @@
 EXPORT_SYMBOL(feature_set);
 EXPORT_SYMBOL(feature_clear);
 EXPORT_SYMBOL(feature_test);
-#endif /* defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC) */
-#if defined(CONFIG_SCSI) && (defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC))
+#endif /* defined(CONFIG_ALL_PPC) */
+#if defined(CONFIG_SCSI) && defined(CONFIG_ALL_PPC)
 EXPORT_SYMBOL(note_scsi_host);
 #endif
 EXPORT_SYMBOL(kd_mksound);
@@ -270,7 +270,6 @@
 EXPORT_SYMBOL(int_control);
 EXPORT_SYMBOL(timer_interrupt_intercept);
 EXPORT_SYMBOL(timer_interrupt);
-extern unsigned long do_IRQ_intercept;
 EXPORT_SYMBOL(do_IRQ_intercept);
 EXPORT_SYMBOL(irq_desc);
 void ppc_irq_dispatch_handler(struct pt_regs *, int);
@@ -278,3 +277,7 @@
 EXPORT_SYMBOL(decrementer_count);
 EXPORT_SYMBOL(get_wchan);
 EXPORT_SYMBOL(console_drivers);
+#ifdef CONFIG_XMON
+EXPORT_SYMBOL(xmon);
+#endif
+EXPORT_SYMBOL(down_read_failed);
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- v2.3.47/linux/arch/ppc/kernel/process.c	Wed Feb 16 17:03:51 2000
+++ linux/arch/ppc/kernel/process.c	Tue Feb 22 22:27:43 2000
@@ -158,7 +158,7 @@
 	if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
 		giveup_altivec(current);
 	else
-		giveup_altivec(NULL):	/* just enable AltiVec for kernel - force */
+		giveup_altivec(NULL);	/* just enable AltiVec for kernel - force */
 #else
 	giveup_altivec(last_task_used_altivec);
 #endif /* __SMP __ */
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
--- v2.3.47/linux/arch/ppc/kernel/prom.c	Sun Feb 13 19:29:03 2000
+++ linux/arch/ppc/kernel/prom.c	Tue Feb 22 22:27:43 2000
@@ -604,7 +604,6 @@
 		/* XXX: hack - don't start cpu 0, this cpu -- Cort */
 		if ( smp_chrp_cpu_nr++ == 0 )
 			continue;
-		RELOC(smp_ibm_chrp_hack) = 1;
 		prom_print(RELOC("starting cpu "));
 		prom_print(path);
 		*(unsigned long *)(0x4) = 0;
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- v2.3.47/linux/arch/ppc/kernel/setup.c	Sun Feb 13 19:29:03 2000
+++ linux/arch/ppc/kernel/setup.c	Sat Feb 26 20:32:13 2000
@@ -733,17 +733,13 @@
 	id->eide_dma_time  = __le16_to_cpu(id->eide_dma_time);
 	id->eide_pio       = __le16_to_cpu(id->eide_pio);
 	id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
-	id->word69         = __le16_to_cpu(id->word69);
-	id->word70         = __le16_to_cpu(id->word70);
-	id->word71         = __le16_to_cpu(id->word71);
-	id->word72         = __le16_to_cpu(id->word72);
-	id->word73         = __le16_to_cpu(id->word73);
-	id->word74         = __le16_to_cpu(id->word74);
+	for (i=0; i<2 i++)
+		id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
+        for (i=0; i<4 i++)
+                id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
 	id->queue_depth	   = __le16_to_cpu(id->queue_depth);
-	id->word76         = __le16_to_cpu(id->word76);
-	id->word77         = __le16_to_cpu(id->word77);
-	id->word78         = __le16_to_cpu(id->word78);
-	id->word79         = __le16_to_cpu(id->word79);
+	for (i=0; i<4 i++)
+		id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
 	id->major_rev_num  = __le16_to_cpu(id->major_rev_num);
 	id->minor_rev_num  = __le16_to_cpu(id->minor_rev_num);
 	id->command_set_1  = __le16_to_cpu(id->command_set_1);
@@ -758,40 +754,14 @@
 	id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);
 	id->word92         = __le16_to_cpu(id->word92);
 	id->hw_config      = __le16_to_cpu(id->hw_config);
-	id->word94         = __le16_to_cpu(id->word94);
-	id->word95         = __le16_to_cpu(id->word95);
-	id->word96         = __le16_to_cpu(id->word96);
-	id->word97         = __le16_to_cpu(id->word97);
-	id->word98         = __le16_to_cpu(id->word98);
-	id->word99         = __le16_to_cpu(id->word99);
-	id->word100        = __le16_to_cpu(id->word100);
-	id->word101        = __le16_to_cpu(id->word101);
-	id->word102        = __le16_to_cpu(id->word102);
-	id->word103        = __le16_to_cpu(id->word103);
-	id->word104        = __le16_to_cpu(id->word104);
-	id->word105        = __le16_to_cpu(id->word105);
-	id->word106        = __le16_to_cpu(id->word106);
-	id->word107        = __le16_to_cpu(id->word107);
-	id->word108        = __le16_to_cpu(id->word108);
-	id->word109        = __le16_to_cpu(id->word109);
-	id->word110        = __le16_to_cpu(id->word110);
-	id->word111        = __le16_to_cpu(id->word111);
-	id->word112        = __le16_to_cpu(id->word112);
-	id->word113        = __le16_to_cpu(id->word113);
-	id->word114        = __le16_to_cpu(id->word114);
-	id->word115        = __le16_to_cpu(id->word115);
-	id->word116        = __le16_to_cpu(id->word116);
-	id->word117        = __le16_to_cpu(id->word117);
-	id->word118        = __le16_to_cpu(id->word118);
-	id->word119        = __le16_to_cpu(id->word119);
-	id->word120        = __le16_to_cpu(id->word120);
-	id->word121        = __le16_to_cpu(id->word121);
-	id->word122        = __le16_to_cpu(id->word122);
-	id->word123        = __le16_to_cpu(id->word123);
-	id->word124        = __le16_to_cpu(id->word124);
-	id->word125        = __le16_to_cpu(id->word125);
-	id->word126        = __le16_to_cpu(id->word126);
+	for (i=0; i<34; i++)
+		id->words94_125[i]  = __le16_to_cpu(id->words94_125[i]);
+	id->last_lun       = __le16_to_cpu(id->last_lun);
 	id->word127        = __le16_to_cpu(id->word127);
-	for (i=0; i<127; i++)
-	        id->reserved[i] = __le16_to_cpu(id->reserved[i]);
+	id->dlf            = __le16_to_cpu(id->dlf);
+	id->csfo           = __le16_to_cpu(id->csfo);
+	for (i=0; i<31; i++)
+		id->words130_159[i] = __le16_to_cpu(id->words130_159[i]);
+	for (i=0; i<97; i++)
+		id->words160_255[i] = __le16_to_cpu(id->words160_255[i]);
 }
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
--- v2.3.47/linux/arch/ppc/kernel/smp.c	Sun Feb 13 19:29:03 2000
+++ linux/arch/ppc/kernel/smp.c	Thu Feb 24 10:11:24 2000
@@ -12,6 +12,7 @@
  * (troy@microux.com, hozer@drgw.net)
  */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
@@ -445,8 +446,10 @@
 	 */
 	if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) )
 		do_openpic_setup_cpu();
+#ifdef CONFIG_GEMINI	
 	if ( _machine == _MACH_gemini )
 		gemini_init_l2();
+#endif
 	while(!smp_commenced)
 		barrier();
 	__sti();
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v2.3.47/linux/arch/ppc/mm/init.c	Sun Feb 13 19:29:03 2000
+++ linux/arch/ppc/mm/init.c	Thu Feb 24 22:43:13 2000
@@ -115,11 +115,7 @@
 PTE *Hash, *Hash_end;
 unsigned long Hash_size, Hash_mask;
 #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
-#ifdef CONFIG_PPC64
-unsigned long long _SDR1;
-#else
 unsigned long _SDR1;
-#endif
 static void hash_init(void);
 
 union ubat {			/* BAT register values to be loaded */
@@ -423,10 +419,9 @@
 	/*
 	 * Is it a candidate for a BAT mapping?
 	 */
-	
 	for (i = 0; i < size; i += PAGE_SIZE)
 		map_page(v+i, p+i, flags);
-out:	
+out:
 	return (void *) (v + (addr & ~PAGE_MASK));
 }
 
@@ -593,7 +588,7 @@
 #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
 static void get_mem_prop(char *, struct mem_pieces *);
 
-#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_ALL_PPC)
 /*
  * Read in a property describing some pieces of memory.
  */
@@ -616,7 +611,7 @@
 	mem_pieces_sort(mp);
 	mem_pieces_coalesce(mp);
 }
-#endif /* CONFIG_PMAC || CONFIG_CHRP || CONFIG_ALL_PPC */
+#endif /* CONFIG_ALL_PPC */
 
 /*
  * Set up one of the I/D BAT (block address translation) register pairs.
@@ -921,10 +916,11 @@
 	if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300);
         hash_init();
 #ifdef CONFIG_PPC64
-	_SDR1 = 0;	/* temporary hack to just use bats -- Cort */
-#else	
+	_SDR1 = __pa(Hash) | (ffz(~Hash_size) - 7)-11;
+#else
         _SDR1 = __pa(Hash) | (Hash_mask >> 10);
-#endif	
+#endif
+	
 	ioremap_base = 0xf8000000;
 
 	if ( ppc_md.progress ) ppc_md.progress("MMU:mapin", 0x301);
@@ -947,7 +943,7 @@
 		setbat(0, 0xf8000000, 0xf8000000, 0x08000000, IO_PAGE);
 #ifdef CONFIG_PPC64
 		/* temporary hack to get working until page tables are stable -- Cort*/
-		setbat(1, 0x80000000, 0xc0000000, 0x10000000, IO_PAGE);
+/*		setbat(1, 0x80000000, 0xc0000000, 0x10000000, IO_PAGE);*/
 		setbat(3, 0xd0000000, 0xd0000000, 0x10000000, IO_PAGE);
 #else
 		setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
@@ -1118,7 +1114,7 @@
 	/*
 	 * All pages are DMA-able so we put them all in the DMA zone.
 	 */
-	zones_size[0] = virt_to_phys(end_of_DRAM) >> PAGE_SHIFT;
+	zones_size[0] = ((unsigned long)end_of_DRAM - KERNELBASE) >> PAGE_SHIFT;
 	for (i = 1; i < MAX_NR_ZONES; i++)
 		zones_size[i] = 0;
 	free_area_init(zones_size);
@@ -1132,9 +1128,9 @@
 	int codepages = 0;
 	int datapages = 0;
 	int initpages = 0;
-#if defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC)	
+#if defined(CONFIG_ALL_PPC)	
 	extern unsigned int rtas_data, rtas_size;
-#endif /* defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC) */
+#endif /* defined(CONFIG_ALL_PPC) */
 	max_mapnr = max_low_pfn;
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 	num_physpages = max_mapnr;	/* RAM is assumed contiguous */
@@ -1150,13 +1146,13 @@
 	}
 #endif /* CONFIG_BLK_DEV_INITRD */
 
-#if defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC)	
+#if defined(CONFIG_ALL_PPC)	
 	/* mark the RTAS pages as reserved */
 	if ( rtas_data )
 		for (addr = rtas_data; addr < PAGE_ALIGN(rtas_data+rtas_size) ;
 		     addr += PAGE_SIZE)
 			SetPageReserved(mem_map + MAP_NR(addr));
-#endif /* defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC) */
+#endif /* defined(CONFIG_ALL_PPC) */
 	if ( sysmap_size )
 		for (addr = (unsigned long)sysmap;
 		     addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ;
@@ -1178,13 +1174,14 @@
 
         printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08x,%08lx]\n",
 	       (unsigned long)nr_free_pages()<< (PAGE_SHIFT-10),
-	       codepages, datapages, initpages,
+	       codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
+	       initpages<< (PAGE_SHIFT-10),
 	       PAGE_OFFSET, (unsigned long) end_of_DRAM);
 	mem_init_done = 1;
 }
 
 #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
-#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_ALL_PPC)
 /*
  * On systems with Open Firmware, collect information about
  * physical RAM and which pieces are already in use.
@@ -1195,9 +1192,13 @@
 unsigned long __init *pmac_find_end_of_memory(void)
 {
 	unsigned long a, total;
-	
-	/* max amount of RAM we allow -- Cort */
-#define RAM_LIMIT (768<<20)
+	unsigned long ram_limit = 0xf0000000 - KERNELBASE;
+	/* allow 0x08000000 for IO space */
+	if ( _machine & (_MACH_prep|_MACH_Pmac) )
+		ram_limit = 0xd8000000 - KERNELBASE;
+#ifdef CONFIG_PPC64
+	ram_limit = 64<<20;
+#endif
 
 	memory_node = find_devices("memory");
 	if (memory_node == NULL) {
@@ -1222,16 +1223,8 @@
 	a = phys_mem.regions[0].address;
 	if (a != 0)
 		panic("RAM doesn't start at physical address 0");
-	/*
-	 * XXX:
-	 * Make sure ram mappings don't stomp on IO space
-	 * This is a temporary hack to keep this from happening
-	 * until we move the KERNELBASE and can allocate RAM up
-	 * to our nearest IO area.
-	 * -- Cort
-	 */
-	if (__max_memory == 0 || __max_memory > RAM_LIMIT)
-		__max_memory = RAM_LIMIT;
+	if (__max_memory == 0 || __max_memory > ram_limit)
+		__max_memory = ram_limit;
 	if (phys_mem.regions[0].size >= __max_memory) {
 		phys_mem.regions[0].size = __max_memory;
 		phys_mem.n_regions = 1;
@@ -1247,12 +1240,11 @@
 
 	set_phys_avail(&phys_mem);
 
-#undef RAM_LIMIT
 	return __va(total);
 }
-#endif /* CONFIG_PMAC || CONFIG_CHRP || CONFIG_ALL_PPC */
+#endif /* CONFIG_ALL_PPC */
 
-#if defined(CONFIG_PREP) || defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_ALL_PPC)
 /*
  * This finds the amount of physical ram and does necessary
  * setup for prep.  This is pretty architecture specific so
@@ -1279,7 +1271,7 @@
 
 	return (__va(total));
 }
-#endif /* defined(CONFIG_PREP) || defined(CONFIG_ALL_PPC) */
+#endif /* defined(CONFIG_ALL_PPC) */
 
 
 #if defined(CONFIG_GEMINI)
@@ -1389,16 +1381,12 @@
 	 * up to a maximum of 2MB.
 	 */
 	ramsize = (ulong)end_of_DRAM - KERNELBASE;
-#ifdef CONFIG_PPC64	
-	Hash_mask = 0;
-	for (h = 256<<10; h < ramsize / 256 && h < 4<<20; h *= 2, Hash_mask++)
-		;
-	Hash_size = h;
-	Hash_mask <<= 10;  /* so setting _SDR1 works the same -- Cort */
-#else
 	for (h = 64<<10; h < ramsize / 256 && h < 2<<20; h *= 2)
 		;
 	Hash_size = h;
+#ifdef CONFIG_PPC64
+	Hash_mask = (h >> 7) - 1;
+#else	
 	Hash_mask = (h >> 6) - 1;
 #endif	
 	
@@ -1433,7 +1421,11 @@
 		/*
 		 * Patch up the instructions in head.S:hash_page
 		 */
+#ifdef CONFIG_PPC64		
+		Hash_bits = ffz(~Hash_size) - 7;
+#else
 		Hash_bits = ffz(~Hash_size) - 6;
+#endif		
 		hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff)
 			| (__pa(Hash) >> 16);
 		hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0)
@@ -1443,9 +1435,17 @@
 		hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0)
 			| ((26 - Hash_bits) << 6);
 		hash_page_patch_B[0] = (hash_page_patch_B[0] & ~0xffff)
+#ifdef CONFIG_PPC64			
+			| (Hash_mask >> 11);
+#else
 			| (Hash_mask >> 10);
+#endif		
 		hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff)
+#ifdef CONFIG_PPC64			
+			| (Hash_mask >> 11);
+#else
 			| (Hash_mask >> 10);
+#endif		
 #if 0	/* see hash_page in head.S, note also patch_C ref below */
 		hash_page_patch_D[0] = (hash_page_patch_D[0] & ~0xffff)
 			| (Hash_mask >> 10);
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/mm/mem_pieces.c linux/arch/ppc/mm/mem_pieces.c
--- v2.3.47/linux/arch/ppc/mm/mem_pieces.c	Tue Jan 11 22:31:38 2000
+++ linux/arch/ppc/mm/mem_pieces.c	Tue Feb 22 22:27:43 2000
@@ -127,7 +127,7 @@
 	printk("\n");
 }
 
-#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC)
 /*
  * Add some memory to an array of pieces
  */
diff -u --recursive --new-file v2.3.47/linux/arch/ppc/xmon/xmon.c linux/arch/ppc/xmon/xmon.c
--- v2.3.47/linux/arch/ppc/xmon/xmon.c	Thu Feb 10 17:11:05 2000
+++ linux/arch/ppc/xmon/xmon.c	Tue Feb 22 22:27:43 2000
@@ -75,11 +75,14 @@
 static unsigned read_spr(int);
 static void write_spr(int, unsigned);
 static void super_regs(void);
+static void print_sysmap(void);
 static void remove_bpts(void);
 static void insert_bpts(void);
 static struct bpt *at_breakpoint(unsigned pc);
 static void bpt_cmds(void);
 static void cacheflush(void);
+static char *pretty_lookup_name(unsigned long addr);
+static char *lookup_name(unsigned long addr);
 
 extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned);
 extern void printf(const char *fmt, ...);
@@ -101,6 +104,7 @@
   mm	move a block of memory\n\
   ms	set a block of memory\n\
   md	compare two blocks of memory\n\
+  M	print System.map\n\
   r	print registers\n\
   S	print special registers\n\
   t	print backtrace\n\
@@ -337,6 +341,8 @@
 			else
 				excprint(excp);
 			break;
+		case 'M':
+			print_sysmap();
 		case 'S':
 			super_regs();
 			break;
@@ -514,8 +520,10 @@
 void
 excprint(struct pt_regs *fp)
 {
-	printf("vector: %x at pc = %x, msr = %x, sp = %x [%x]\n",
-	       fp->trap, fp->nip, fp->msr, fp->gpr[1], fp);
+	printf("vector: %x at pc = %x %s",
+	       fp->trap, fp->nip,/* pretty_lookup_name(fp->nip)*/"");
+	printf(", msr = %x, sp = %x [%x]\n",
+	       fp->msr, fp->gpr[1], fp);
 	if (fp->trap == 0x300 || fp->trap == 0x600)
 		printf("dar = %x, dsisr = %x\n", fp->dar, fp->dsisr);
 	if (current)
@@ -597,6 +605,14 @@
 extern char dec_exc;
 
 void
+print_sysmap(void)
+{
+	extern char *sysmap;
+	if ( sysmap )
+		printf("System.map: \n%s", sysmap);
+}
+
+void
 super_regs()
 {
 	int i, cmd;
@@ -1345,9 +1361,26 @@
 	lineptr = str;
 }
 
+/*
+ * We use this array a lot here.  We assume we don't have multiple
+ * instances of xmon running and that we don't use the return value of
+ * any functions other than printing them.
+ *  -- Cort
+ */
 char last[64];
-char *
-lookup_addr(unsigned long addr)
+static char *pretty_lookup_name(unsigned long addr)
+{
+	if ( lookup_name(addr) )
+	{
+		sprintf(last, " (%s)", lookup_name(addr));
+		return last;
+	}
+	else
+		return NULL;
+}
+
+
+static char *lookup_name(unsigned long addr)
 {
 	extern char *sysmap;
 	extern unsigned long sysmap_size;
@@ -1357,10 +1390,6 @@
 	if ( !sysmap || !sysmap_size )
 		return NULL;
 	
-	/* adjust if addr is relative to kernelbase */
-	if ( addr < PAGE_OFFSET )
-		addr += PAGE_OFFSET;
-
 	cmp = simple_strtoul(c, &c, 8);
 	strcpy( last, strsep( &c, "\n"));
 	while ( c < (sysmap+sysmap_size) )
@@ -1372,3 +1401,4 @@
 	}
 	return last;
 }
+
diff -u --recursive --new-file v2.3.47/linux/arch/sparc/boot/Makefile linux/arch/sparc/boot/Makefile
--- v2.3.47/linux/arch/sparc/boot/Makefile	Tue Oct 27 09:52:20 1998
+++ linux/arch/sparc/boot/Makefile	Sat Feb 26 20:46:44 2000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.9 1998/10/26 20:01:03 davem Exp $
+# $Id: Makefile,v 1.10 2000/02/23 08:17:46 jj Exp $
 # Makefile for the Sparc boot stuff.
 #
 # Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -22,16 +22,20 @@
 clean:
 	rm -f btfixupprep piggyback tftpboot.img btfix.o btfix.s
 
-BTOBJS := $(HEAD) init/main.o init/version.o \
-	$(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
-	$(NETWORKS) $(DRIVERS)
+BTOBJS := $(HEAD) init/main.o init/version.o
+BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
+	$(DRIVERS) $(NETWORKS)
 
 # I wanted to make this depend upon BTOBJS so that a parallel
 # build would work, but this fails because $(HEAD) cannot work
 # properly as it will cause head.o to be built with the implicit
 # rules not the ones in kernel/Makefile.  Someone please fix. --DaveM
 vmlinux.o: dummy
-	$(LD) -r $(patsubst %,$(TOPDIR)/%,$(BTOBJS)) $(LIBS) -o vmlinux.o
+	$(LD) -r $(patsubst %,$(TOPDIR)/%,$(BTOBJS)) \
+		--start-group \
+		$(patsubst %,$(TOPDIR)/%,$(BTLIBS)) \
+		$(LIBS) \
+		--end-group -o vmlinux.o
 
 btfix.s: btfixupprep vmlinux.o
 	$(OBJDUMP) -x vmlinux.o | ./btfixupprep > btfix.s
diff -u --recursive --new-file v2.3.47/linux/arch/sparc/kernel/ioport.c linux/arch/sparc/kernel/ioport.c
--- v2.3.47/linux/arch/sparc/kernel/ioport.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/sparc/kernel/ioport.c	Sat Feb 26 20:33:02 2000
@@ -695,42 +695,6 @@
 	return p-buf;
 }
 
-static struct proc_dir_entry _sparc_iomap_proc_entry = {
-	0,                      /* Inode number - dynamic */
-	6,                      /* Length of the file name */
-	"io_map",		/* The file name */
-	S_IFREG | S_IRUGO,      /* File mode */
-	1,                      /* Number of links */
-	0, 0,                   /* The uid and gid for the file */
-	0,                      /* The size of the file reported by ls. */
-	NULL,                   /* struct inode_operations * ops */
-	NULL,			/* get_info: backward compatibility */
-	NULL,			/* owner */
-	NULL, NULL, NULL,	/* linkage */
-	&sparc_iomap,
-	_sparc_io_get_info,	/* The read function for this file */
-	NULL,
-	/* and more stuff */
-};
-
-static struct proc_dir_entry _sparc_dvma_proc_entry = {
-	0,                      /* Inode number - dynamic */
-	8,			/* Length of the file name */
-	"dvma_map",		/* The file name */
-	S_IFREG | S_IRUGO,      /* File mode */
-	1,                      /* Number of links */
-	0, 0,                   /* The uid and gid for the file */
-	0,                      /* The size of the file reported by ls. */
-	NULL,                   /* struct inode_operations * ops */
-	NULL,			/* get_info: backward compatibility */
-	NULL,			/* owner */
-	NULL, NULL, NULL,	/* linkage */
-	&_sparc_dvma,
-	_sparc_io_get_info,
-	NULL,
-	/* some more stuff */
-};
-
 #endif CONFIG_PROC_FS
 
 /*
@@ -782,7 +746,7 @@
 	};
 
 #ifdef CONFIG_PROC_FS
-	proc_register(&proc_root, &_sparc_iomap_proc_entry);
-	proc_register(&proc_root, &_sparc_dvma_proc_entry);
+	create_proc_read_entry("io_map",0,0,_sparc_io_get_info,&sparc_iomap);
+	create_proc_read_entry("dvma_map",0,0,_sparc_io_get_info,&_sparc_dvma);
 #endif
 }
diff -u --recursive --new-file v2.3.47/linux/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c
--- v2.3.47/linux/arch/sparc/kernel/irq.c	Thu Feb 10 17:11:05 2000
+++ linux/arch/sparc/kernel/irq.c	Sat Feb 26 20:46:44 2000
@@ -1,4 +1,4 @@
-/*  $Id: irq.c,v 1.101 2000/02/09 11:15:03 davem Exp $
+/*  $Id: irq.c,v 1.102 2000/02/25 05:44:35 davem Exp $
  *  arch/sparc/kernel/irq.c:  Interrupt request handling routines. On the
  *                            Sparc the IRQ's are basically 'cast in stone'
  *                            and you are supposed to probe the prom's device
@@ -712,4 +712,9 @@
 		break;
 	}
 	btfixup();
+}
+
+void init_irq_proc(void)
+{
+	/* For now, nothing... */
 }
diff -u --recursive --new-file v2.3.47/linux/arch/sparc/kernel/setup.c linux/arch/sparc/kernel/setup.c
--- v2.3.47/linux/arch/sparc/kernel/setup.c	Tue Feb  1 01:35:43 2000
+++ linux/arch/sparc/kernel/setup.c	Sat Feb 26 20:46:44 2000
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.114 2000/01/29 01:08:57 anton Exp $
+/*  $Id: setup.c,v 1.115 2000/02/26 04:24:31 davem Exp $
  *  linux/arch/sparc/kernel/setup.c
  *
  *  Copyright (C) 1995  David S. Miller (davem@caip.rutgers.edu)
@@ -294,6 +294,8 @@
 	"PROM", prom_cons_write, 0, 0, 0, 0, 0, CON_PRINTBUFFER, 0, 0, 0
 };
 
+extern void paging_init(void);
+
 void __init setup_arch(char **cmdline_p)
 {
 	int i;
@@ -478,6 +480,8 @@
 
 	if (serial_console)
 		conswitchp = NULL;
+
+	paging_init();
 }
 
 asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
diff -u --recursive --new-file v2.3.47/linux/arch/sparc/kernel/sparc_ksyms.c linux/arch/sparc/kernel/sparc_ksyms.c
--- v2.3.47/linux/arch/sparc/kernel/sparc_ksyms.c	Sun Feb 20 21:12:38 2000
+++ linux/arch/sparc/kernel/sparc_ksyms.c	Sat Feb 26 20:46:44 2000
@@ -1,4 +1,4 @@
-/* $Id: sparc_ksyms.c,v 1.91 2000/02/18 20:23:24 davem Exp $
+/* $Id: sparc_ksyms.c,v 1.93 2000/02/26 11:02:45 anton Exp $
  * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -92,7 +92,6 @@
 
 /* used by various drivers */
 EXPORT_SYMBOL(sparc_cpu_model);
-EXPORT_SYMBOL_PRIVATE(_spinlock_waitfor);
 EXPORT_SYMBOL(kernel_thread);
 #ifdef SPIN_LOCK_DEBUG
 EXPORT_SYMBOL(_do_spin_lock);
@@ -246,7 +245,6 @@
 EXPORT_SYMBOL(strpbrk);
 EXPORT_SYMBOL(strtok);
 EXPORT_SYMBOL(strstr);
-EXPORT_SYMBOL(strspn);
 
 /* Special internal versions of library functions. */
 EXPORT_SYMBOL(__copy_1page);
diff -u --recursive --new-file v2.3.47/linux/arch/sparc/lib/locks.S linux/arch/sparc/lib/locks.S
--- v2.3.47/linux/arch/sparc/lib/locks.S	Tue Oct 27 09:52:20 1998
+++ linux/arch/sparc/lib/locks.S	Sat Feb 26 20:46:44 2000
@@ -1,4 +1,4 @@
-/* $Id: locks.S,v 1.15 1998/10/14 09:18:55 jj Exp $
+/* $Id: locks.S,v 1.16 2000/02/26 11:02:47 anton Exp $
  * locks.S: SMP low-level lock primitives on Sparc.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -14,25 +14,6 @@
 
 	.text
 	.align	4
-
-	/* This is called when the initial acquisition attempt of a spin
-	 * lock fails.  The calling convention is weird, return address
-	 * is in %o7 as usual but we agree with the caller to only touch
-	 * and use %g2 as a temporary.  We are passed a ptr to the lock
-	 * itself in %g1, %g4 must be restored into %o7 when we return,
-	 * and the caller wants us to return to him at three instructions
-	 * previous to the call instruction which got us here.  See how
-	 * this is used in asm/spinlock.h if what I just said confuses
-	 * you to no end.
-	 */
-	.globl	___spinlock_waitfor
-___spinlock_waitfor:
-1:	orcc	%g2, 0x0, %g0
-	bne,a	1b
-	 ldub	[%g1], %g2
-	ldstub	[%g1], %g2
-	jmpl	%o7 - 12, %g0
-	 mov	%g4, %o7
 
 	/* Read/writer locks, as usual this is overly clever to make it
 	 * as fast as possible.
diff -u --recursive --new-file v2.3.47/linux/arch/sparc/mm/init.c linux/arch/sparc/mm/init.c
--- v2.3.47/linux/arch/sparc/mm/init.c	Thu Feb 10 17:11:05 2000
+++ linux/arch/sparc/mm/init.c	Sat Feb 26 20:46:44 2000
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.80 2000/02/09 21:11:06 davem Exp $
+/*  $Id: init.c,v 1.81 2000/02/26 11:59:31 anton Exp $
  *  linux/arch/sparc/mm/init.c
  *
  *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -40,7 +40,7 @@
 struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
 unsigned long sparc_unmapped_base;
 
-struct pgtable_cache_struct pgt_quicklists;
+struct pgtable_cache_struct pgt_quicklists = { 0, 0, 0, 0, SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED };
 
 /* References to section boundaries */
 extern char __init_begin, __init_end, _start, end, etext , edata;
diff -u --recursive --new-file v2.3.47/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.3.47/linux/arch/sparc64/defconfig	Sun Feb 20 21:12:38 2000
+++ linux/arch/sparc64/defconfig	Sat Feb 26 20:46:44 2000
@@ -273,9 +273,9 @@
 CONFIG_SUNQE=m
 CONFIG_DE4X5=m
 CONFIG_VORTEX=m
-CONFIG_RTL8139=m
+CONFIG_8139TOO=m
 CONFIG_NE2K_PCI=m
-CONFIG_EEXPRESS_PRO100=m
+CONFIG_EEPRO100=m
 CONFIG_ADAPTEC_STARFIRE=m
 
 #
@@ -299,7 +299,7 @@
 # CONFIG_VIDEO_BT848 is not set
 
 #
-# Filesystems
+# File systems
 #
 # CONFIG_QUOTA is not set
 CONFIG_AUTOFS_FS=m
diff -u --recursive --new-file v2.3.47/linux/arch/sparc64/kernel/irq.c linux/arch/sparc64/kernel/irq.c
--- v2.3.47/linux/arch/sparc64/kernel/irq.c	Sat Feb 12 11:22:10 2000
+++ linux/arch/sparc64/kernel/irq.c	Sat Feb 26 20:46:44 2000
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.83 2000/02/11 06:57:17 jj Exp $
+/* $Id: irq.c,v 1.84 2000/02/25 05:44:41 davem Exp $
  * irq.c: UltraSparc IRQ handling/init/registry.
  *
  * Copyright (C) 1997  David S. Miller  (davem@caip.rutgers.edu)
@@ -1155,4 +1155,9 @@
 			     : /* No outputs */
 			     : "i" (PSTATE_IE)
 			     : "g1");
+}
+
+void init_irq_proc(void)
+{
+	/* For now, nothing... */
 }
diff -u --recursive --new-file v2.3.47/linux/arch/sparc64/kernel/setup.c linux/arch/sparc64/kernel/setup.c
--- v2.3.47/linux/arch/sparc64/kernel/setup.c	Wed Dec 29 13:13:14 1999
+++ linux/arch/sparc64/kernel/setup.c	Sat Feb 26 20:46:44 2000
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.50 1999/12/01 10:44:45 davem Exp $
+/*  $Id: setup.c,v 1.51 2000/02/26 04:24:32 davem Exp $
  *  linux/arch/sparc64/kernel/setup.c
  *
  *  Copyright (C) 1995,1996  David S. Miller (davem@caip.rutgers.edu)
@@ -451,6 +451,8 @@
 		   "' linux-.soft2 to .soft2");
 }
 
+extern void paging_init(void);
+
 void __init setup_arch(char **cmdline_p)
 {
 	extern int serial_console;  /* in console.c, of course */
@@ -587,6 +589,8 @@
 #endif
 	if (serial_console)
 		conswitchp = NULL;
+
+	paging_init();
 }
 
 asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
diff -u --recursive --new-file v2.3.47/linux/arch/sparc64/kernel/signal32.c linux/arch/sparc64/kernel/signal32.c
--- v2.3.47/linux/arch/sparc64/kernel/signal32.c	Fri Jan 28 15:09:07 2000
+++ linux/arch/sparc64/kernel/signal32.c	Sat Feb 26 20:46:44 2000
@@ -1,4 +1,4 @@
-/*  $Id: signal32.c,v 1.59 2000/01/21 11:38:52 jj Exp $
+/*  $Id: signal32.c,v 1.60 2000/02/25 06:02:37 jj Exp $
  *  arch/sparc64/kernel/signal32.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
@@ -126,6 +126,8 @@
 			err |= __put_user(from->si_pid, &to->si_pid);
 			err |= __put_user(from->si_uid, &to->si_uid);
 			break;
+		case SIGURG:
+		case SIGIO:
 		case SIGSEGV:
 		case SIGILL:
 		case SIGFPE:
diff -u --recursive --new-file v2.3.47/linux/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c
--- v2.3.47/linux/arch/sparc64/kernel/sparc64_ksyms.c	Thu Feb 10 17:11:06 2000
+++ linux/arch/sparc64/kernel/sparc64_ksyms.c	Mon Feb 21 16:32:27 2000
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.74 2000/02/09 11:15:07 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.75 2000/02/21 15:50:08 davem Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -261,7 +261,6 @@
 EXPORT_SYMBOL(strpbrk);
 EXPORT_SYMBOL(strtok);
 EXPORT_SYMBOL(strstr);
-EXPORT_SYMBOL(strspn);
 
 #ifdef CONFIG_SOLARIS_EMUL_MODULE
 EXPORT_SYMBOL(getname32);
diff -u --recursive --new-file v2.3.47/linux/arch/sparc64/lib/VIScsum.S linux/arch/sparc64/lib/VIScsum.S
--- v2.3.47/linux/arch/sparc64/lib/VIScsum.S	Mon Aug  2 22:07:16 1999
+++ linux/arch/sparc64/lib/VIScsum.S	Mon Feb 21 16:32:27 2000
@@ -1,14 +1,15 @@
-/* $Id: VIScsum.S,v 1.5 1999/07/30 09:35:36 davem Exp $
+/* $Id: VIScsum.S,v 1.6 2000/02/20 23:21:39 davem Exp $
  * VIScsum.S: High bandwidth IP checksumming utilizing the UltraSparc
  *            Visual Instruction Set.
  *
  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 2000 David S. Miller (davem@redhat.com)
  *
  * Based on older sparc32/sparc64 checksum.S, which is:
  *
  *      Copyright(C) 1995 Linus Torvalds
  *      Copyright(C) 1995 Miguel de Icaza
- *      Copyright(C) 1996,1997 David S. Miller
+ *      Copyright(C) 1996, 1997 David S. Miller
  *    derived from:
  *	  Linux/Alpha checksum c-code
  *        Linux/ix86 inline checksum assembly
@@ -38,290 +39,290 @@
  * tricks are UltraLinux trade secrets :))
  */
 
-#define START_THE_TRICK(fz,f0,f2,f4,f6,f8,f10)							\
-	fcmpgt32	%fz, %f0, %g1		/*  FPM		Group			*/;	\
-	fcmpgt32	%fz, %f2, %g2		/*  FPM		Group			*/;	\
-	fcmpgt32	%fz, %f4, %g3		/*  FPM		Group			*/;	\
-	fcmpgt32	%fz, %f6, %g5		/*  FPM		Group			*/;	\
-	inc		%g1			/*  IEU0				*/;	\
-	fcmpgt32	%fz, %f8, %g7		/*  FPM		Group			*/;	\
-	srl		%g1, 1, %g1		/*  IEU0				*/;	\
-	inc		%g2			/*  IEU1				*/;	\
-	fcmpgt32	%fz, %f10, %o3		/*  FPM		Group			*/;	\
-	srl		%g2, 1, %g2		/*  IEU0				*/;	\
-	add		%o2, %g1, %o2		/*  IEU1				*/;	\
-	add		%g3, 1, %g3		/*  IEU0	Group			*/;	\
-	srl		%g3, 1, %g3		/*  IEU0	Group			*/;	\
-	add		%o2, %g2, %o2		/*  IEU1				*/;	\
-	inc		%g5			/*  IEU0	Group			*/;	\
-	add		%o2, %g3, %o2		/*  IEU1				*/;
+#define START_THE_TRICK(fz,f0,f2,f4,f6,f8,f10)						\
+	fcmpgt32	%fz, %f0, %g1		/*  FPM		Group	*/;		\
+	fcmpgt32	%fz, %f2, %g2		/*  FPM		Group	*/;		\
+	fcmpgt32	%fz, %f4, %g3		/*  FPM		Group	*/;		\
+	inc		%g1			/*  IEU0	Group	*/;		\
+	fcmpgt32	%fz, %f6, %g5		/*  FPM			*/;		\
+	srl		%g1, 1, %g1		/*  IEU0	Group	*/;		\
+	fcmpgt32	%fz, %f8, %g7		/*  FPM			*/;		\
+	inc		%g2			/*  IEU0	Group	*/;		\
+	fcmpgt32	%fz, %f10, %o3		/*  FPM			*/;		\
+	srl		%g2, 1, %g2		/*  IEU0	Group	*/;		\
+	inc		%g3			/*  IEU1		*/;		\
+	srl		%g3, 1, %g3		/*  IEU0	Group	*/;		\
+	add		%o2, %g1, %o2		/*  IEU1		*/;		\
+	add		%o2, %g2, %o2		/*  IEU0	Group	*/;		\
+	inc		%g5			/*  IEU1		*/;		\
+	add		%o2, %g3, %o2		/*  IEU0	Group	*/;
 
-#define DO_THE_TRICK(O12,O14,f0,f2,f4,f6,f8,f10,f12,f14,F0,F2,F4,F6,F8,F10,F12,F14)		\
-	fcmpgt32	%O12, %f12, %o4		/*  FPM		Group			*/;	\
-	srl		%g5, 1, %g5		/*  IEU0				*/;	\
-	inc		%g7			/*  IEU1				*/;	\
-	fpadd32		%F0, %f0, %F0		/*  FPA					*/;	\
-	fcmpgt32	%O14, %f14, %o5		/*  FPM		Group			*/;	\
-	srl		%g7, 1, %g7		/*  IEU0				*/;	\
-	add		%o2, %g5, %o2		/*  IEU1				*/;	\
-	fpadd32		%F2, %f2, %F2		/*  FPA					*/;	\
-	inc		%o3			/*  IEU0	Group			*/;	\
-	add		%o2, %g7, %o2		/*  IEU1				*/;	\
-	fcmpgt32	%f0, %F0, %g1		/*  FPM		Group			*/;	\
-	srl		%o3, 1, %o3		/*  IEU0				*/;	\
-	inc		%o4			/*  IEU1				*/;	\
-	fpadd32		%F4, %f4, %F4		/*  FPA					*/;	\
-	fcmpgt32	%f2, %F2, %g2		/*  FPM		Group			*/;	\
-	srl		%o4, 1, %o4		/*  IEU0				*/;	\
-	add		%o2, %o3, %o2		/*  IEU1				*/;	\
-	fpadd32		%F6, %f6, %F6		/*  FPA					*/;	\
-	inc		%o5			/*  IEU0	Group			*/;	\
-	add		%o2, %o4, %o2		/*  IEU1				*/;	\
-	fcmpgt32	%f4, %F4, %g3		/*  FPM		Group			*/;	\
-	srl		%o5, 1, %o5		/*  IEU0				*/;	\
-	inc		%g1			/*  IEU1				*/;	\
-	fpadd32		%F8, %f8, %F8		/*  FPA					*/;	\
-	fcmpgt32	%f6, %F6, %g5		/*  FPM		Group			*/;	\
-	srl		%g1, 1, %g1		/*  IEU0				*/;	\
-	add		%o2, %o5, %o2		/*  IEU1				*/;	\
-	fpadd32		%F10, %f10, %F10	/*  FPA					*/;	\
-	inc		%g2			/*  IEU0	Group			*/;	\
-	add		%o2, %g1, %o2		/*  IEU1				*/;	\
-	fcmpgt32	%f8, %F8, %g7		/*  FPM		Group			*/;	\
-	srl		%g2, 1, %g2		/*  IEU0				*/;	\
-	inc		%g3			/*  IEU1				*/;	\
-	fpadd32		%F12, %f12, %F12	/*  FPA					*/;	\
-	fcmpgt32	%f10, %F10, %o3		/*  FPM		Group			*/;	\
-	srl		%g3, 1, %g3		/*  IEU0				*/;	\
-	add		%o2, %g2, %o2		/*  IEU1				*/;	\
-	fpadd32		%F14, %f14, %F14	/*  FPA					*/;	\
-	inc		%g5			/*  IEU0	Group			*/;	\
-	add		%o2, %g3, %o2		/*  IEU1				*/;
+#define DO_THE_TRICK(O12,O14,f0,f2,f4,f6,f8,f10,f12,f14,F0,F2,F4,F6,F8,F10,F12,F14)	\
+	srl		%g5, 1, %g5		/*  IEU0	Group	*/;		\
+	fpadd32		%F0, %f0, %F0		/*  FPA			*/;		\
+	fcmpgt32	%O12, %f12, %o4		/*  FPM			*/;		\
+	inc		%g7			/*  IEU0	Group	*/;		\
+	fpadd32		%F2, %f2, %F2		/*  FPA			*/;		\
+	fcmpgt32	%O14, %f14, %o5		/*  FPM			*/;		\
+	add		%o2, %g5, %o2		/*  IEU1	Group	*/;		\
+	fpadd32		%F4, %f4, %F4		/*  FPA			*/;		\
+	fcmpgt32	%f0, %F0, %g1		/*  FPM			*/;		\
+	srl		%g7, 1, %g7		/*  IEU0	Group	*/;		\
+	fpadd32		%F6, %f6, %F6		/*  FPA			*/;		\
+	fcmpgt32	%f2, %F2, %g2		/*  FPM			*/;		\
+	add		%o2, %g7, %o2		/*  IEU0	Group	*/;		\
+	fpadd32		%F8, %f8, %F8		/*  FPA			*/;		\
+	fcmpgt32	%f4, %F4, %g3		/*  FPM			*/;		\
+	inc		%o3			/*  IEU0	Group	*/;		\
+	fpadd32		%F10, %f10, %F10	/*  FPA			*/;		\
+	fcmpgt32	%f6, %F6, %g5		/*  FPM			*/;		\
+	srl		%o3, 1, %o3		/*  IEU0	Group	*/;		\
+	fpadd32		%F12, %f12, %F12	/*  FPA			*/;		\
+	fcmpgt32	%f8, %F8, %g7		/*  FPM			*/;		\
+	add		%o2, %o3, %o2		/*  IEU0	Group	*/;		\
+	fpadd32		%F14, %f14, %F14	/*  FPA			*/;		\
+	fcmpgt32	%f10, %F10, %o3		/*  FPM			*/;		\
+	inc		%o4			/*  IEU0	Group	*/;		\
+	inc		%o5			/*  IEU1		*/;		\
+	srl		%o4, 1, %o4		/*  IEU0	Group	*/;		\
+	inc		%g1			/*  IEU1		*/;		\
+	srl		%o5, 1, %o5		/*  IEU0	Group	*/;		\
+	add		%o2, %o4, %o2		/*  IEU1		*/;		\
+	srl		%g1, 1, %g1		/*  IEU0	Group	*/;		\
+	add		%o2, %o5, %o2		/*  IEU1		*/;		\
+	inc		%g2			/*  IEU0	Group	*/;		\
+	add		%o2, %g1, %o2		/*  IEU1		*/;		\
+	srl		%g2, 1, %g2		/*  IEU0	Group	*/;		\
+	inc		%g3			/*  IEU1		*/;		\
+	srl		%g3, 1, %g3		/*  IEU0	Group	*/;		\
+	add		%o2, %g2, %o2		/*  IEU1		*/;		\
+	inc		%g5			/*  IEU0	Group	*/;		\
+	add		%o2, %g3, %o2		/*  IEU0		*/;
 
-#define END_THE_TRICK(O12,O14,f0,f2,f4,f6,f8,f10,f12,f14,S0,S1,S2,S3,T0,T1,U0,fz)		\
-	fcmpgt32	%O12, %f12, %o4		/*  FPM		Group			*/;	\
-	srl		%g5, 1, %g5		/*  IEU0				*/;	\
-	inc		%g7			/*  IEU1				*/;	\
-	fpadd32		%f2, %f0, %S0		/*  FPA					*/;	\
-	fcmpgt32	%O14, %f14, %o5		/*  FPM		Group			*/;	\
-	srl		%g7, 1, %g7		/*  IEU0				*/;	\
-	add		%o2, %g5, %o2		/*  IEU1				*/;	\
-	fpadd32		%f6, %f4, %S1		/*  FPA					*/;	\
-	inc		%o3			/*  IEU0	Group			*/;	\
-	add		%o2, %g7, %o2		/*  IEU1				*/;	\
-	fcmpgt32	%f0, %S0, %g1		/*  FPM		Group			*/;	\
-	srl		%o3, 1, %o3		/*  IEU0				*/;	\
-	inc		%o4			/*  IEU1				*/;	\
-	fpadd32		%f10, %f8, %S2		/*  FPA					*/;	\
-	fcmpgt32	%f4, %S1, %g2		/*  FPM		Group			*/;	\
-	srl		%o4, 1, %o4		/*  IEU0				*/;	\
-	add		%o2, %o3, %o2		/*  IEU1				*/;	\
-	fpadd32		%f14, %f12, %S3		/*  FPA					*/;	\
-	inc		%o5			/*  IEU0	Group			*/;	\
-	add		%o2, %o4, %o2		/*  IEU1				*/;	\
-	fzero		%fz			/*  FPA					*/;	\
-	fcmpgt32	%f8, %S2, %g3		/*  FPM		Group			*/;	\
-	srl		%o5, 1, %o5		/*  IEU0				*/;	\
-	inc		%g1			/*  IEU1				*/;	\
-	fpadd32		%S0, %S1, %T0		/*  FPA					*/;	\
-	fcmpgt32	%f12, %S3, %g5		/*  FPM		Group			*/;	\
-	srl		%g1, 1, %g1		/*  IEU0				*/;	\
-	add		%o2, %o5, %o2		/*  IEU1				*/;	\
-	fpadd32		%S2, %S3, %T1		/*  FPA					*/;	\
-	inc		%g2			/*  IEU0	Group			*/;	\
-	add		%o2, %g1, %o2		/*  IEU1				*/;	\
-	fcmpgt32	%S0, %T0, %g7		/*  FPM		Group			*/;	\
-	srl		%g2, 1, %g2		/*  IEU0				*/;	\
-	inc		%g3			/*  IEU1				*/;	\
-	fcmpgt32	%S2, %T1, %o3		/*  FPM		Group			*/;	\
-	srl		%g3, 1, %g3		/*  IEU0				*/;	\
-	add		%o2, %g2, %o2		/*  IEU1				*/;	\
-	inc		%g5			/*  IEU0	Group			*/;	\
-	add		%o2, %g3, %o2		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %f2, %o4		/*  FPM		Group			*/;	\
-	srl		%g5, 1, %g5		/*  IEU0				*/;	\
-	inc		%g7			/*  IEU1				*/;	\
-	fpadd32		%T0, %T1, %U0		/*  FPA					*/;	\
-	fcmpgt32	%fz, %f6, %o5		/*  FPM		Group			*/;	\
-	srl		%g7, 1, %g7		/*  IEU0				*/;	\
-	add		%o2, %g5, %o2		/*  IEU1				*/;	\
-	inc		%o3			/*  IEU0	Group			*/;	\
-	add		%o2, %g7, %o2		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %f10, %g1		/*  FPM		Group			*/;	\
-	srl		%o3, 1, %o3		/*  IEU0				*/;	\
-	inc		%o4			/*  IEU1				*/;	\
-	fcmpgt32	%fz, %f14, %g2		/*  FPM		Group			*/;	\
-	srl		%o4, 1, %o4		/*  IEU0				*/;	\
-	add		%o2, %o3, %o2		/*  IEU1				*/;	\
-	std		%U0, [%sp + STACKOFF]	/*  Store	Group			*/;	\
-	inc		%o5			/*  IEU0				*/;	\
-	sub		%o2, %o4, %o2		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %S1, %g3		/*  FPM		Group			*/;	\
-	srl		%o5, 1, %o5		/*  IEU0				*/;	\
-	inc		%g1			/*  IEU1				*/;	\
-	fcmpgt32	%fz, %S3, %g5		/*  FPM		Group			*/;	\
-	srl		%g1, 1, %g1		/*  IEU0				*/;	\
-	sub		%o2, %o5, %o2		/*  IEU1				*/;	\
-	ldx		[%sp + STACKOFF], %o5	/*  Load	Group			*/;	\
-	inc		%g2			/*  IEU0				*/;	\
-	sub		%o2, %g1, %o2		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %T1, %g7		/*  FPM		Group			*/;	\
-	srl		%g2, 1, %g2		/*  IEU0				*/;	\
-	inc		%g3			/*  IEU1				*/;	\
-	fcmpgt32	%T0, %U0, %o3		/*  FPM		Group			*/;	\
-	srl		%g3, 1, %g3		/*  IEU0				*/;	\
-	sub		%o2, %g2, %o2		/*  IEU1				*/;	\
-	inc		%g5			/*  IEU0	Group			*/;	\
-	sub		%o2, %g3, %o2		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %U0, %o4		/*  FPM		Group			*/;	\
-	srl		%g5, 1, %g5		/*  IEU0				*/;	\
-	inc		%g7			/*  IEU1				*/;	\
-	srl		%g7, 1, %g7		/*  IEU0	Group			*/;	\
-	sub		%o2, %g5, %o2		/*  IEU1				*/;	\
-	inc		%o3			/*  IEU0	Group			*/;	\
-	sub		%o2, %g7, %o2		/*  IEU1				*/;	\
-	srl		%o3, 1, %o3		/*  IEU0	Group			*/;	\
-	inc		%o4			/*  IEU1				*/;	\
-	srl		%o4, 1, %o4		/*  IEU0	Group			*/;	\
-	add		%o2, %o3, %o2		/*  IEU1				*/;	\
-	sub		%o2, %o4, %o2		/*  IEU0	Group			*/;	\
-	addcc		%o2, %o5, %o2		/*  IEU1	Group			*/;	\
-	bcs,a,pn	%xcc, 33f		/*  CTI					*/;	\
-	 add		%o2, 1, %o2		/*  IEU0				*/;	\
-33:						/*  That's it				*/;
+#define END_THE_TRICK(O12,O14,f0,f2,f4,f6,f8,f10,f12,f14,S0,S1,S2,S3,T0,T1,U0,fz)	\
+	srl		%g5, 1, %g5		/*  IEU0	Group	*/;		\
+	fpadd32		%f2, %f0, %S0		/*  FPA			*/;		\
+	fcmpgt32	%O12, %f12, %o4		/*  FPM			*/;		\
+	inc		%g7			/*  IEU0	Group	*/;		\
+	fpadd32		%f6, %f4, %S1		/*  FPA			*/;		\
+	fcmpgt32	%O14, %f14, %o5		/*  FPM			*/;		\
+	srl		%g7, 1, %g7		/*  IEU0	Group	*/;		\
+	fpadd32		%f10, %f8, %S2		/*  FPA			*/;		\
+	fcmpgt32	%f0, %S0, %g1		/*  FPM			*/;		\
+	inc		%o3			/*  IEU0	Group	*/;		\
+	fpadd32		%f14, %f12, %S3		/*  FPA			*/;		\
+	fcmpgt32	%f4, %S1, %g2		/*  FPM			*/;		\
+	add		%o2, %g5, %o2		/*  IEU0	Group	*/;		\
+	fpadd32		%S0, %S1, %T0		/*  FPA			*/;		\
+	fcmpgt32	%f8, %S2, %g3		/*  FPM			*/;		\
+	add		%o2, %g7, %o2		/*  IEU0	Group	*/;		\
+	fzero		%fz			/*  FPA			*/;		\
+	fcmpgt32	%f12, %S3, %g5		/*  FPM			*/;		\
+	srl		%o3, 1, %o3		/*  IEU0	Group	*/;		\
+	fpadd32		%S2, %S3, %T1		/*  FPA			*/;		\
+	fcmpgt32	%S0, %T0, %g7		/*  FPM			*/;		\
+	add		%o2, %o3, %o2		/*  IEU0	Group	*/;		\
+	fpadd32		%T0, %T1, %U0		/*  FPA			*/;		\
+	fcmpgt32	%S2, %T1, %o3		/*  FPM			*/;		\
+	inc		%o4			/*  IEU0	Group	*/;		\
+	inc		%o5			/*  IEU1		*/;		\
+	srl		%o4, 1, %o4		/*  IEU0	Group	*/;		\
+	inc		%g1			/*  IEU1		*/;		\
+	add		%o2, %o4, %o2		/*  IEU0	Group	*/;		\
+	fcmpgt32	%fz, %f2, %o4		/*  FPM			*/;		\
+	srl		%o5, 1, %o5		/*  IEU0	Group	*/;		\
+	inc		%g2			/*  IEU1		*/;		\
+	add		%o2, %o5, %o2		/*  IEU0	Group	*/;		\
+	fcmpgt32	%fz, %f6, %o5		/*  FPM			*/;		\
+	srl		%g1, 1, %g1		/*  IEU0	Group	*/;		\
+	inc		%g3			/*  IEU1		*/;		\
+	add		%o2, %g1, %o2		/*  IEU0	Group	*/;		\
+	fcmpgt32	%fz, %f10, %g1		/*  FPM			*/;		\
+	srl		%g2, 1, %g2		/*  IEU0	Group	*/;		\
+	inc		%g5			/*  IEU1		*/;		\
+	add		%o2, %g2, %o2		/*  IEU0	Group	*/;		\
+	fcmpgt32	%fz, %f14, %g2		/*  FPM			*/;		\
+	srl		%g3, 1, %g3		/*  IEU0	Group	*/;		\
+	inc		%g7			/*  IEU1		*/;		\
+	add		%o2, %g3, %o2		/*  IEU0	Group	*/;		\
+	fcmpgt32	%fz, %S1, %g3		/*  FPM			*/;		\
+	srl		%g5, 1, %g5		/*  IEU0	Group	*/;		\
+	inc		%o3			/*  IEU1		*/;		\
+	add		%o2, %g5, %o2		/*  IEU0	Group	*/;		\
+	fcmpgt32	%fz, %S3, %g5		/*  FPM			*/;		\
+	srl		%g7, 1, %g7		/*  IEU0	Group	*/;		\
+	inc		%o4			/*  IEU1		*/;		\
+	add		%o2, %g7, %o2		/*  IEU0	Group	*/;		\
+	fcmpgt32	%fz, %T1, %g7		/*  FPM			*/;		\
+	srl		%o3, 1, %o3		/*  IEU0	Group	*/;		\
+	inc		%o5			/*  IEU1		*/;		\
+	add		%o2, %o3, %o2		/*  IEU0	Group	*/;		\
+	fcmpgt32	%T0, %U0, %o3		/*  FPM			*/;		\
+	srl		%o4, 1, %o4		/*  IEU0	Group	*/;		\
+	inc		%g1			/*  IEU1		*/;		\
+	sub		%o2, %o4, %o2		/*  IEU0	Group	*/;		\
+	fcmpgt32	%fz, %U0, %o4		/*  FPM			*/;		\
+	srl		%o5, 1, %o5		/*  IEU0	Group	*/;		\
+	inc		%g2			/*  IEU1		*/;		\
+	srl		%g1, 1, %g1		/*  IEU0	Group	*/;		\
+	sub		%o2, %o5, %o2		/*  IEU1		*/;		\
+	std		%U0, [%sp + STACKOFF]	/*  Store		*/;		\
+	srl		%g2, 1, %g2		/*  IEU0	Group	*/;		\
+	sub		%o2, %g1, %o2		/*  IEU1		*/;		\
+	inc		%g3			/*  IEU0	Group	*/;		\
+	sub		%o2, %g2, %o2		/*  IEU1		*/;		\
+	srl		%g3, 1, %g3		/*  IEU0	Group	*/;		\
+	inc		%g5			/*  IEU1		*/;		\
+	srl		%g5, 1, %g5		/*  IEU0	Group	*/;		\
+	sub		%o2, %g3, %o2		/*  IEU1		*/;		\
+	ldx		[%sp + STACKOFF], %o5	/*  Load	Group	*/;		\
+	inc		%g7			/*  IEU0		*/;		\
+	sub		%o2, %g5, %o2		/*  IEU1		*/;		\
+	srl		%g7, 1, %g7		/*  IEU0	Group	*/;		\
+	inc		%o3			/*  IEU1		*/;		\
+	srl		%o3, 1, %o3		/*  IEU0	Group	*/;		\
+	sub		%o2, %g7, %o2		/*  IEU1		*/;		\
+	inc		%o4			/*  IEU0	Group	*/;		\
+	add		%o2, %o3, %o2		/*  IEU1		*/;		\
+	srl		%o4, 1, %o4		/*  IEU0	Group	*/;		\
+	sub		%o2, %o4, %o2		/*  IEU0	Group	*/;		\
+	addcc		%o2, %o5, %o2		/*  IEU1	Group	*/;		\
+	bcs,a,pn	%xcc, 33f		/*  CTI			*/;		\
+	 add		%o2, 1, %o2		/*  IEU0		*/;		\
+33:						/*  That's it		*/;
 
-#define CSUM_LASTCHUNK(offset)									\
-        ldx             [%o0 - offset - 0x10], %g2;						\
-        ldx             [%o0 - offset - 0x08], %g3;						\
-        addcc           %g2, %o2, %o2;								\
-        bcs,a,pn        %xcc, 31f;								\
-         add            %o2, 1, %o2;								\
-31:     addcc           %g3, %o2, %o2;								\
-        bcs,a,pn        %xcc, 32f;								\
-         add            %o2, 1, %o2;								\
+#define CSUM_LASTCHUNK(offset)								\
+        ldx             [%o0 - offset - 0x10], %g2;					\
+        ldx             [%o0 - offset - 0x08], %g3;					\
+        addcc           %g2, %o2, %o2;							\
+        bcs,a,pn        %xcc, 31f;							\
+         add            %o2, 1, %o2;							\
+31:     addcc           %g3, %o2, %o2;							\
+        bcs,a,pn        %xcc, 32f;							\
+         add            %o2, 1, %o2;							\
 32:
 
 	.text
 	.globl		csum_partial
 	.align		32
 csum_partial:
-	andcc		%o0, 7, %g0		/*  IEU1	Group			*/
-	be,pt		%icc, 4f		/*  CTI					*/
-	 andcc		%o0, 0x38, %g3		/*  IEU1				*/
-	mov		1, %g5			/*  IEU0	Group			*/
-	cmp		%o1, 6			/*  IEU1				*/
-	bl,pn		%icc, 21f		/*  CTI					*/
-	 andcc		%o0, 2, %g0		/*  IEU1	Group			*/
-	be,pt		%icc, 1f		/*  CTI					*/
-	 and		%o0, 4, %g7		/*  IEU0				*/
-	lduh		[%o0], %g2		/*  Load				*/
-	sub		%o1, 2, %o1		/*  IEU0	Group			*/
-	add		%o0, 2, %o0		/*  IEU1				*/
-	andcc		%o0, 4, %g7		/*  IEU1	Group			*/
-	sll		%g5, 16, %g5		/*  IEU0				*/
-	sll		%g2, 16, %g2		/*  IEU0	Group 			*/
-	addcc		%g2, %o2, %o2		/*  IEU1	Group (regdep)		*/
-	bcs,a,pn	%icc, 1f		/*  CTI					*/
-	 add		%o2, %g5, %o2		/*  IEU0				*/
-1:	ld		[%o0], %g2		/*  Load				*/
-	brz,a,pn	%g7, 4f			/*  CTI+IEU1	Group			*/
-	 and		%o0, 0x38, %g3		/*  IEU0				*/
-	add		%o0, 4, %o0		/*  IEU0	Group			*/
-	sub		%o1, 4, %o1		/*  IEU1				*/
-	addcc		%g2, %o2, %o2		/*  IEU1	Group			*/
-	bcs,a,pn	%icc, 1f		/*  CTI					*/
-	 add		%o2, 1, %o2		/*  IEU0				*/
-1:	and		%o0, 0x38, %g3		/*  IEU1	Group			*/
-4:	srl		%o2, 0, %o2		/*  IEU0	Group			*/
-	mov		0x40, %g1		/*  IEU1				*/
-	brz,pn		%g3, 3f			/*  CTI+IEU1	Group			*/
-	 sub		%g1, %g3, %g1		/*  IEU0				*/
-	cmp		%o1, 56			/*  IEU1	Group			*/
-	blu,pn		%icc, 20f		/*  CTI					*/
-	 andcc		%o0, 8, %g0		/*  IEU1	Group			*/
-	be,pn		%icc, 1f		/*  CTI					*/
-	 ldx		[%o0], %g2		/*  Load				*/
-	add		%o0, 8, %o0		/*  IEU0	Group			*/
-	sub		%o1, 8, %o1		/*  IEU1				*/
-	addcc		%g2, %o2, %o2		/*  IEU1	Group			*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%o2, 1, %o2		/*  IEU0				*/
-1:	andcc		%g1, 0x10, %g0		/*  IEU1	Group			*/
-	be,pn		%icc, 2f		/*  CTI					*/
-	 and		%g1, 0x20, %g1		/*  IEU0				*/
-	ldx		[%o0], %g2		/*  Load				*/
-	ldx		[%o0+8], %g3		/*  Load	Group			*/
-	add		%o0, 16, %o0		/*  IEU0				*/
-	sub		%o1, 16, %o1		/*  IEU1				*/
-	addcc		%g2, %o2, %o2		/*  IEU1	Group			*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%o2, 1, %o2		/*  IEU0				*/
-1:	addcc		%g3, %o2, %o2		/*  IEU1	Group			*/
-	bcs,a,pn	%xcc, 2f		/*  CTI					*/
-	 add		%o2, 1, %o2		/*  IEU0				*/
-2:	brz,pn		%g1, 3f			/*  CTI+IEU1	Group			*/
-	 ldx		[%o0], %g2		/*  Load				*/
-	ldx		[%o0+8], %g3		/*  Load	Group			*/
-	ldx		[%o0+16], %g5		/*  Load	Group			*/
-	ldx		[%o0+24], %g7		/*  Load	Group			*/
-	add		%o0, 32, %o0		/*  IEU0				*/
-	sub		%o1, 32, %o1		/*  IEU1				*/
-	addcc		%g2, %o2, %o2		/*  IEU1	Group			*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%o2, 1, %o2		/*  IEU0				*/
-1:	addcc		%g3, %o2, %o2		/*  IEU1	Group			*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%o2, 1, %o2		/*  IEU0				*/
-1:	addcc		%g5, %o2, %o2		/*  IEU1	Group			*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%o2, 1, %o2		/*  IEU0				*/
-1:	addcc		%g7, %o2, %o2		/*  IEU1	Group			*/
-	bcs,a,pn	%xcc, 3f		/*  CTI					*/
-	 add		%o2, 1, %o2		/*  IEU0				*/
-3:	cmp		%o1, 0xc0		/*  IEU1	Group			*/
-	blu,pn		%icc, 20f		/*  CTI					*/
-	 sllx		%o2, 32, %g5		/*  IEU0				*/
+	andcc		%o0, 7, %g0		/*  IEU1	Group		*/
+	be,pt		%icc, 4f		/*  CTI				*/
+	 andcc		%o0, 0x38, %g3		/*  IEU1			*/
+	mov		1, %g5			/*  IEU0	Group		*/
+	cmp		%o1, 6			/*  IEU1			*/
+	bl,pn		%icc, 21f		/*  CTI				*/
+	 andcc		%o0, 2, %g0		/*  IEU1	Group		*/
+	be,pt		%icc, 1f		/*  CTI				*/
+	 and		%o0, 4, %g7		/*  IEU0			*/
+	lduh		[%o0], %g2		/*  Load			*/
+	sub		%o1, 2, %o1		/*  IEU0	Group		*/
+	add		%o0, 2, %o0		/*  IEU1			*/
+	andcc		%o0, 4, %g7		/*  IEU1	Group		*/
+	sll		%g5, 16, %g5		/*  IEU0			*/
+	sll		%g2, 16, %g2		/*  IEU0	Group 		*/
+	addcc		%g2, %o2, %o2		/*  IEU1	Group (regdep)	*/
+	bcs,a,pn	%icc, 1f		/*  CTI				*/
+	 add		%o2, %g5, %o2		/*  IEU0			*/
+1:	ld		[%o0], %g2		/*  Load			*/
+	brz,a,pn	%g7, 4f			/*  CTI+IEU1	Group		*/
+	 and		%o0, 0x38, %g3		/*  IEU0			*/
+	add		%o0, 4, %o0		/*  IEU0	Group		*/
+	sub		%o1, 4, %o1		/*  IEU1			*/
+	addcc		%g2, %o2, %o2		/*  IEU1	Group		*/
+	bcs,a,pn	%icc, 1f		/*  CTI				*/
+	 add		%o2, 1, %o2		/*  IEU0			*/
+1:	and		%o0, 0x38, %g3		/*  IEU1	Group		*/
+4:	srl		%o2, 0, %o2		/*  IEU0	Group		*/
+	mov		0x40, %g1		/*  IEU1			*/
+	brz,pn		%g3, 3f			/*  CTI+IEU1	Group		*/
+	 sub		%g1, %g3, %g1		/*  IEU0			*/
+	cmp		%o1, 56			/*  IEU1	Group		*/
+	blu,pn		%icc, 20f		/*  CTI				*/
+	 andcc		%o0, 8, %g0		/*  IEU1	Group		*/
+	be,pn		%icc, 1f		/*  CTI				*/
+	 ldx		[%o0], %g2		/*  Load			*/
+	add		%o0, 8, %o0		/*  IEU0	Group		*/
+	sub		%o1, 8, %o1		/*  IEU1			*/
+	addcc		%g2, %o2, %o2		/*  IEU1	Group		*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%o2, 1, %o2		/*  IEU0			*/
+1:	andcc		%g1, 0x10, %g0		/*  IEU1	Group		*/
+	be,pn		%icc, 2f		/*  CTI				*/
+	 and		%g1, 0x20, %g1		/*  IEU0			*/
+	ldx		[%o0], %g2		/*  Load			*/
+	ldx		[%o0+8], %g3		/*  Load	Group		*/
+	add		%o0, 16, %o0		/*  IEU0			*/
+	sub		%o1, 16, %o1		/*  IEU1			*/
+	addcc		%g2, %o2, %o2		/*  IEU1	Group		*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%o2, 1, %o2		/*  IEU0			*/
+1:	addcc		%g3, %o2, %o2		/*  IEU1	Group		*/
+	bcs,a,pn	%xcc, 2f		/*  CTI				*/
+	 add		%o2, 1, %o2		/*  IEU0			*/
+2:	brz,pn		%g1, 3f			/*  CTI+IEU1	Group		*/
+	 ldx		[%o0], %g2		/*  Load			*/
+	ldx		[%o0+8], %g3		/*  Load	Group		*/
+	ldx		[%o0+16], %g5		/*  Load	Group		*/
+	ldx		[%o0+24], %g7		/*  Load	Group		*/
+	add		%o0, 32, %o0		/*  IEU0			*/
+	sub		%o1, 32, %o1		/*  IEU1			*/
+	addcc		%g2, %o2, %o2		/*  IEU1	Group		*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%o2, 1, %o2		/*  IEU0			*/
+1:	addcc		%g3, %o2, %o2		/*  IEU1	Group		*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%o2, 1, %o2		/*  IEU0			*/
+1:	addcc		%g5, %o2, %o2		/*  IEU1	Group		*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%o2, 1, %o2		/*  IEU0			*/
+1:	addcc		%g7, %o2, %o2		/*  IEU1	Group		*/
+	bcs,a,pn	%xcc, 3f		/*  CTI				*/
+	 add		%o2, 1, %o2		/*  IEU0			*/
+3:	cmp		%o1, 0xc0		/*  IEU1	Group		*/
+	blu,pn		%icc, 20f		/*  CTI				*/
+	 sllx		%o2, 32, %g5		/*  IEU0			*/
 #ifdef __KERNEL__
 	VISEntry
 #endif
-	addcc		%o2, %g5, %o2		/*  IEU1	Group			*/
-	sub		%o1, 0xc0, %o1		/*  IEU0				*/
-	wr		%g0, ASI_BLK_P, %asi	/*  LSU		Group			*/
-	membar		#StoreLoad		/*  LSU		Group			*/
-	srlx		%o2, 32, %o2		/*  IEU0	Group			*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%o2, 1, %o2		/*  IEU1				*/
-1:	andcc		%o1, 0x80, %g0		/*  IEU1	Group			*/
-	bne,pn		%icc, 7f		/*  CTI					*/
-	 andcc		%o1, 0x40, %g0		/*  IEU1	Group			*/
-	be,pn		%icc, 6f		/*  CTI					*/
-	 fzero		%f12			/*  FPA					*/
-	fzero		%f14			/*  FPA		Group			*/
+	addcc		%o2, %g5, %o2		/*  IEU1	Group		*/
+	sub		%o1, 0xc0, %o1		/*  IEU0			*/
+	wr		%g0, ASI_BLK_P, %asi	/*  LSU		Group		*/
+	membar		#StoreLoad		/*  LSU		Group		*/
+	srlx		%o2, 32, %o2		/*  IEU0	Group		*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%o2, 1, %o2		/*  IEU1			*/
+1:	andcc		%o1, 0x80, %g0		/*  IEU1	Group		*/
+	bne,pn		%icc, 7f		/*  CTI				*/
+	 andcc		%o1, 0x40, %g0		/*  IEU1	Group		*/
+	be,pn		%icc, 6f		/*  CTI				*/
+	 fzero		%f12			/*  FPA				*/
+	fzero		%f14			/*  FPA		Group		*/
 	ldda		[%o0 + 0x000] %asi, %f16
 	ldda		[%o0 + 0x040] %asi, %f32
 	ldda		[%o0 + 0x080] %asi, %f48
 	START_THE_TRICK(f12,f16,f18,f20,f22,f24,f26)
 	ba,a,pt		%xcc, 3f
-6:	sub		%o0, 0x40, %o0		/*  IEU0	Group			*/
-	fzero		%f28			/*  FPA					*/
-	fzero		%f30			/*  FPA		Group			*/
+6:	sub		%o0, 0x40, %o0		/*  IEU0	Group		*/
+	fzero		%f28			/*  FPA				*/
+	fzero		%f30			/*  FPA		Group		*/
 	ldda		[%o0 + 0x040] %asi, %f32
 	ldda		[%o0 + 0x080] %asi, %f48
 	ldda		[%o0 + 0x0c0] %asi, %f0
 	START_THE_TRICK(f28,f32,f34,f36,f38,f40,f42)
 	ba,a,pt		%xcc, 4f
-7:	bne,pt		%icc, 8f		/*  CTI					*/
-	 fzero		%f44			/*  FPA					*/
-	add		%o0, 0x40, %o0		/*  IEU0	Group			*/
-	fzero		%f60			/*  FPA					*/
-	fzero		%f62			/*  FPA		Group			*/
+7:	bne,pt		%icc, 8f		/*  CTI				*/
+	 fzero		%f44			/*  FPA				*/
+	add		%o0, 0x40, %o0		/*  IEU0	Group		*/
+	fzero		%f60			/*  FPA				*/
+	fzero		%f62			/*  FPA		Group		*/
 	ldda		[%o0 - 0x040] %asi, %f0
 	ldda		[%o0 + 0x000] %asi, %f16
 	ldda		[%o0 + 0x040] %asi, %f32
 	START_THE_TRICK(f60,f0,f2,f4,f6,f8,f10)
 	ba,a,pt		%xcc, 2f
-8:	add		%o0, 0x80, %o0		/*  IEU0	Group			*/
-	fzero		%f46			/*  FPA					*/
+8:	add		%o0, 0x80, %o0		/*  IEU0	Group		*/
+	fzero		%f46			/*  FPA				*/
 	ldda		[%o0 - 0x080] %asi, %f48
 	ldda		[%o0 - 0x040] %asi, %f0
 	ldda		[%o0 + 0x000] %asi, %f16
@@ -333,36 +334,36 @@
 3:	DO_THE_TRICK(f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46)
 	ldda		[%o0 + 0x0c0] %asi, %f0
 4:	DO_THE_TRICK(f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,f48,f50,f52,f54,f56,f58,f60,f62)
-	add		%o0, 0x100, %o0		/*  IEU0	Group			*/
-	subcc		%o1, 0x100, %o1		/*  IEU1				*/
-	bgeu,a,pt	%icc, 1b		/*  CTI					*/
+	add		%o0, 0x100, %o0		/*  IEU0	Group		*/
+	subcc		%o1, 0x100, %o1		/*  IEU1			*/
+	bgeu,a,pt	%icc, 1b		/*  CTI				*/
 	 ldda		[%o0 + 0x000] %asi, %f16
-	membar		#Sync			/*  LSU		Group			*/
+	membar		#Sync			/*  LSU		Group		*/
 	DO_THE_TRICK(f44,f46,f48,f50,f52,f54,f56,f58,f60,f62,f0,f2,f4,f6,f8,f10,f12,f14)
 	END_THE_TRICK(f60,f62,f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30)
 #ifdef __KERNEL__
 	ldub		[%g6 + AOFF_task_thread + AOFF_thread_current_ds], %g7
 #endif
-	and		%o1, 0x3f, %o1		/*  IEU0	Group			*/
+	and		%o1, 0x3f, %o1		/*  IEU0	Group		*/
 #ifdef __KERNEL__
 	VISExit
 	wr		%g7, %g0, %asi
 #endif
-20:	andcc		%o1, 0xf0, %g1		/*  IEU1	Group			*/
-	be,pn		%icc, 23f		/*  CTI					*/
-	 and		%o1, 0xf, %o3		/*  IEU0				*/
+20:	andcc		%o1, 0xf0, %g1		/*  IEU1	Group		*/
+	be,pn		%icc, 23f		/*  CTI				*/
+	 and		%o1, 0xf, %o3		/*  IEU0			*/
 #ifdef __KERNEL__
-22:	sll		%g1, 1, %o4		/*  IEU0	Group			*/
-	sethi		%hi(23f), %g7		/*  IEU1				*/
-	sub		%g7, %o4, %g7		/*  IEU0	Group			*/
-	jmpl		%g7 + %lo(23f), %g0	/*  CTI		Group brk forced	*/
-	 add		%o0, %g1, %o0		/*  IEU0				*/
+22:	sll		%g1, 1, %o4		/*  IEU0	Group		*/
+	sethi		%hi(23f), %g7		/*  IEU1			*/
+	sub		%g7, %o4, %g7		/*  IEU0	Group		*/
+	jmpl		%g7 + %lo(23f), %g0	/*  CTI		Group brk forced*/
+	 add		%o0, %g1, %o0		/*  IEU0			*/
 #else
-22:	rd		%pc, %g7		/*  LSU		Group+4bubbles		*/
-	sll		%g1, 1, %o4		/*  IEU0	Group			*/
-	sub		%g7, %o4, %g7		/*  IEU0	Group (regdep)		*/
-	jmpl		%g7 + (23f - 22b), %g0	/*  CTI		Group brk forced	*/
-	 add		%o0, %g1, %o0		/*  IEU0				*/
+22:	rd		%pc, %g7		/*  LSU		Group+4bubbles	*/
+	sll		%g1, 1, %o4		/*  IEU0	Group		*/
+	sub		%g7, %o4, %g7		/*  IEU0	Group (regdep)	*/
+	jmpl		%g7 + (23f - 22b), %g0	/*  CTI		Group brk forced*/
+	 add		%o0, %g1, %o0		/*  IEU0			*/
 #endif
 	CSUM_LASTCHUNK(0xe0)
 	CSUM_LASTCHUNK(0xd0)
@@ -379,72 +380,72 @@
 	CSUM_LASTCHUNK(0x20)
 	CSUM_LASTCHUNK(0x10)
 	CSUM_LASTCHUNK(0x00)
-23:	brnz,pn		%o3, 26f		/*  CTI+IEU1	Group			*/
-24:	 sllx		%o2, 32, %g1		/*  IEU0				*/
-25:	addcc		%o2, %g1, %o0		/*  IEU1	Group			*/
-	srlx		%o0, 32, %o0		/*  IEU0	Group (regdep)		*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%o0, 1, %o0		/*  IEU1				*/
-1:	retl					/*  CTI		Group brk forced	*/
-	 srl		%o0, 0, %o0		/*  IEU0				*/
-26:	andcc		%o1, 8, %g0		/*  IEU1	Group			*/
-	be,pn		%icc, 1f		/*  CTI					*/
-	 ldx		[%o0], %g3		/*  Load				*/
-	add		%o0, 8, %o0		/*  IEU0	Group			*/
-	addcc		%g3, %o2, %o2		/*  IEU1	Group			*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%o2, 1, %o2		/*  IEU0				*/
-1:	andcc		%o1, 4, %g0		/*  IEU1	Group			*/
-	be,a,pn		%icc, 1f		/*  CTI					*/
-	 clr		%g2			/*  IEU0				*/
-	ld		[%o0], %g2		/*  Load				*/
-	add		%o0, 4, %o0		/*  IEU0	Group			*/
-	sllx		%g2, 32, %g2		/*  IEU0	Group			*/
-1:	andcc		%o1, 2, %g0		/*  IEU1				*/
-	be,a,pn		%icc, 1f		/*  CTI					*/
-	 clr		%o4			/*  IEU0	Group			*/
-	lduh		[%o0], %o4		/*  Load				*/
-	add		%o0, 2, %o0		/*  IEU1				*/
-	sll		%o4, 16, %o4		/*  IEU0	Group			*/
-1:	andcc		%o1, 1, %g0		/*  IEU1				*/
-	be,a,pn		%icc, 1f		/*  CTI					*/
-	 clr		%o5			/*  IEU0	Group			*/
-	ldub		[%o0], %o5		/*  Load				*/
-	sll		%o5, 8, %o5		/*  IEU0	Group			*/
-1:	or		%g2, %o4, %o4		/*  IEU1				*/
-	or		%o5, %o4, %o4		/*  IEU0	Group (regdep)		*/
-	addcc		%o4, %o2, %o2		/*  IEU1	Group (regdep)		*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%o2, 1, %o2		/*  IEU0				*/
-1:	ba,pt		%xcc, 25b		/*  CTI		Group			*/
-	 sllx		%o2, 32, %g1		/*  IEU0				*/
-21:	srl		%o2, 0, %o2		/*  IEU0	Group			*/
-	cmp		%o1, 0			/*  IEU1				*/
-	be,pn		%icc, 24b		/*  CTI					*/
-	 andcc		%o1, 4, %g0		/*  IEU1	Group			*/
-	be,a,pn		%icc, 1f		/*  CTI					*/
-	 clr		%g2			/*  IEU0				*/
-	lduh		[%o0], %g3		/*  Load				*/
-	lduh		[%o0+2], %g2		/*  Load	Group			*/
-	add		%o0, 4, %o0		/*  IEU0	Group			*/
-	sllx		%g3, 48, %g3		/*  IEU0	Group			*/
-	sllx		%g2, 32, %g2		/*  IEU0	Group			*/
-	or		%g3, %g2, %g2		/*  IEU0	Group			*/
-1:	andcc		%o1, 2, %g0		/*  IEU1				*/
-	be,a,pn		%icc, 1f		/*  CTI					*/
-	 clr		%o4			/*  IEU0	Group			*/
-	lduh		[%o0], %o4		/*  Load				*/
-	add		%o0, 2, %o0		/*  IEU1				*/
-	sll		%o4, 16, %o4		/*  IEU0	Group			*/
-1:	andcc		%o1, 1, %g0		/*  IEU1				*/
-	be,a,pn		%icc, 1f		/*  CTI					*/
-	 clr		%o5			/*  IEU0	Group			*/
-	ldub		[%o0], %o5		/*  Load				*/
-	sll		%o5, 8, %o5		/*  IEU0	Group			*/
-1:	or		%g2, %o4, %o4		/*  IEU1				*/
-	or		%o5, %o4, %o4		/*  IEU0	Group (regdep)		*/
-	addcc		%o4, %o2, %o2		/*  IEU1	Group (regdep)		*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%o2, 1, %o2		/*  IEU0				*/
-1:	ba,pt		%xcc, 25b		/*  CTI		Group			*/
-	 sllx		%o2, 32, %g1		/*  IEU0				*/
+23:	brnz,pn		%o3, 26f		/*  CTI+IEU1	Group		*/
+24:	 sllx		%o2, 32, %g1		/*  IEU0			*/
+25:	addcc		%o2, %g1, %o0		/*  IEU1	Group		*/
+	srlx		%o0, 32, %o0		/*  IEU0	Group (regdep)	*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%o0, 1, %o0		/*  IEU1			*/
+1:	retl					/*  CTI		Group brk forced*/
+	 srl		%o0, 0, %o0		/*  IEU0			*/
+26:	andcc		%o1, 8, %g0		/*  IEU1	Group		*/
+	be,pn		%icc, 1f		/*  CTI				*/
+	 ldx		[%o0], %g3		/*  Load			*/
+	add		%o0, 8, %o0		/*  IEU0	Group		*/
+	addcc		%g3, %o2, %o2		/*  IEU1	Group		*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%o2, 1, %o2		/*  IEU0			*/
+1:	andcc		%o1, 4, %g0		/*  IEU1	Group		*/
+	be,a,pn		%icc, 1f		/*  CTI				*/
+	 clr		%g2			/*  IEU0			*/
+	ld		[%o0], %g2		/*  Load			*/
+	add		%o0, 4, %o0		/*  IEU0	Group		*/
+	sllx		%g2, 32, %g2		/*  IEU0	Group		*/
+1:	andcc		%o1, 2, %g0		/*  IEU1			*/
+	be,a,pn		%icc, 1f		/*  CTI				*/
+	 clr		%o4			/*  IEU0	Group		*/
+	lduh		[%o0], %o4		/*  Load			*/
+	add		%o0, 2, %o0		/*  IEU1			*/
+	sll		%o4, 16, %o4		/*  IEU0	Group		*/
+1:	andcc		%o1, 1, %g0		/*  IEU1			*/
+	be,a,pn		%icc, 1f		/*  CTI				*/
+	 clr		%o5			/*  IEU0	Group		*/
+	ldub		[%o0], %o5		/*  Load			*/
+	sll		%o5, 8, %o5		/*  IEU0	Group		*/
+1:	or		%g2, %o4, %o4		/*  IEU1			*/
+	or		%o5, %o4, %o4		/*  IEU0	Group (regdep)	*/
+	addcc		%o4, %o2, %o2		/*  IEU1	Group (regdep)	*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%o2, 1, %o2		/*  IEU0			*/
+1:	ba,pt		%xcc, 25b		/*  CTI		Group		*/
+	 sllx		%o2, 32, %g1		/*  IEU0			*/
+21:	srl		%o2, 0, %o2		/*  IEU0	Group		*/
+	cmp		%o1, 0			/*  IEU1			*/
+	be,pn		%icc, 24b		/*  CTI				*/
+	 andcc		%o1, 4, %g0		/*  IEU1	Group		*/
+	be,a,pn		%icc, 1f		/*  CTI				*/
+	 clr		%g2			/*  IEU0			*/
+	lduh		[%o0], %g3		/*  Load			*/
+	lduh		[%o0+2], %g2		/*  Load	Group		*/
+	add		%o0, 4, %o0		/*  IEU0	Group		*/
+	sllx		%g3, 48, %g3		/*  IEU0	Group		*/
+	sllx		%g2, 32, %g2		/*  IEU0	Group		*/
+	or		%g3, %g2, %g2		/*  IEU0	Group		*/
+1:	andcc		%o1, 2, %g0		/*  IEU1			*/
+	be,a,pn		%icc, 1f		/*  CTI				*/
+	 clr		%o4			/*  IEU0	Group		*/
+	lduh		[%o0], %o4		/*  Load			*/
+	add		%o0, 2, %o0		/*  IEU1			*/
+	sll		%o4, 16, %o4		/*  IEU0	Group		*/
+1:	andcc		%o1, 1, %g0		/*  IEU1			*/
+	be,a,pn		%icc, 1f		/*  CTI				*/
+	 clr		%o5			/*  IEU0	Group		*/
+	ldub		[%o0], %o5		/*  Load			*/
+	sll		%o5, 8, %o5		/*  IEU0	Group		*/
+1:	or		%g2, %o4, %o4		/*  IEU1			*/
+	or		%o5, %o4, %o4		/*  IEU0	Group (regdep)	*/
+	addcc		%o4, %o2, %o2		/*  IEU1	Group (regdep)	*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%o2, 1, %o2		/*  IEU0			*/
+1:	ba,pt		%xcc, 25b		/*  CTI		Group		*/
+	 sllx		%o2, 32, %g1		/*  IEU0			*/
diff -u --recursive --new-file v2.3.47/linux/arch/sparc64/lib/VIScsumcopy.S linux/arch/sparc64/lib/VIScsumcopy.S
--- v2.3.47/linux/arch/sparc64/lib/VIScsumcopy.S	Fri Jan 28 15:09:07 2000
+++ linux/arch/sparc64/lib/VIScsumcopy.S	Mon Feb 21 16:32:27 2000
@@ -1,4 +1,4 @@
-/* $Id: VIScsumcopy.S,v 1.7 2000/01/19 04:06:03 davem Exp $
+/* $Id: VIScsumcopy.S,v 1.8 2000/02/20 23:21:39 davem Exp $
  * VIScsumcopy.S: High bandwidth IP checksumming with simultaneous
  *            copying utilizing the UltraSparc Visual Instruction Set.
  *
@@ -62,384 +62,386 @@
  * per 64bytes checksummed/copied.
  */
 
-#define LDBLK(O0)										\
-	ldda		[%src] %asi, %O0 	/*  Load	Group			*/
+#define LDBLK(O0)									\
+	ldda		[%src] %asi, %O0 	/*  Load	Group		*/
 
-#define STBLK											\
-	stda		%f48, [%dst] ASI_BLK_P	/*  Store				*/
+#define STBLK										\
+	stda		%f48, [%dst] ASI_BLK_P	/*  Store			*/
 
-#define ST(fx,off)										\
-	std		%fx, [%dst + off]	/*  Store				*/
+#define ST(fx,off)									\
+	std		%fx, [%dst + off]	/*  Store			*/
 
-#define SYNC											\
+#define SYNC										\
 	membar		#Sync
 
 
 #define DO_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,F0,F2,F4,F6,F8,F10,F12,F14,DUMMY1,A0,A2,A4,A6,A8,A10,A12,A14,B14,DUMMY2,LOAD,STORE1,STORE2,STORE3,STORE4,STORE5,STORE6,STORE7,STORE8,DUMMY3,BRANCH...)	\
-	LOAD					/*  Load	Group			*/;	\
-	faligndata	%A14, %F0, %A14		/*  FPA		Group			*/;	\
-	inc		%x5			/*  IEU0				*/;	\
-	STORE1					/*  Store (optional)			*/;	\
-	faligndata	%F0, %F2, %A0		/*  FPA		Group			*/;	\
-	srl		%x5, 1, %x5		/*  IEU0				*/;	\
-	add		%sum, %x4, %sum		/*  IEU1				*/;	\
-	fpadd32		%F0, %f0, %F0		/*  FPA		Group			*/;	\
-	inc		%x6			/*  IEU0				*/;	\
-	STORE2					/*  Store (optional)			*/;	\
-	faligndata	%F2, %F4, %A2		/*  FPA		Group			*/;	\
-	srl		%x6, 1, %x6		/*  IEU0				*/;	\
-	add		%sum, %x5, %sum		/*  IEU1				*/;	\
-	fpadd32		%F2, %f2, %F2		/*  FPA		Group			*/;	\
-	add		%src, 64, %src		/*  IEU0				*/;	\
-	add		%dst, 64, %dst		/*  IEU1				*/;	\
-	fcmpgt32	%f0, %F0, %x1		/*  FPM		Group			*/;	\
-	inc		%x7			/*  IEU0				*/;	\
-	STORE3					/*  Store (optional)			*/;	\
-	faligndata	%F4, %F6, %A4		/*  FPA					*/;	\
-	srl		%x7, 1, %x7		/*  IEU0	Group			*/;	\
-	add		%sum, %x6, %sum		/*  IEU1				*/;	\
-	fpadd32		%F4, %f4, %F4		/*  FPA					*/;	\
-	fcmpgt32	%f2, %F2, %x2		/*  FPM		Group			*/;	\
-	inc		%x8			/*  IEU0				*/;	\
-	STORE4					/*  Store (optional)			*/;	\
-	faligndata	%F6, %F8, %A6		/*  FPA					*/;	\
-	srl		%x8, 1, %x8		/*  IEU0	Group			*/;	\
-	add		%sum, %x7, %sum		/*  IEU1				*/;	\
-	fpadd32		%F6, %f6, %F6		/*  FPA					*/;	\
-	fcmpgt32	%f4, %F4, %x3		/*  FPM		Group			*/;	\
-	inc		%x1			/*  IEU0				*/;	\
-	STORE5					/*  Store (optional)			*/;	\
-	faligndata	%F8, %F10, %A8		/*  FPA					*/;	\
-	srl		%x1, 1, %x1		/*  IEU0	Group			*/;	\
-	add		%sum, %x8, %sum		/*  IEU1				*/;	\
-	fpadd32		%F8, %f8, %F8		/*  FPA					*/;	\
-	fcmpgt32	%f6, %F6, %x4		/*  FPM		Group			*/;	\
-	inc		%x2			/*  IEU0				*/;	\
-	STORE6					/*  Store (optional)			*/;	\
-	faligndata	%F10, %F12, %A10	/*  FPA					*/;	\
-	srl		%x2, 1, %x2		/*  IEU0	Group			*/;	\
-	add		%sum, %x1, %sum		/*  IEU1				*/;	\
-	fpadd32		%F10, %f10, %F10	/*  FPA					*/;	\
-	fcmpgt32	%f8, %F8, %x5		/*  FPM		Group			*/;	\
-	inc		%x3			/*  IEU0				*/;	\
-	STORE7					/*  Store (optional)			*/;	\
-	faligndata	%F12, %F14, %A12	/*  FPA					*/;	\
-	srl		%x3, 1, %x3		/*  IEU0	Group			*/;	\
-	add		%sum, %x2, %sum		/*  IEU1				*/;	\
-	fpadd32		%F12, %f12, %F12	/*  FPA					*/;	\
-	fcmpgt32	%f10, %F10, %x6		/*  FPM		Group			*/;	\
-	inc		%x4			/*  IEU0				*/;	\
-	STORE8					/*  Store (optional)			*/;	\
-	fmovd		%F14, %B14		/*  FPA					*/;	\
-	srl		%x4, 1, %x4		/*  IEU0	Group			*/;	\
-	add		%sum, %x3, %sum		/*  IEU1				*/;	\
-	fpadd32		%F14, %f14, %F14	/*  FPA					*/;	\
-	fcmpgt32	%f12, %F12, %x7		/*  FPM		Group			*/;	\
-	subcc		%len, 64, %len		/*  IEU1				*/;	\
-	BRANCH					/*  CTI					*/;	\
-	fcmpgt32	%f14, %F14, %x8		/*  FPM		Group			*/;	\
+	LOAD					/*  Load	(Group)		*/;	\
+	faligndata	%A14, %F0, %A14		/*  FPA		Group		*/;	\
+	inc		%x5			/*  IEU0			*/;	\
+	STORE1					/*  Store (optional)		*/;	\
+	faligndata	%F0, %F2, %A0		/*  FPA		Group		*/;	\
+	srl		%x5, 1, %x5		/*  IEU0			*/;	\
+	add		%sum, %x4, %sum		/*  IEU1			*/;	\
+	fpadd32		%F0, %f0, %F0		/*  FPA		Group		*/;	\
+	inc		%x6			/*  IEU0			*/;	\
+	STORE2					/*  Store (optional)		*/;	\
+	faligndata	%F2, %F4, %A2		/*  FPA		Group		*/;	\
+	srl		%x6, 1, %x6		/*  IEU0			*/;	\
+	add		%sum, %x5, %sum		/*  IEU1			*/;	\
+	fpadd32		%F2, %f2, %F2		/*  FPA		Group		*/;	\
+	add		%src, 64, %src		/*  IEU0			*/;	\
+	fcmpgt32	%f0, %F0, %x1		/*  FPM				*/;	\
+	add		%dst, 64, %dst		/*  IEU1	Group		*/;	\
+	inc		%x7			/*  IEU0			*/;	\
+	STORE3					/*  Store (optional)		*/;	\
+	faligndata	%F4, %F6, %A4		/*  FPA				*/;	\
+	fpadd32		%F4, %f4, %F4		/*  FPA		Group		*/;	\
+	add		%sum, %x6, %sum		/*  IEU1			*/;	\
+	fcmpgt32	%f2, %F2, %x2		/*  FPM				*/;	\
+	srl		%x7, 1, %x7		/*  IEU0	Group		*/;	\
+	inc		%x8			/*  IEU1			*/;	\
+	STORE4					/*  Store (optional)		*/;	\
+	faligndata	%F6, %F8, %A6		/*  FPA				*/;	\
+	fpadd32		%F6, %f6, %F6		/*  FPA		Group		*/;	\
+	srl		%x8, 1, %x8		/*  IEU0			*/;	\
+	fcmpgt32	%f4, %F4, %x3		/*  FPM				*/;	\
+	add		%sum, %x7, %sum		/*  IEU0	Group		*/;	\
+	inc		%x1			/*  IEU1			*/;	\
+	STORE5					/*  Store (optional)		*/;	\
+	faligndata	%F8, %F10, %A8		/*  FPA				*/;	\
+	fpadd32		%F8, %f8, %F8		/*  FPA		Group		*/;	\
+	srl		%x1, 1, %x1		/*  IEU0			*/;	\
+	fcmpgt32	%f6, %F6, %x4		/*  FPM				*/;	\
+	add		%sum, %x8, %sum		/*  IEU0	Group		*/;	\
+	inc		%x2			/*  IEU1			*/;	\
+	STORE6					/*  Store (optional)		*/;	\
+	faligndata	%F10, %F12, %A10	/*  FPA				*/;	\
+	fpadd32		%F10, %f10, %F10	/*  FPA		Group		*/;	\
+	srl		%x2, 1, %x2		/*  IEU0			*/;	\
+	fcmpgt32	%f8, %F8, %x5		/*  FPM				*/;	\
+	add		%sum, %x1, %sum		/*  IEU0	Group		*/;	\
+	inc		%x3			/*  IEU1			*/;	\
+	STORE7					/*  Store (optional)		*/;	\
+	faligndata	%F12, %F14, %A12	/*  FPA				*/;	\
+	fpadd32		%F12, %f12, %F12	/*  FPA		Group		*/;	\
+	srl		%x3, 1, %x3		/*  IEU0			*/;	\
+	fcmpgt32	%f10, %F10, %x6		/*  FPM				*/;	\
+	add		%sum, %x2, %sum		/*  IEU0	Group		*/;	\
+	inc		%x4			/*  IEU1			*/;	\
+	STORE8					/*  Store (optional)		*/;	\
+	fmovd		%F14, %B14		/*  FPA				*/;	\
+	fpadd32		%F14, %f14, %F14	/*  FPA		Group		*/;	\
+	srl		%x4, 1, %x4		/*  IEU0			*/;	\
+	fcmpgt32	%f12, %F12, %x7		/*  FPM				*/;	\
+	add		%sum, %x3, %sum		/*  IEU0	Group		*/;	\
+	subcc		%len, 64, %len		/*  IEU1			*/;	\
+	BRANCH					/*  CTI				*/;	\
+	fcmpgt32	%f14, %F14, %x8		/*  FPM		Group		*/;
 
 #define END_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB,S0,S1,S2,S3,T0,T1,U0,fz) \
-	inc		%x5			/*  IEU0	Group			*/;	\
-	fpadd32		%f2, %f0, %S0		/*  FPA					*/;	\
-	srl		%x5, 1, %x5		/*  IEU0	Group			*/;	\
-	add		%sum, %x4, %sum		/*  IEU1				*/;	\
-	fpadd32		%f6, %f4, %S1		/*  FPA					*/;	\
-	inc		%x6			/*  IEU0	Group			*/;	\
-	add		%sum, %x5, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%f0, %S0, %x1		/*  FPM		Group			*/;	\
-	srl		%x6, 1, %x6		/*  IEU0				*/;	\
-	inc		%x7			/*  IEU1				*/;	\
-	fpadd32		%f10, %f8, %S2		/*  FPA					*/;	\
-	fcmpgt32	%f4, %S1, %x2		/*  FPM		Group			*/;	\
-	srl		%x7, 1, %x7		/*  IEU0				*/;	\
-	add		%sum, %x6, %sum		/*  IEU1				*/;	\
-	fpadd32		%f14, %f12, %S3		/*  FPA					*/;	\
-	inc		%x8			/*  IEU0	Group			*/;	\
-	add		%sum, %x7, %sum		/*  IEU1				*/;	\
-	fzero		%fz			/*  FPA					*/;	\
-	fcmpgt32	%f8, %S2, %x3		/*  FPM		Group			*/;	\
-	srl		%x8, 1, %x8		/*  IEU0				*/;	\
-	inc		%x1			/*  IEU1				*/;	\
-	fpadd32		%S0, %S1, %T0		/*  FPA					*/;	\
-	fcmpgt32	%f12, %S3, %x4		/*  FPM		Group			*/;	\
-	srl		%x1, 1, %x1		/*  IEU0				*/;	\
-	add		%sum, %x8, %sum		/*  IEU1				*/;	\
-	fpadd32		%S2, %S3, %T1		/*  FPA					*/;	\
-	inc		%x2			/*  IEU0	Group			*/;	\
-	add		%sum, %x1, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%S0, %T0, %x5		/*  FPM		Group			*/;	\
-	srl		%x2, 1, %x2		/*  IEU0				*/;	\
-	inc		%x3			/*  IEU1				*/;	\
-	fcmpgt32	%S2, %T1, %x6		/*  FPM		Group			*/;	\
-	srl		%x3, 1, %x3		/*  IEU0				*/;	\
-	add		%sum, %x2, %sum		/*  IEU1				*/;	\
-	inc		%x4			/*  IEU0	Group			*/;	\
-	add		%sum, %x3, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %f2, %x7		/*  FPM		Group			*/;	\
-	srl		%x4, 1, %x4		/*  IEU0				*/;	\
-	inc		%x5			/*  IEU1				*/;	\
-	fpadd32		%T0, %T1, %U0		/*  FPA					*/;	\
-	fcmpgt32	%fz, %f6, %x8		/*  FPM		Group			*/;	\
-	srl		%x5, 1, %x5		/*  IEU0				*/;	\
-	add		%sum, %x4, %sum		/*  IEU1				*/;	\
-	inc		%x6			/*  IEU0	Group			*/;	\
-	add		%sum, %x5, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %f10, %x1		/*  FPM		Group			*/;	\
-	srl		%x6, 1, %x6		/*  IEU0				*/;	\
-	inc		%x7			/*  IEU1				*/;	\
-	fcmpgt32	%fz, %f14, %x2		/*  FPM		Group			*/;	\
-	ba,pt		%xcc, ett		/*  CTI					*/;	\
-	 fmovd		%FA, %FB		/*  FPA					*/;	\
+	inc		%x5			/*  IEU0	Group		*/;	\
+	fpadd32		%f2, %f0, %S0		/*  FPA				*/;	\
+	add		%sum, %x4, %sum		/*  IEU1			*/;	\
+	srl		%x5, 1, %x5		/*  IEU0	Group		*/;	\
+	fpadd32		%f6, %f4, %S1		/*  FPA				*/;	\
+	inc		%x6			/*  IEU1			*/;	\
+	fpadd32		%f10, %f8, %S2		/*  FPA		Group		*/;	\
+	add		%sum, %x5, %sum		/*  IEU0			*/;	\
+	fcmpgt32	%f0, %S0, %x1		/*  FPM				*/;	\
+	fpadd32		%f14, %f12, %S3		/*  FPA		Group		*/;	\
+	srl		%x6, 1, %x6		/*  IEU0			*/;	\
+	fcmpgt32	%f4, %S1, %x2		/*  FPM				*/;	\
+	add		%sum, %x6, %sum		/*  IEU0	Group		*/;	\
+	fzero		%fz			/*  FPA				*/;	\
+	fcmpgt32	%f8, %S2, %x3		/*  FPM				*/;	\
+	inc		%x7			/*  IEU0	Group		*/;	\
+	inc		%x8			/*  IEU1			*/;	\
+	srl		%x7, 1, %x7		/*  IEU0	Group		*/;	\
+	inc		%x1			/*  IEU1			*/;	\
+	fpadd32		%S0, %S1, %T0		/*  FPA				*/;	\
+	fpadd32		%S2, %S3, %T1		/*  FPA		Group		*/;	\
+	add		%sum, %x7, %sum		/*  IEU0			*/;	\
+	fcmpgt32	%f12, %S3, %x4		/*  FPM				*/;	\
+	srl		%x8, 1, %x8		/*  IEU0	Group		*/;	\
+	inc		%x2			/*  IEU1			*/;	\
+	srl		%x1, 1, %x1		/*  IEU0	Group		*/;	\
+	add		%sum, %x8, %sum		/*  IEU1			*/;	\
+	add		%sum, %x1, %sum		/*  IEU0	Group		*/;	\
+	fcmpgt32	%S0, %T0, %x5		/*  FPM				*/;	\
+	srl		%x2, 1, %x2		/*  IEU0	Group		*/;	\
+	fcmpgt32	%S2, %T1, %x6		/*  FPM				*/;	\
+	inc		%x3			/*  IEU0	Group		*/;	\
+	add		%sum, %x2, %sum		/*  IEU1			*/;	\
+	srl		%x3, 1, %x3		/*  IEU0	Group		*/;	\
+	inc		%x4			/*  IEU1			*/;	\
+	fpadd32		%T0, %T1, %U0		/*  FPA		Group		*/;	\
+	add		%sum, %x3, %sum		/*  IEU0			*/;	\
+	fcmpgt32	%fz, %f2, %x7		/*  FPM				*/;	\
+	srl		%x4, 1, %x4		/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %f6, %x8		/*  FPM				*/;	\
+	inc		%x5			/*  IEU0	Group		*/;	\
+	add		%sum, %x4, %sum		/*  IEU1			*/;	\
+	srl		%x5, 1, %x5		/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %f10, %x1		/*  FPM				*/;	\
+	inc		%x6			/*  IEU0	Group		*/;	\
+	add		%sum, %x5, %sum		/*  IEU1			*/;	\
+	fmovd		%FA, %FB		/*  FPA		Group		*/;	\
+	fcmpgt32	%fz, %f14, %x2		/*  FPM				*/;	\
+	srl		%x6, 1, %x6		/*  IEU0	Group		*/;	\
+	ba,pt		%xcc, ett		/*  CTI				*/;	\
+	 inc		%x7			/*  IEU1			*/;
 
-#define END_THE_TRICK1(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB) 					\
+#define END_THE_TRICK1(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB) 				\
 	END_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB,f48,f50,f52,f54,f56,f58,f60,f62)
 
-#define END_THE_TRICK2(S0,S1,S2,S3,T0,T1,U0,U1,V0,fz) 						\
-	fpadd32		%U0, %U1, %V0		/*  FPA		Group			*/;	\
-	srl		%x7, 1, %x7		/*  IEU0				*/;	\
-	add		%sum, %x6, %sum		/*  IEU1				*/;	\
-	std		%V0, [%sp + STACKOFF]	/*  Store	Group			*/;	\
-	inc		%x8			/*  IEU0				*/;	\
-	sub		%sum, %x7, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %S1, %x3		/*  FPM		Group			*/;	\
-	srl		%x8, 1, %x8		/*  IEU0				*/;	\
-	inc		%x1			/*  IEU1				*/;	\
-	fcmpgt32	%fz, %S3, %x4		/*  FPM		Group			*/;	\
-	srl		%x1, 1, %x1		/*  IEU0				*/;	\
-	sub		%sum, %x8, %sum		/*  IEU1				*/;	\
-	ldx		[%sp + STACKOFF], %x8	/*  Load	Group			*/;	\
-	inc		%x2			/*  IEU0				*/;	\
-	sub		%sum, %x1, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %T1, %x5		/*  FPM		Group			*/;	\
-	srl		%x2, 1, %x2		/*  IEU0				*/;	\
-	inc		%x3			/*  IEU1				*/;	\
-	fcmpgt32	%T0, %U0, %x6		/*  FPM		Group			*/;	\
-	srl		%x3, 1, %x3		/*  IEU0				*/;	\
-	sub		%sum, %x2, %sum		/*  IEU1				*/;	\
-	inc		%x4			/*  IEU0	Group			*/;	\
-	sub		%sum, %x3, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %U1, %x7		/*  FPM		Group			*/;	\
-	srl		%x4, 1, %x4		/*  IEU0				*/;	\
-	inc		%x5			/*  IEU1				*/;	\
-	fcmpgt32	%U0, %V0, %x1		/*  FPM		Group			*/;	\
-	srl		%x5, 1, %x5		/*  IEU0				*/;	\
-	sub		%sum, %x4, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %V0, %x2		/*  FPM		Group			*/;	\
-	inc		%x6			/*  IEU0				*/;	\
-	sub		%sum, %x5, %sum		/*  IEU1				*/;	\
-	srl		%x6, 1, %x6		/*  IEU0	Group			*/;	\
-	inc		%x7			/*  IEU1				*/;	\
-	srl		%x7, 1, %x7		/*  IEU0	Group			*/;	\
-	add		%sum, %x6, %sum		/*  IEU1				*/;	\
-	inc		%x1			/*  IEU0	Group			*/;	\
-	sub		%sum, %x7, %sum		/*  IEU1				*/;	\
-	srl		%x1, 1, %x1		/*  IEU0	Group			*/;	\
-	inc		%x2			/*  IEU1				*/;	\
-	srl		%x2, 1, %x2		/*  IEU0	Group			*/;	\
-	add		%sum, %x1, %sum		/*  IEU1				*/;	\
-	sub		%sum, %x2, %sum		/*  IEU0	Group			*/;	\
-	addcc		%sum, %x8, %sum		/*  IEU		Group			*/;	\
-	bcs,a,pn	%xcc, 33f		/*  CTI					*/;	\
-	 add		%sum, 1, %sum		/*  IEU0				*/;	\
-33:						/*  That's it				*/;
+#define END_THE_TRICK2(S0,S1,S2,S3,T0,T1,U0,U1,V0,fz) 					\
+	fpadd32		%U0, %U1, %V0		/*  FPA		Group		*/;	\
+	srl		%x7, 1, %x7		/*  IEU0			*/;	\
+	add		%sum, %x6, %sum		/*  IEU1			*/;	\
+	std		%V0, [%sp + STACKOFF]	/*  Store	Group		*/;	\
+	inc		%x8			/*  IEU0			*/;	\
+	sub		%sum, %x7, %sum		/*  IEU1			*/;	\
+	srl		%x8, 1, %x8		/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %S1, %x3		/*  FPM				*/;	\
+	inc		%x1			/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %S3, %x4		/*  FPM				*/;	\
+	srl		%x1, 1, %x1		/*  IEU0	Group		*/;	\
+	sub		%sum, %x8, %sum		/*  IEU1			*/;	\
+	ldx		[%sp + STACKOFF], %x8	/*  Load	Group		*/;	\
+	inc		%x2			/*  IEU0			*/;	\
+	sub		%sum, %x1, %sum		/*  IEU1			*/;	\
+	srl		%x2, 1, %x2		/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %T1, %x5		/*  FPM				*/;	\
+	inc		%x3			/*  IEU0	Group		*/;	\
+	fcmpgt32	%T0, %U0, %x6		/*  FPM				*/;	\
+	srl		%x3, 1, %x3		/*  IEU0	Group		*/;	\
+	sub		%sum, %x2, %sum		/*  IEU1			*/;	\
+	inc		%x4			/*  IEU0	Group		*/;	\
+	sub		%sum, %x3, %sum		/*  IEU1			*/;	\
+	srl		%x4, 1, %x4		/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %U1, %x7		/*  FPM				*/;	\
+	inc		%x5			/*  IEU0	Group		*/;	\
+	fcmpgt32	%U0, %V0, %x1		/*  FPM				*/;	\
+	srl		%x5, 1, %x5		/*  IEU0	Group		*/;	\
+	sub		%sum, %x4, %sum		/*  IEU1			*/;	\
+	sub		%sum, %x5, %sum		/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %V0, %x2		/*  FPM				*/;	\
+	inc		%x6			/*  IEU0	Group		*/;	\
+	inc		%x7			/*  IEU1			*/;	\
+	srl		%x6, 1, %x6		/*  IEU0	Group		*/;	\
+	inc		%x1			/*  IEU1			*/;	\
+	srl		%x7, 1, %x7		/*  IEU0	Group		*/;	\
+	add		%sum, %x6, %sum		/*  IEU1			*/;	\
+	srl		%x1, 1, %x1		/*  IEU0	Group		*/;	\
+	sub		%sum, %x7, %sum		/*  IEU1			*/;	\
+	inc		%x2			/*  IEU0	Group		*/;	\
+	add		%sum, %x1, %sum		/*  IEU1			*/;	\
+	srl		%x2, 1, %x2		/*  IEU0	Group		*/;	\
+	sub		%sum, %x2, %sum		/*  IEU0	Group		*/;	\
+	addcc		%sum, %x8, %sum		/*  IEU1	Group		*/;	\
+	bcs,a,pn	%xcc, 33f		/*  CTI				*/;	\
+	 add		%sum, 1, %sum		/*  IEU0	(Group)		*/;	\
+33:						/*  That's it			*/;
 
 	.text
 	.globl		csum_partial_copy_vis
 	.align		32
-/* %asi should be either ASI_P or ASI_AIUS for csum_partial_copy resp. csum_partial_copy_from_user */
-/* This assumes that !((%src^%dst)&3) && !((%src|%dst)&1) && %len >= 256 */
+/* %asi should be either ASI_P or ASI_AIUS for csum_partial_copy resp.
+ * csum_partial_copy_from_user
+ * This assumes that !((%src^%dst)&3) && !((%src|%dst)&1) && %len >= 256
+ */
 csum_partial_copy_vis:
-	andcc		%dst, 7, %g0		/*  IEU1	Group			*/
-	be,pt		%icc, 4f		/*  CTI					*/
-	 and		%dst, 0x38, %o4		/*  IEU0				*/
-	mov		1, %g5			/*  IEU0	Group			*/
-	andcc		%dst, 2, %g0		/*  IEU1				*/
-	be,pt		%icc, 1f		/*  CTI					*/
-	 and		%dst, 4, %g7		/*  IEU0	Group			*/
-	lduha		[%src] %asi, %g2	/*  Load				*/
-	sub		%len, 2, %len		/*  IEU0	Group			*/
-	add		%dst, 2, %dst		/*  IEU1				*/
-	andcc		%dst, 4, %g7		/*  IEU1	Group			*/
-	sll		%g5, 16, %g5		/*  IEU0				*/
-	sth		%g2, [%dst - 2]		/*  Store	Group			*/
-	sll		%g2, 16, %g2		/*  IEU0	 			*/
-	add		%src, 2, %src		/*  IEU1				*/
-	addcc		%g2, %sum, %sum		/*  IEU1	Group			*/
-	bcs,a,pn	%icc, 1f		/*  CTI					*/
-	 add		%sum, %g5, %sum		/*  IEU0				*/
-1:	lduwa		[%src] %asi, %g2	/*  Load				*/
-	brz,a,pn	%g7, 4f			/*  CTI+IEU1	Group			*/
-	 and		%dst, 0x38, %o4		/*  IEU0				*/
-	add		%dst, 4, %dst		/*  IEU0	Group			*/
-	sub		%len, 4, %len		/*  IEU1				*/
-	addcc		%g2, %sum, %sum		/*  IEU1	Group			*/
-	bcs,a,pn	%icc, 1f		/*  CTI					*/
-	 add		%sum, 1, %sum		/*  IEU0				*/
-1:	and		%dst, 0x38, %o4		/*  IEU0	Group			*/
-	stw		%g2, [%dst - 4]		/*  Store				*/
-	add		%src, 4, %src		/*  IEU1				*/
+	andcc		%dst, 7, %g0		/*  IEU1	Group		*/
+	be,pt		%icc, 4f		/*  CTI				*/
+	 and		%dst, 0x38, %o4		/*  IEU0			*/
+	mov		1, %g5			/*  IEU0	Group		*/
+	andcc		%dst, 2, %g0		/*  IEU1			*/
+	be,pt		%icc, 1f		/*  CTI				*/
+	 and		%dst, 4, %g7		/*  IEU0	Group		*/
+	lduha		[%src] %asi, %g2	/*  Load			*/
+	sub		%len, 2, %len		/*  IEU0	Group		*/
+	add		%dst, 2, %dst		/*  IEU1			*/
+	andcc		%dst, 4, %g7		/*  IEU1	Group		*/
+	sll		%g5, 16, %g5		/*  IEU0			*/
+	sth		%g2, [%dst - 2]		/*  Store	Group		*/
+	sll		%g2, 16, %g2		/*  IEU0	 		*/
+	add		%src, 2, %src		/*  IEU1			*/
+	addcc		%g2, %sum, %sum		/*  IEU1	Group		*/
+	bcs,a,pn	%icc, 1f		/*  CTI				*/
+	 add		%sum, %g5, %sum		/*  IEU0			*/
+1:	lduwa		[%src] %asi, %g2	/*  Load			*/
+	brz,a,pn	%g7, 4f			/*  CTI+IEU1	Group		*/
+	 and		%dst, 0x38, %o4		/*  IEU0			*/
+	add		%dst, 4, %dst		/*  IEU0	Group		*/
+	sub		%len, 4, %len		/*  IEU1			*/
+	addcc		%g2, %sum, %sum		/*  IEU1	Group		*/
+	bcs,a,pn	%icc, 1f		/*  CTI				*/
+	 add		%sum, 1, %sum		/*  IEU0			*/
+1:	and		%dst, 0x38, %o4		/*  IEU0	Group		*/
+	stw		%g2, [%dst - 4]		/*  Store			*/
+	add		%src, 4, %src		/*  IEU1			*/
 4:
 #ifdef __KERNEL__
 	VISEntry
 #endif
-	mov		%src, %g7		/*  IEU1	Group			*/
-	fzero		%f48			/*  FPA					*/
-	alignaddr	%src, %g0, %src		/*  Single	Group			*/
-	subcc		%g7, %src, %g7		/*  IEU1	Group			*/
-	be,pt		%xcc, 1f		/*  CTI					*/
-	 mov		0x40, %g1		/*  IEU0				*/
-	lduwa		[%src] %asi, %g2	/*  Load	Group			*/
-	subcc		%sum, %g2, %sum		/*  IEU1	Group+load stall	*/
-	bcs,a,pn	%icc, 1f		/*  CTI					*/
-	 sub		%sum, 1, %sum		/*  IEU0				*/
-1:	srl		%sum, 0, %sum		/*  IEU0	Group			*/
-	clr		%g5			/*  IEU1				*/
-	brz,pn		%o4, 3f			/*  CTI+IEU1	Group			*/
-	 sub		%g1, %o4, %g1		/*  IEU0				*/
-	ldda		[%src] %asi, %f0	/*  Load				*/
-	clr		%o4			/*  IEU0	Group			*/
-	andcc		%dst, 8, %g0		/*  IEU1				*/
-	be,pn		%icc, 1f		/*  CTI					*/
-	 ldda		[%src + 8] %asi, %f2	/*  Load	Group			*/
-	add		%src, 8, %src		/*  IEU0				*/
-	sub		%len, 8, %len		/*  IEU1				*/
-	fpadd32		%f0, %f48, %f50		/*  FPA					*/
-	addcc		%dst, 8, %dst		/*  IEU1	Group			*/
-	faligndata	%f0, %f2, %f16		/*  FPA					*/
-	fcmpgt32	%f48, %f50, %o4		/*  FPM		Group			*/
-	fmovd		%f2, %f0		/*  FPA		Group			*/
-	ldda		[%src + 8] %asi, %f2	/*  Load				*/
-	std		%f16, [%dst - 8]	/*  Store				*/
-	fmovd		%f50, %f48		/*  FPA					*/
-1:	andcc		%g1, 0x10, %g0		/*  IEU1	Group			*/
-	be,pn		%icc, 1f		/*  CTI					*/
-	 and		%g1, 0x20, %g1		/*  IEU0				*/
-	fpadd32		%f0, %f48, %f50		/*  FPA					*/
-	ldda		[%src + 16] %asi, %f4	/*  Load	Group			*/
-	add		%src, 16, %src		/*  IEU0				*/
-	add		%dst, 16, %dst		/*  IEU1				*/
-	faligndata	%f0, %f2, %f16		/*  FPA					*/
-	fcmpgt32	%f48, %f50, %g5		/*  FPM		Group			*/
-	sub		%len, 16, %len		/*  IEU0				*/
-	inc		%o4			/*  IEU1				*/
-	std		%f16, [%dst - 16]	/*  Store	Group			*/
-	fpadd32		%f2, %f50, %f48		/*  FPA					*/
-	srl		%o4, 1, %o5		/*  IEU0				*/
-	faligndata	%f2, %f4, %f18		/*  FPA		Group			*/
-	std		%f18, [%dst - 8]	/*  Store				*/
-	fcmpgt32	%f50, %f48, %o4		/*  FPM		Group			*/
-	add		%o5, %sum, %sum		/*  IEU0				*/
-	ldda		[%src + 8] %asi, %f2	/*  Load				*/
-	fmovd		%f4, %f0		/*  FPA					*/
-1:	brz,a,pn	%g1, 4f			/*  CTI+IEU1	Group			*/
-	 rd		%asi, %g2		/*  LSU		Group + 4 bubbles	*/
-	inc		%g5			/*  IEU0				*/
-	fpadd32		%f0, %f48, %f50		/*  FPA					*/
-	ldda		[%src + 16] %asi, %f4	/*  Load	Group			*/
-	srl		%g5, 1, %g5		/*  IEU0				*/
-	add		%dst, 32, %dst		/*  IEU1				*/
-	faligndata	%f0, %f2, %f16		/*  FPA					*/
-	fcmpgt32	%f48, %f50, %o5		/*  FPM		Group			*/
-	inc		%o4			/*  IEU0				*/
-	ldda		[%src + 24] %asi, %f6	/*  Load				*/
-	srl		%o4, 1, %o4		/*  IEU0	Group			*/
-	add		%g5, %sum, %sum		/*  IEU1				*/
-	ldda		[%src + 32] %asi, %f8	/*  Load				*/
-	fpadd32		%f2, %f50, %f48		/*  FPA					*/
-	faligndata	%f2, %f4, %f18		/*  FPA		Group			*/
-	sub		%len, 32, %len		/*  IEU0				*/
-	std		%f16, [%dst - 32]	/*  Store				*/
-	fcmpgt32	%f50, %f48, %g3		/*  FPM		Group			*/
-	inc		%o5			/*  IEU0				*/
-	add		%o4, %sum, %sum		/*  IEU1				*/
-	fpadd32		%f4, %f48, %f50		/*  FPA					*/
-	faligndata	%f4, %f6, %f20		/*  FPA		Group			*/
-	srl		%o5, 1, %o5		/*  IEU0				*/
-	fcmpgt32	%f48, %f50, %g5		/*  FPM		Group			*/
-	add		%o5, %sum, %sum		/*  IEU0				*/
-	std		%f18, [%dst - 24]	/*  Store				*/
-	fpadd32		%f6, %f50, %f48		/*  FPA					*/
-	inc		%g3			/*  IEU0	Group			*/
-	std		%f20, [%dst - 16]	/*  Store				*/
-	add		%src, 32, %src		/*  IEU1				*/
-	faligndata	%f6, %f8, %f22		/*  FPA					*/
-	fcmpgt32	%f50, %f48, %o4		/*  FPM		Group			*/
-	srl		%g3, 1, %g3		/*  IEU0				*/
-	std		%f22, [%dst - 8]	/*  Store				*/	
-	add		%g3, %sum, %sum		/*  IEU0	Group			*/
-3:	rd		%asi, %g2		/*  LSU		Group + 4 bubbles	*/
+	mov		%src, %g7		/*  IEU1	Group		*/
+	fzero		%f48			/*  FPA				*/
+	alignaddr	%src, %g0, %src		/*  Single	Group		*/
+	subcc		%g7, %src, %g7		/*  IEU1	Group		*/
+	be,pt		%xcc, 1f		/*  CTI				*/
+	 mov		0x40, %g1		/*  IEU0			*/
+	lduwa		[%src] %asi, %g2	/*  Load	Group		*/
+	subcc		%sum, %g2, %sum		/*  IEU1	Group+load stall*/
+	bcs,a,pn	%icc, 1f		/*  CTI				*/
+	 sub		%sum, 1, %sum		/*  IEU0			*/
+1:	srl		%sum, 0, %sum		/*  IEU0	Group		*/
+	clr		%g5			/*  IEU1			*/
+	brz,pn		%o4, 3f			/*  CTI+IEU1	Group		*/
+	 sub		%g1, %o4, %g1		/*  IEU0			*/
+	ldda		[%src] %asi, %f0	/*  Load			*/
+	clr		%o4			/*  IEU0	Group		*/
+	andcc		%dst, 8, %g0		/*  IEU1			*/
+	be,pn		%icc, 1f		/*  CTI				*/
+	 ldda		[%src + 8] %asi, %f2	/*  Load	Group		*/
+	add		%src, 8, %src		/*  IEU0			*/
+	sub		%len, 8, %len		/*  IEU1			*/
+	fpadd32		%f0, %f48, %f50		/*  FPA				*/
+	addcc		%dst, 8, %dst		/*  IEU1	Group		*/
+	faligndata	%f0, %f2, %f16		/*  FPA				*/
+	fcmpgt32	%f48, %f50, %o4		/*  FPM		Group		*/
+	fmovd		%f2, %f0		/*  FPA		Group		*/
+	ldda		[%src + 8] %asi, %f2	/*  Load			*/
+	std		%f16, [%dst - 8]	/*  Store			*/
+	fmovd		%f50, %f48		/*  FPA				*/
+1:	andcc		%g1, 0x10, %g0		/*  IEU1	Group		*/
+	be,pn		%icc, 1f		/*  CTI				*/
+	 and		%g1, 0x20, %g1		/*  IEU0			*/
+	fpadd32		%f0, %f48, %f50		/*  FPA				*/
+	ldda		[%src + 16] %asi, %f4	/*  Load	Group		*/
+	add		%src, 16, %src		/*  IEU0			*/
+	add		%dst, 16, %dst		/*  IEU1			*/
+	faligndata	%f0, %f2, %f16		/*  FPA				*/
+	fcmpgt32	%f48, %f50, %g5		/*  FPM		Group		*/
+	sub		%len, 16, %len		/*  IEU0			*/
+	inc		%o4			/*  IEU1			*/
+	std		%f16, [%dst - 16]	/*  Store	Group		*/
+	fpadd32		%f2, %f50, %f48		/*  FPA				*/
+	srl		%o4, 1, %o5		/*  IEU0			*/
+	faligndata	%f2, %f4, %f18		/*  FPA		Group		*/
+	std		%f18, [%dst - 8]	/*  Store			*/
+	fcmpgt32	%f50, %f48, %o4		/*  FPM		Group		*/
+	add		%o5, %sum, %sum		/*  IEU0			*/
+	ldda		[%src + 8] %asi, %f2	/*  Load			*/
+	fmovd		%f4, %f0		/*  FPA				*/
+1:	brz,a,pn	%g1, 4f			/*  CTI+IEU1	Group		*/
+	 rd		%asi, %g2		/*  LSU		Group + 4 bubbles*/
+	inc		%g5			/*  IEU0			*/
+	fpadd32		%f0, %f48, %f50		/*  FPA				*/
+	ldda		[%src + 16] %asi, %f4	/*  Load	Group		*/
+	srl		%g5, 1, %g5		/*  IEU0			*/
+	add		%dst, 32, %dst		/*  IEU1			*/
+	faligndata	%f0, %f2, %f16		/*  FPA				*/
+	fcmpgt32	%f48, %f50, %o5		/*  FPM		Group		*/
+	inc		%o4			/*  IEU0			*/
+	ldda		[%src + 24] %asi, %f6	/*  Load			*/
+	srl		%o4, 1, %o4		/*  IEU0	Group		*/
+	add		%g5, %sum, %sum		/*  IEU1			*/
+	ldda		[%src + 32] %asi, %f8	/*  Load			*/
+	fpadd32		%f2, %f50, %f48		/*  FPA				*/
+	faligndata	%f2, %f4, %f18		/*  FPA		Group		*/
+	sub		%len, 32, %len		/*  IEU0			*/
+	std		%f16, [%dst - 32]	/*  Store			*/
+	fcmpgt32	%f50, %f48, %g3		/*  FPM		Group		*/
+	inc		%o5			/*  IEU0			*/
+	add		%o4, %sum, %sum		/*  IEU1			*/
+	fpadd32		%f4, %f48, %f50		/*  FPA				*/
+	faligndata	%f4, %f6, %f20		/*  FPA		Group		*/
+	srl		%o5, 1, %o5		/*  IEU0			*/
+	fcmpgt32	%f48, %f50, %g5		/*  FPM		Group		*/
+	add		%o5, %sum, %sum		/*  IEU0			*/
+	std		%f18, [%dst - 24]	/*  Store			*/
+	fpadd32		%f6, %f50, %f48		/*  FPA				*/
+	inc		%g3			/*  IEU0	Group		*/
+	std		%f20, [%dst - 16]	/*  Store			*/
+	add		%src, 32, %src		/*  IEU1			*/
+	faligndata	%f6, %f8, %f22		/*  FPA				*/
+	fcmpgt32	%f50, %f48, %o4		/*  FPM		Group		*/
+	srl		%g3, 1, %g3		/*  IEU0			*/
+	std		%f22, [%dst - 8]	/*  Store			*/	
+	add		%g3, %sum, %sum		/*  IEU0	Group		*/
+3:	rd		%asi, %g2		/*  LSU		Group + 4 bubbles*/
 #ifdef __KERNEL__
-4:	sethi		%hi(vis0s), %g7		/*  IEU0	Group			*/
-	or		%g2, ASI_BLK_OR, %g2	/*  IEU1				*/
+4:	sethi		%hi(vis0s), %g7		/*  IEU0	Group		*/
+	or		%g2, ASI_BLK_OR, %g2	/*  IEU1			*/
 #else
-4:	rd		%pc, %g7		/*  LSU		Group + 4 bubbles	*/
+4:	rd		%pc, %g7		/*  LSU		Group + 4 bubbles*/
 #endif
-	inc		%g5			/*  IEU0	Group			*/
-	and		%src, 0x38, %g3		/*  IEU1				*/	
-	membar		#StoreLoad		/*  LSU		Group			*/
-	srl		%g5, 1, %g5		/*  IEU0				*/
-	inc		%o4			/*  IEU1				*/
-	sll		%g3, 8, %g3		/*  IEU0	Group			*/
-	sub		%len, 0xc0, %len	/*  IEU1				*/
-	addcc		%g5, %sum, %sum		/*  IEU1	Group			*/
-	srl		%o4, 1, %o4		/*  IEU0				*/
-	add		%g7, %g3, %g7		/*  IEU0	Group			*/
-	add		%o4, %sum, %sum		/*  IEU1				*/
+	inc		%g5			/*  IEU0	Group		*/
+	and		%src, 0x38, %g3		/*  IEU1			*/	
+	membar		#StoreLoad		/*  LSU		Group		*/
+	srl		%g5, 1, %g5		/*  IEU0			*/
+	inc		%o4			/*  IEU1			*/
+	sll		%g3, 8, %g3		/*  IEU0	Group		*/
+	sub		%len, 0xc0, %len	/*  IEU1			*/
+	addcc		%g5, %sum, %sum		/*  IEU1	Group		*/
+	srl		%o4, 1, %o4		/*  IEU0			*/
+	add		%g7, %g3, %g7		/*  IEU0	Group		*/
+	add		%o4, %sum, %sum		/*  IEU1			*/
 #ifdef __KERNEL__
-	jmpl		%g7 + %lo(vis0s), %g0	/*  CTI+IEU1	Group			*/
+	jmpl		%g7 + %lo(vis0s), %g0	/*  CTI+IEU1	Group		*/
 #else
-	jmpl		%g7 + (vis0s - 4b), %g0	/*  CTI+IEU1	Group			*/
+	jmpl		%g7 + (vis0s - 4b), %g0	/*  CTI+IEU1	Group		*/
 #endif
-	 fzero		%f32			/*  FPA					*/
+	 fzero		%f32			/*  FPA				*/
 
 	.align		2048
-vis0s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	add		%src, 128, %src		/*  IEU0	Group			*/
-	ldda		[%src-128] %asi, %f0	/*  Load	Group			*/
-	ldda		[%src-64] %asi, %f16	/*  Load	Group			*/
-	fmovd		%f48, %f62		/*  FPA		Group	f0 available	*/
-	faligndata	%f0, %f2, %f48		/*  FPA		Group	f2 available	*/
-	fcmpgt32	%f32, %f2, %x1		/*  FPM		Group	f4 available	*/
-	fpadd32		%f0, %f62, %f0		/*  FPA					*/
-	fcmpgt32	%f32, %f4, %x2		/*  FPM		Group	f6 available	*/
-	faligndata	%f2, %f4, %f50		/*  FPA					*/
-	fcmpgt32	%f62, %f0, %x3		/*  FPM		Group	f8 available	*/
-	faligndata	%f4, %f6, %f52		/*  FPA					*/
-	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group	f10 available	*/
-	inc		%x1			/*  IEU0				*/
-	faligndata	%f6, %f8, %f54		/*  FPA					*/
-	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group	f12 available	*/
-	srl		%x1, 1, %x1		/*  IEU0				*/
-	inc		%x2			/*  IEU1				*/
-	faligndata	%f8, %f10, %f56		/*  FPA					*/
-	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group	f14 available	*/
-	srl		%x2, 1, %x2		/*  IEU0				*/
-	add		%sum, %x1, %sum		/*  IEU1				*/
-	faligndata	%f10, %f12, %f58	/*  FPA					*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	inc		%x3			/*  IEU0				*/
-	add		%sum, %x2, %sum		/*  IEU1				*/
-	faligndata	%f12, %f14, %f60	/*  FPA					*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	srl		%x3, 1, %x3		/*  IEU0				*/
-	inc		%x4			/*  IEU1				*/
-	fmovd		%f14, %f62		/*  FPA					*/
-	srl		%x4, 1, %x4		/*  IEU0	Group			*/
-	add		%sum, %x3, %sum		/*  IEU1				*/
+vis0s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	add		%src, 128, %src		/*  IEU0	Group		*/
+	ldda		[%src-128] %asi, %f0	/*  Load	Group		*/
+	ldda		[%src-64] %asi, %f16	/*  Load	Group		*/
+	fmovd		%f48, %f62		/*  FPA		Group	f0 available*/
+	faligndata	%f0, %f2, %f48		/*  FPA		Group	f2 available*/
+	fcmpgt32	%f32, %f2, %x1		/*  FPM		Group	f4 available*/
+	fpadd32		%f0, %f62, %f0		/*  FPA				*/
+	fcmpgt32	%f32, %f4, %x2		/*  FPM		Group	f6 available*/
+	faligndata	%f2, %f4, %f50		/*  FPA				*/
+	fcmpgt32	%f62, %f0, %x3		/*  FPM		Group	f8 available*/
+	faligndata	%f4, %f6, %f52		/*  FPA				*/
+	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group	f10 available*/
+	inc		%x1			/*  IEU0			*/
+	faligndata	%f6, %f8, %f54		/*  FPA				*/
+	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group	f12 available*/
+	srl		%x1, 1, %x1		/*  IEU0			*/
+	inc		%x2			/*  IEU1			*/
+	faligndata	%f8, %f10, %f56		/*  FPA				*/
+	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group	f14 available*/
+	srl		%x2, 1, %x2		/*  IEU0			*/
+	add		%sum, %x1, %sum		/*  IEU1			*/
+	faligndata	%f10, %f12, %f58	/*  FPA				*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	inc		%x3			/*  IEU0			*/
+	add		%sum, %x2, %sum		/*  IEU1			*/
+	faligndata	%f12, %f14, %f60	/*  FPA				*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	srl		%x3, 1, %x3		/*  IEU0			*/
+	inc		%x4			/*  IEU1			*/
+	fmovd		%f14, %f62		/*  FPA				*/
+	srl		%x4, 1, %x4		/*  IEU0	Group		*/
+	add		%sum, %x3, %sum		/*  IEU1			*/
 vis0:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
-			,f48,f50,f52,f54,f56,f58,f60,f62,f62,								
-			,LDBLK(f32),	STBLK,,,,,,,,									
+			,f48,f50,f52,f54,f56,f58,f60,f62,f62,
+			,LDBLK(f32),	STBLK,,,,,,,,
 			,bcs,pn %icc, vis0e1)
 	DO_THE_TRICK(	f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
-			,f48,f50,f52,f54,f56,f58,f60,f62,f62,								
-			,LDBLK(f0),	STBLK,,,,,,,,									
+			,f48,f50,f52,f54,f56,f58,f60,f62,f62,
+			,LDBLK(f0),	STBLK,,,,,,,,
 			,bcs,pn %icc, vis0e2)
-	DO_THE_TRICK(	f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,	
+	DO_THE_TRICK(	f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
 			,f48,f50,f52,f54,f56,f58,f60,f62,f62,
 			,LDBLK(f16),	STBLK,,,,,,,,
 			,bcc,pt %icc, vis0)
-vis0e3:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
+vis0e3:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
 			,f48,f50,f52,f54,f56,f58,f60,f62,f32,
 			,SYNC,		STBLK,ST(f48,64),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),ST(f60,48),
 			,add %dst, 56, %dst; add %len, 192 - 8*8, %len; ba,pt %icc, e2)
@@ -447,39 +449,39 @@
 			,f48,f50,f52,f54,f56,f58,f60,f62,f0,
 			,SYNC,		STBLK,ST(f48,64),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),ST(f60,48),
 			,add %dst, 56, %dst; add %len, 192 - 8*8, %len; ba,pt %icc, e3)
-vis0e2:	DO_THE_TRICK(	f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,	
+vis0e2:	DO_THE_TRICK(	f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
 			,f48,f50,f52,f54,f56,f58,f60,f62,f16,
 			,SYNC,		STBLK,ST(f48,64),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),ST(f60,48),
 			,add %dst, 56, %dst; add %len, 192 - 8*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis1s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	add		%src, 128 - 8, %src	/*  IEU0	Group			*/
-	ldda		[%src-128] %asi, %f0	/*  Load	Group			*/
-	ldda		[%src-64] %asi, %f16	/*  Load	Group			*/
-	fmovd		%f0, %f58		/*  FPA		Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/
-	fcmpgt32	%f32, %f2, %x2		/*  FPM		Group			*/
-	faligndata	%f2, %f4, %f48		/*  FPA					*/
-	fcmpgt32	%f32, %f4, %x3		/*  FPM		Group			*/
-	faligndata	%f4, %f6, %f50		/*  FPA					*/
-	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group			*/
-	faligndata	%f6, %f8, %f52		/*  FPA					*/
-	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group			*/
-	inc		%x2			/*  IEU1				*/
-	faligndata	%f8, %f10, %f54		/*  FPA					*/
-	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group			*/
-	srl		%x2, 1, %x2		/*  IEU0				*/
-	faligndata	%f10, %f12, %f56	/*  FPA					*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	inc		%x3			/*  IEU0				*/
-	add		%sum, %x2, %sum		/*  IEU1				*/
-	faligndata	%f12, %f14, %f58	/*  FPA					*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	srl		%x3, 1, %x3		/*  IEU0				*/
-	inc		%x4			/*  IEU1				*/
-	fmovd		%f14, %f60		/*  FPA					*/
-	srl		%x4, 1, %x4		/*  IEU0	Group			*/
-	add		%sum, %x3, %sum		/*  IEU1				*/
+vis1s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	add		%src, 128 - 8, %src	/*  IEU0	Group		*/
+	ldda		[%src-128] %asi, %f0	/*  Load	Group		*/
+	ldda		[%src-64] %asi, %f16	/*  Load	Group		*/
+	fmovd		%f0, %f58		/*  FPA		Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/
+	fcmpgt32	%f32, %f2, %x2		/*  FPM		Group		*/
+	faligndata	%f2, %f4, %f48		/*  FPA				*/
+	fcmpgt32	%f32, %f4, %x3		/*  FPM		Group		*/
+	faligndata	%f4, %f6, %f50		/*  FPA				*/
+	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group		*/
+	faligndata	%f6, %f8, %f52		/*  FPA				*/
+	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group		*/
+	inc		%x2			/*  IEU1			*/
+	faligndata	%f8, %f10, %f54		/*  FPA				*/
+	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group		*/
+	srl		%x2, 1, %x2		/*  IEU0			*/
+	faligndata	%f10, %f12, %f56	/*  FPA				*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	inc		%x3			/*  IEU0			*/
+	add		%sum, %x2, %sum		/*  IEU1			*/
+	faligndata	%f12, %f14, %f58	/*  FPA				*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	srl		%x3, 1, %x3		/*  IEU0			*/
+	inc		%x4			/*  IEU1			*/
+	fmovd		%f14, %f60		/*  FPA				*/
+	srl		%x4, 1, %x4		/*  IEU0	Group		*/
+	add		%sum, %x3, %sum		/*  IEU1			*/
 vis1:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f62,f48,f50,f52,f54,f56,f58,f60,f60,
 			,LDBLK(f32),	,STBLK,,,,,,,
@@ -505,31 +507,31 @@
 			,SYNC,		,STBLK,ST(f48,0),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),
 			,add %dst, 48, %dst; add %len, 192 - 7*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis2s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	add		%src, 128 - 16, %src	/*  IEU0	Group			*/
-	ldda		[%src-128] %asi, %f0	/*  Load	Group			*/
-	ldda		[%src-64] %asi, %f16	/*  Load	Group			*/
-	fmovd		%f0, %f56		/*  FPA		Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/	
-	sub		%dst, 64, %dst		/*  IEU0				*/
-	fpsub32		%f2, %f2, %f2		/*  FPA		Group			*/
-	fcmpgt32	%f32, %f4, %x3		/*  FPM		Group			*/
-	faligndata	%f4, %f6, %f48		/*  FPA					*/
-	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group			*/
-	faligndata	%f6, %f8, %f50		/*  FPA					*/
-	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group			*/
-	faligndata	%f8, %f10, %f52		/*  FPA					*/
-	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group			*/
-	faligndata	%f10, %f12, %f54	/*  FPA					*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	inc		%x3			/*  IEU0				*/
-	faligndata	%f12, %f14, %f56	/*  FPA					*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	srl		%x3, 1, %x3		/*  IEU0				*/
-	inc		%x4			/*  IEU1				*/
-	fmovd		%f14, %f58		/*  FPA					*/
-	srl		%x4, 1, %x4		/*  IEU0	Group			*/
-	add		%sum, %x3, %sum		/*  IEU1				*/
+vis2s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	add		%src, 128 - 16, %src	/*  IEU0	Group		*/
+	ldda		[%src-128] %asi, %f0	/*  Load	Group		*/
+	ldda		[%src-64] %asi, %f16	/*  Load	Group		*/
+	fmovd		%f0, %f56		/*  FPA		Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/	
+	sub		%dst, 64, %dst		/*  IEU0			*/
+	fpsub32		%f2, %f2, %f2		/*  FPA		Group		*/
+	fcmpgt32	%f32, %f4, %x3		/*  FPM		Group		*/
+	faligndata	%f4, %f6, %f48		/*  FPA				*/
+	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group		*/
+	faligndata	%f6, %f8, %f50		/*  FPA				*/
+	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group		*/
+	faligndata	%f8, %f10, %f52		/*  FPA				*/
+	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group		*/
+	faligndata	%f10, %f12, %f54	/*  FPA				*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	inc		%x3			/*  IEU0			*/
+	faligndata	%f12, %f14, %f56	/*  FPA				*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	srl		%x3, 1, %x3		/*  IEU0			*/
+	inc		%x4			/*  IEU1			*/
+	fmovd		%f14, %f58		/*  FPA				*/
+	srl		%x4, 1, %x4		/*  IEU0	Group		*/
+	add		%sum, %x3, %sum		/*  IEU1			*/
 vis2:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f60,f62,f48,f50,f52,f54,f56,f58,f58,
 			,LDBLK(f32),	,,STBLK,,,,,,
@@ -555,27 +557,27 @@
 			,SYNC,		,,STBLK,ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),ST(f56,96),
 			,add %dst, 104, %dst; add %len, 192 - 6*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis3s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	add		%src, 128 - 24, %src	/*  IEU0	Group			*/
-	ldda		[%src-128] %asi, %f0	/*  Load	Group			*/
-	ldda		[%src-64] %asi, %f16	/*  Load	Group			*/
-	fmovd		%f0, %f54		/*  FPA		Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/
-	sub		%dst, 64, %dst		/*  IEU0				*/
-	fpsub32		%f2, %f2, %f2		/*  FPA		Group			*/
-	fpsub32		%f4, %f4, %f4		/*  FPA		Group			*/
-	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group			*/
-	faligndata	%f6, %f8, %f48		/*  FPA					*/
-	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group			*/
-	faligndata	%f8, %f10, %f50		/*  FPA					*/
-	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group			*/
-	faligndata	%f10, %f12, %f52	/*  FPA					*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	faligndata	%f12, %f14, %f54	/*  FPA					*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	fmovd		%f14, %f56		/*  FPA					*/
-	inc		%x4			/*  IEU0				*/
-	srl		%x4, 1, %x4		/*  IEU0	Group			*/
+vis3s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	add		%src, 128 - 24, %src	/*  IEU0	Group		*/
+	ldda		[%src-128] %asi, %f0	/*  Load	Group		*/
+	ldda		[%src-64] %asi, %f16	/*  Load	Group		*/
+	fmovd		%f0, %f54		/*  FPA		Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/
+	sub		%dst, 64, %dst		/*  IEU0			*/
+	fpsub32		%f2, %f2, %f2		/*  FPA		Group		*/
+	fpsub32		%f4, %f4, %f4		/*  FPA		Group		*/
+	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group		*/
+	faligndata	%f6, %f8, %f48		/*  FPA				*/
+	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group		*/
+	faligndata	%f8, %f10, %f50		/*  FPA				*/
+	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group		*/
+	faligndata	%f10, %f12, %f52	/*  FPA				*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	faligndata	%f12, %f14, %f54	/*  FPA				*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	fmovd		%f14, %f56		/*  FPA				*/
+	inc		%x4			/*  IEU0			*/
+	srl		%x4, 1, %x4		/*  IEU0	Group		*/
 vis3:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f58,f60,f62,f48,f50,f52,f54,f56,f56,
 			,LDBLK(f32),	,,,STBLK,,,,,
@@ -601,25 +603,25 @@
 			,SYNC,		,,,STBLK,ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),
 			,add %dst, 96, %dst; add %len, 192 - 5*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis4s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	add		%src, 128 - 32, %src	/*  IEU0	Group			*/
-	ldda		[%src-128] %asi, %f0	/*  Load	Group			*/
-	ldda		[%src-64] %asi, %f16	/*  Load	Group			*/
-	fmovd		%f0, %f52		/*  FPA		Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/
-	sub		%dst, 64, %dst		/*  IEU0				*/
-	fpsub32		%f2, %f2, %f2		/*  FPA		Group			*/
-	fpsub32		%f4, %f4, %f4		/*  FPA		Group			*/
-	fpsub32		%f6, %f6, %f6		/*  FPA		Group			*/
-	clr		%x4			/*  IEU0				*/
-	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group			*/
-	faligndata	%f8, %f10, %f48		/*  FPA					*/
-	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group			*/
-	faligndata	%f10, %f12, %f50	/*  FPA					*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	faligndata	%f12, %f14, %f52	/*  FPA					*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	fmovd		%f14, %f54		/*  FPA					*/
+vis4s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	add		%src, 128 - 32, %src	/*  IEU0	Group		*/
+	ldda		[%src-128] %asi, %f0	/*  Load	Group		*/
+	ldda		[%src-64] %asi, %f16	/*  Load	Group		*/
+	fmovd		%f0, %f52		/*  FPA		Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/
+	sub		%dst, 64, %dst		/*  IEU0			*/
+	fpsub32		%f2, %f2, %f2		/*  FPA		Group		*/
+	fpsub32		%f4, %f4, %f4		/*  FPA		Group		*/
+	fpsub32		%f6, %f6, %f6		/*  FPA		Group		*/
+	clr		%x4			/*  IEU0			*/
+	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group		*/
+	faligndata	%f8, %f10, %f48		/*  FPA				*/
+	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group		*/
+	faligndata	%f10, %f12, %f50	/*  FPA				*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	faligndata	%f12, %f14, %f52	/*  FPA				*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	fmovd		%f14, %f54		/*  FPA				*/
 vis4:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f56,f58,f60,f62,f48,f50,f52,f54,f54,
 			,LDBLK(f32),	,,,,STBLK,,,,
@@ -645,26 +647,26 @@
 			,SYNC,		,,,,STBLK,ST(f48,64),ST(f50,72),ST(f52,80),
 			,add %dst, 88, %dst; add %len, 192 - 4*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis5s:	add		%src, 128 - 40, %src	/*  IEU0	Group			*/
-	ldda		[%src-88] %asi, %f10	/*  Load	Group			*/
-	ldda		[%src-80] %asi, %f12	/*  Load	Group			*/
-	ldda		[%src-72] %asi, %f14	/*  Load	Group			*/
-	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	ldda		[%src-64] %asi, %f16	/*  Load	Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f2		/*  FPM					*/
-	clr		%x4			/*  IEU0				*/
-	faddd		%f32, %f32, %f4		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f6		/*  FPM					*/
-	clr		%x5			/*  IEU0				*/
-	faddd		%f32, %f32, %f8		/*  FPA		Group			*/
-	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group			*/
-	sub		%dst, 64, %dst		/*  IEU0				*/
-	faligndata	%f10, %f12, %f48	/*  FPA					*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	faligndata	%f12, %f14, %f50	/*  FPA					*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	fmovd		%f14, %f52		/*  FPA					*/
+vis5s:	add		%src, 128 - 40, %src	/*  IEU0	Group		*/
+	ldda		[%src-88] %asi, %f10	/*  Load	Group		*/
+	ldda		[%src-80] %asi, %f12	/*  Load	Group		*/
+	ldda		[%src-72] %asi, %f14	/*  Load	Group		*/
+	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	ldda		[%src-64] %asi, %f16	/*  Load	Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f2		/*  FPM				*/
+	clr		%x4			/*  IEU0			*/
+	faddd		%f32, %f32, %f4		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f6		/*  FPM				*/
+	clr		%x5			/*  IEU0			*/
+	faddd		%f32, %f32, %f8		/*  FPA		Group		*/
+	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group		*/
+	sub		%dst, 64, %dst		/*  IEU0			*/
+	faligndata	%f10, %f12, %f48	/*  FPA				*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	faligndata	%f12, %f14, %f50	/*  FPA				*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	fmovd		%f14, %f52		/*  FPA				*/
 vis5:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f54,f56,f58,f60,f62,f48,f50,f52,f52,
 			,LDBLK(f32),	,,,,,STBLK,,,
@@ -690,25 +692,25 @@
 			,SYNC,		,,,,,STBLK,ST(f48,64),ST(f50,72),
 			,add %dst, 80, %dst; add %len, 192 - 3*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis6s:	add		%src, 128 - 48, %src	/*  IEU0	Group			*/
-	ldda		[%src-80] %asi, %f12	/*  Load	Group			*/
-	ldda		[%src-72] %asi, %f14	/*  Load	Group			*/
-	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	ldda		[%src-64] %asi, %f16	/*  Load	Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f2		/*  FPM					*/
-	clr		%x4			/*  IEU0				*/
-	faddd		%f32, %f32, %f4		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f6		/*  FPM					*/
-	clr		%x5			/*  IEU0				*/
-	faddd		%f32, %f32, %f8		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f10	/*  FPM					*/
-	clr		%x6			/*  IEU0				*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	sub		%dst, 64, %dst		/*  IEU0				*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	faligndata	%f12, %f14, %f48	/*  FPA					*/
-	fmovd		%f14, %f50		/*  FPA		Group			*/
+vis6s:	add		%src, 128 - 48, %src	/*  IEU0	Group		*/
+	ldda		[%src-80] %asi, %f12	/*  Load	Group		*/
+	ldda		[%src-72] %asi, %f14	/*  Load	Group		*/
+	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	ldda		[%src-64] %asi, %f16	/*  Load	Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f2		/*  FPM				*/
+	clr		%x4			/*  IEU0			*/
+	faddd		%f32, %f32, %f4		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f6		/*  FPM				*/
+	clr		%x5			/*  IEU0			*/
+	faddd		%f32, %f32, %f8		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f10	/*  FPM				*/
+	clr		%x6			/*  IEU0			*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	sub		%dst, 64, %dst		/*  IEU0			*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	faligndata	%f12, %f14, %f48	/*  FPA				*/
+	fmovd		%f14, %f50		/*  FPA		Group		*/
 vis6:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f52,f54,f56,f58,f60,f62,f48,f50,f50,
 			,LDBLK(f32),	,,,,,,STBLK,,
@@ -734,24 +736,24 @@
 			,SYNC,		,,,,,,STBLK,ST(f48,64),
 			,add %dst, 72, %dst; add %len, 192 - 2*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis7s:	add		%src, 128 - 56, %src	/*  IEU0	Group			*/
-	ldda		[%src-72] %asi, %f14	/*  Load	Group			*/
-	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	ldda		[%src-64] %asi, %f16	/*  Load	Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f2		/*  FPM					*/
-	clr		%x4			/*  IEU0				*/
-	faddd		%f32, %f32, %f4		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f6		/*  FPM					*/
-	clr		%x5			/*  IEU0				*/
-	faddd		%f32, %f32, %f8		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f10	/*  FPM					*/
-	clr		%x6			/*  IEU0				*/
-	faddd		%f32, %f32, %f12	/*  FPA		Group			*/
-	clr		%x7			/*  IEU0				*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	sub		%dst, 64, %dst		/*  IEU0				*/
-	fmovd		%f14, %f48		/*  FPA					*/
+vis7s:	add		%src, 128 - 56, %src	/*  IEU0	Group		*/
+	ldda		[%src-72] %asi, %f14	/*  Load	Group		*/
+	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	ldda		[%src-64] %asi, %f16	/*  Load	Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f2		/*  FPM				*/
+	clr		%x4			/*  IEU0			*/
+	faddd		%f32, %f32, %f4		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f6		/*  FPM				*/
+	clr		%x5			/*  IEU0			*/
+	faddd		%f32, %f32, %f8		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f10	/*  FPM				*/
+	clr		%x6			/*  IEU0			*/
+	faddd		%f32, %f32, %f12	/*  FPA		Group		*/
+	clr		%x7			/*  IEU0			*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	sub		%dst, 64, %dst		/*  IEU0			*/
+	fmovd		%f14, %f48		/*  FPA				*/
 vis7:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f50,f52,f54,f56,f58,f60,f62,f48,f48,
 			,LDBLK(f32),	,,,,,,,STBLK,
@@ -779,112 +781,112 @@
 e1:	END_THE_TRICK1(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f6)
 e2:	END_THE_TRICK1(	f16,f18,f20,f22,f24,f26,f28,f30,f32,f6)
 e3:	END_THE_TRICK1(	f32,f34,f36,f38,f40,f42,f44,f46,f0,f6)
-ett:	rd		%asi, %x4		/*  LSU		Group+4bubbles		*/
-	rd		%gsr, %x3		/*  LSU		Group+4bubbles		*/
+ett:	rd		%asi, %x4		/*  LSU		Group+4bubbles	*/
+	rd		%gsr, %x3		/*  LSU		Group+4bubbles	*/
 #ifdef __KERNEL__
-	srl		%x4, 3, %x5		/*  IEU0	Group			*/
-	xor		%x4, ASI_BLK_XOR1, %x4	/*  IEU1				*/
-	wr		%x4, %x5, %asi		/*  LSU		Group+4bubbles		*/
+	srl		%x4, 3, %x5		/*  IEU0	Group		*/
+	xor		%x4, ASI_BLK_XOR1, %x4	/*  IEU1			*/
+	wr		%x4, %x5, %asi		/*  LSU		Group+4bubbles	*/
 #else
-	wr		%x4, ASI_BLK_XOR, %asi	/*  LSU		Group+4bubbles		*/
+	wr		%x4, ASI_BLK_XOR, %asi	/*  LSU		Group+4bubbles	*/
 #endif
-	andcc		%x3, 7, %x3		/*  IEU1	Group			*/
-	add		%dst, 8, %dst		/*  IEU0				*/
-	bne,pn		%icc, 1f		/*  CTI					*/
-	 fzero		%f10			/*  FPA					*/
-	brz,a,pn	%len, 2f		/*  CTI+IEU1	Group			*/
-	 std		%f6, [%dst - 8]		/*  Store				*/
-1:	cmp		%len, 8			/*  IEU1				*/
-	blu,pn		%icc, 3f		/*  CTI					*/
-	 sub		%src, 64, %src		/*  IEU0	Group			*/
-1:	ldda		[%src] %asi, %f2	/*  Load	Group			*/
-	fpadd32		%f10, %f2, %f12		/*  FPA		Group+load stall	*/
-	add		%src, 8, %src		/*  IEU0				*/
-	add		%dst, 8, %dst		/*  IEU1				*/
-	faligndata	%f6, %f2, %f14		/*  FPA		Group			*/
-	fcmpgt32	%f10, %f12, %x5		/*  FPM		Group			*/
-	std		%f14, [%dst - 16]	/*  Store				*/
-	fmovd		%f2, %f6		/*  FPA					*/
-	fmovd		%f12, %f10		/*  FPA		Group			*/
-	sub		%len, 8, %len		/*  IEU1				*/
-	fzero		%f16			/*  FPA		Group - FPU nop		*/
-	fzero		%f18			/*  FPA		Group - FPU nop		*/
-	inc		%x5			/*  IEU0				*/
-	srl		%x5, 1, %x5		/*  IEU0	Group (regdep)		*/
-	cmp		%len, 8			/*  IEU1				*/
-	bgeu,pt		%icc, 1b		/*  CTI					*/
-	 add		%x5, %sum, %sum		/*  IEU0	Group			*/
-3:	brz,a,pt	%x3, 2f			/*  CTI+IEU1				*/
-	 std		%f6, [%dst - 8]		/*  Store	Group			*/
-	st		%f7, [%dst - 8]		/*  Store	Group			*/
-	sub		%dst, 4, %dst		/*  IEU0				*/
-	add		%len, 4, %len		/*  IEU1				*/
+	andcc		%x3, 7, %x3		/*  IEU1	Group		*/
+	add		%dst, 8, %dst		/*  IEU0			*/
+	bne,pn		%icc, 1f		/*  CTI				*/
+	 fzero		%f10			/*  FPA				*/
+	brz,a,pn	%len, 2f		/*  CTI+IEU1	Group		*/
+	 std		%f6, [%dst - 8]		/*  Store			*/
+1:	cmp		%len, 8			/*  IEU1			*/
+	blu,pn		%icc, 3f		/*  CTI				*/
+	 sub		%src, 64, %src		/*  IEU0	Group		*/
+1:	ldda		[%src] %asi, %f2	/*  Load	Group		*/
+	fpadd32		%f10, %f2, %f12		/*  FPA		Group+load stall*/
+	add		%src, 8, %src		/*  IEU0			*/
+	add		%dst, 8, %dst		/*  IEU1			*/
+	faligndata	%f6, %f2, %f14		/*  FPA		Group		*/
+	fcmpgt32	%f10, %f12, %x5		/*  FPM		Group		*/
+	std		%f14, [%dst - 16]	/*  Store			*/
+	fmovd		%f2, %f6		/*  FPA				*/
+	fmovd		%f12, %f10		/*  FPA		Group		*/
+	sub		%len, 8, %len		/*  IEU1			*/
+	fzero		%f16			/*  FPA		Group - FPU nop	*/
+	fzero		%f18			/*  FPA		Group - FPU nop	*/
+	inc		%x5			/*  IEU0			*/
+	srl		%x5, 1, %x5		/*  IEU0	Group (regdep)	*/
+	cmp		%len, 8			/*  IEU1			*/
+	bgeu,pt		%icc, 1b		/*  CTI				*/
+	 add		%x5, %sum, %sum		/*  IEU0	Group		*/
+3:	brz,a,pt	%x3, 2f			/*  CTI+IEU1			*/
+	 std		%f6, [%dst - 8]		/*  Store	Group		*/
+	st		%f7, [%dst - 8]		/*  Store	Group		*/
+	sub		%dst, 4, %dst		/*  IEU0			*/
+	add		%len, 4, %len		/*  IEU1			*/
 2:
 #ifdef __KERNEL__
-	sub		%sp, 8, %sp		/*  IEU0	Group			*/
+	sub		%sp, 8, %sp		/*  IEU0	Group		*/
 #endif
 	END_THE_TRICK2(	f48,f50,f52,f54,f56,f58,f60,f10,f12,f62)
-	membar		#Sync			/*  LSU		Group			*/
+	membar		#Sync			/*  LSU		Group		*/
 #ifdef __KERNEL__
 	VISExit
-	add		%sp, 8, %sp		/*  IEU0	Group			*/
+	add		%sp, 8, %sp		/*  IEU0	Group		*/
 #endif
-23:	brnz,pn		%len, 26f		/*  CTI+IEU1	Group			*/
-24:	 sllx		%sum, 32, %g1		/*  IEU0				*/
-25:	addcc		%sum, %g1, %src		/*  IEU1	Group			*/
-	srlx		%src, 32, %src		/*  IEU0	Group (regdep)		*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%src, 1, %src		/*  IEU1				*/
+23:	brnz,pn		%len, 26f		/*  CTI+IEU1	Group		*/
+24:	 sllx		%sum, 32, %g1		/*  IEU0			*/
+25:	addcc		%sum, %g1, %src		/*  IEU1	Group		*/
+	srlx		%src, 32, %src		/*  IEU0	Group (regdep)	*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%src, 1, %src		/*  IEU1			*/
 #ifndef __KERNEL__
-1:	retl					/*  CTI		Group brk forced	*/
-	 srl		%src, 0, %src		/*  IEU0				*/
+1:	retl					/*  CTI		Group brk forced*/
+	 srl		%src, 0, %src		/*  IEU0			*/
 #else
-1:	sethi		%uhi(PAGE_OFFSET), %g4	/*  IEU0	Group			*/
-	retl					/*  CTI		Group brk forced	*/
-	 sllx		%g4, 32, %g4		/*  IEU0				*/
+1:	sethi		%uhi(PAGE_OFFSET), %g4	/*  IEU0	Group		*/
+	retl					/*  CTI		Group brk forced*/
+	 sllx		%g4, 32, %g4		/*  IEU0			*/
 #endif
-26:	andcc		%len, 8, %g0		/*  IEU1	Group			*/
-	be,pn		%icc, 1f		/*  CTI					*/
-	 lduwa		[%src] %asi, %o4	/*  Load				*/
-	lduwa		[%src+4] %asi, %g2	/*  Load	Group			*/
-	add		%src, 8, %src		/*  IEU0				*/
-	add		%dst, 8, %dst		/*  IEU1				*/
-	sllx		%o4, 32, %g5		/*  IEU0	Group			*/
-	stw		%o4, [%dst - 8]		/*  Store				*/
-	or		%g5, %g2, %g5		/*  IEU0	Group			*/
-	stw		%g2, [%dst - 4]		/*  Store				*/
-	addcc		%g5, %sum, %sum		/*  IEU1	Group			*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%sum, 1, %sum		/*  IEU0				*/
-1:	andcc		%len, 4, %g0		/*  IEU1	Group			*/
-	be,a,pn		%icc, 1f		/*  CTI					*/
-	 clr		%g2			/*  IEU0				*/
-	lduwa		[%src] %asi, %g7	/*  Load				*/
-	add		%src, 4, %src		/*  IEU0	Group			*/
-	add		%dst, 4, %dst		/*  IEU1				*/
-	sllx		%g7, 32, %g2		/*  IEU0	Group			*/
-	stw		%g7, [%dst - 4]		/*  Store				*/
-1:	andcc		%len, 2, %g0		/*  IEU1				*/
-	be,a,pn		%icc, 1f		/*  CTI					*/
-	 clr		%g3			/*  IEU0	Group			*/
-	lduha		[%src] %asi, %g7	/*  Load				*/
-	add		%src, 2, %src		/*  IEU1				*/
-	add		%dst, 2, %dst		/*  IEU0	Group			*/
-	sll		%g7, 16, %g3		/*  IEU0	Group			*/
-	sth		%g7, [%dst - 2]		/*  Store				*/
-1:	andcc		%len, 1, %g0		/*  IEU1				*/
-	be,a,pn		%icc, 1f		/*  CTI					*/
-	 clr		%o5			/*  IEU0	Group			*/
-	lduba		[%src] %asi, %g7	/*  Load				*/
-	sll		%g7, 8, %o5		/*  IEU0	Group			*/
-	stb		%g7, [%dst]		/*  Store				*/
-1:	or		%g2, %g3, %g3		/*  IEU1				*/
-	or		%o5, %g3, %g3		/*  IEU0	Group (regdep)		*/
-	addcc		%g3, %sum, %sum		/*  IEU1	Group (regdep)		*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%sum, 1, %sum		/*  IEU0				*/
-1:	ba,pt		%xcc, 25b		/*  CTI		Group			*/
-	 sllx		%sum, 32, %g1		/*  IEU0				*/
+26:	andcc		%len, 8, %g0		/*  IEU1	Group		*/
+	be,pn		%icc, 1f		/*  CTI				*/
+	 lduwa		[%src] %asi, %o4	/*  Load			*/
+	lduwa		[%src+4] %asi, %g2	/*  Load	Group		*/
+	add		%src, 8, %src		/*  IEU0			*/
+	add		%dst, 8, %dst		/*  IEU1			*/
+	sllx		%o4, 32, %g5		/*  IEU0	Group		*/
+	stw		%o4, [%dst - 8]		/*  Store			*/
+	or		%g5, %g2, %g5		/*  IEU0	Group		*/
+	stw		%g2, [%dst - 4]		/*  Store			*/
+	addcc		%g5, %sum, %sum		/*  IEU1	Group		*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%sum, 1, %sum		/*  IEU0			*/
+1:	andcc		%len, 4, %g0		/*  IEU1	Group		*/
+	be,a,pn		%icc, 1f		/*  CTI				*/
+	 clr		%g2			/*  IEU0			*/
+	lduwa		[%src] %asi, %g7	/*  Load			*/
+	add		%src, 4, %src		/*  IEU0	Group		*/
+	add		%dst, 4, %dst		/*  IEU1			*/
+	sllx		%g7, 32, %g2		/*  IEU0	Group		*/
+	stw		%g7, [%dst - 4]		/*  Store			*/
+1:	andcc		%len, 2, %g0		/*  IEU1			*/
+	be,a,pn		%icc, 1f		/*  CTI				*/
+	 clr		%g3			/*  IEU0	Group		*/
+	lduha		[%src] %asi, %g7	/*  Load			*/
+	add		%src, 2, %src		/*  IEU1			*/
+	add		%dst, 2, %dst		/*  IEU0	Group		*/
+	sll		%g7, 16, %g3		/*  IEU0	Group		*/
+	sth		%g7, [%dst - 2]		/*  Store			*/
+1:	andcc		%len, 1, %g0		/*  IEU1			*/
+	be,a,pn		%icc, 1f		/*  CTI				*/
+	 clr		%o5			/*  IEU0	Group		*/
+	lduba		[%src] %asi, %g7	/*  Load			*/
+	sll		%g7, 8, %o5		/*  IEU0	Group		*/
+	stb		%g7, [%dst]		/*  Store			*/
+1:	or		%g2, %g3, %g3		/*  IEU1			*/
+	or		%o5, %g3, %g3		/*  IEU0	Group (regdep)	*/
+	addcc		%g3, %sum, %sum		/*  IEU1	Group (regdep)	*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%sum, 1, %sum		/*  IEU0			*/
+1:	ba,pt		%xcc, 25b		/*  CTI		Group		*/
+	 sllx		%sum, 32, %g1		/*  IEU0			*/
 
 #ifdef __KERNEL__
 end:
diff -u --recursive --new-file v2.3.47/linux/arch/sparc64/lib/VIScsumcopyusr.S linux/arch/sparc64/lib/VIScsumcopyusr.S
--- v2.3.47/linux/arch/sparc64/lib/VIScsumcopyusr.S	Fri Jan 28 15:09:07 2000
+++ linux/arch/sparc64/lib/VIScsumcopyusr.S	Mon Feb 21 16:32:27 2000
@@ -1,4 +1,4 @@
-/* $Id: VIScsumcopyusr.S,v 1.1 2000/01/19 04:06:04 davem Exp $
+/* $Id: VIScsumcopyusr.S,v 1.2 2000/02/20 23:21:40 davem Exp $
  * VIScsumcopyusr.S: High bandwidth IP checksumming with simultaneous
  *                   copying utilizing the UltraSparc Visual Instruction Set.
  *
@@ -91,358 +91,360 @@
 
 
 #define DO_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,F0,F2,F4,F6,F8,F10,F12,F14,DUMMY1,A0,A2,A4,A6,A8,A10,A12,A14,B14,DUMMY2,LOAD,STORE1,STORE2,STORE3,STORE4,STORE5,STORE6,STORE7,STORE8,DUMMY3,BRANCH...)	\
-	LOAD					/*  Load	Group			*/;	\
-	faligndata	%A14, %F0, %A14		/*  FPA		Group			*/;	\
-	inc		%x5			/*  IEU0				*/;	\
-	STORE1					/*  Store (optional)			*/;	\
-	faligndata	%F0, %F2, %A0		/*  FPA		Group			*/;	\
-	srl		%x5, 1, %x5		/*  IEU0				*/;	\
-	add		%sum, %x4, %sum		/*  IEU1				*/;	\
-	fpadd32		%F0, %f0, %F0		/*  FPA		Group			*/;	\
-	inc		%x6			/*  IEU0				*/;	\
-	STORE2					/*  Store (optional)			*/;	\
-	faligndata	%F2, %F4, %A2		/*  FPA		Group			*/;	\
-	srl		%x6, 1, %x6		/*  IEU0				*/;	\
-	add		%sum, %x5, %sum		/*  IEU1				*/;	\
-	fpadd32		%F2, %f2, %F2		/*  FPA		Group			*/;	\
-	add		%src, 64, %src		/*  IEU0				*/;	\
-	add		%dst, 64, %dst		/*  IEU1				*/;	\
-	fcmpgt32	%f0, %F0, %x1		/*  FPM		Group			*/;	\
-	inc		%x7			/*  IEU0				*/;	\
-	STORE3					/*  Store (optional)			*/;	\
-	faligndata	%F4, %F6, %A4		/*  FPA					*/;	\
-	srl		%x7, 1, %x7		/*  IEU0	Group			*/;	\
-	add		%sum, %x6, %sum		/*  IEU1				*/;	\
-	fpadd32		%F4, %f4, %F4		/*  FPA					*/;	\
-	fcmpgt32	%f2, %F2, %x2		/*  FPM		Group			*/;	\
-	inc		%x8			/*  IEU0				*/;	\
-	STORE4					/*  Store (optional)			*/;	\
-	faligndata	%F6, %F8, %A6		/*  FPA					*/;	\
-	srl		%x8, 1, %x8		/*  IEU0	Group			*/;	\
-	add		%sum, %x7, %sum		/*  IEU1				*/;	\
-	fpadd32		%F6, %f6, %F6		/*  FPA					*/;	\
-	fcmpgt32	%f4, %F4, %x3		/*  FPM		Group			*/;	\
-	inc		%x1			/*  IEU0				*/;	\
-	STORE5					/*  Store (optional)			*/;	\
-	faligndata	%F8, %F10, %A8		/*  FPA					*/;	\
-	srl		%x1, 1, %x1		/*  IEU0	Group			*/;	\
-	add		%sum, %x8, %sum		/*  IEU1				*/;	\
-	fpadd32		%F8, %f8, %F8		/*  FPA					*/;	\
-	fcmpgt32	%f6, %F6, %x4		/*  FPM		Group			*/;	\
-	inc		%x2			/*  IEU0				*/;	\
-	STORE6					/*  Store (optional)			*/;	\
-	faligndata	%F10, %F12, %A10	/*  FPA					*/;	\
-	srl		%x2, 1, %x2		/*  IEU0	Group			*/;	\
-	add		%sum, %x1, %sum		/*  IEU1				*/;	\
-	fpadd32		%F10, %f10, %F10	/*  FPA					*/;	\
-	fcmpgt32	%f8, %F8, %x5		/*  FPM		Group			*/;	\
-	inc		%x3			/*  IEU0				*/;	\
-	STORE7					/*  Store (optional)			*/;	\
-	faligndata	%F12, %F14, %A12	/*  FPA					*/;	\
-	srl		%x3, 1, %x3		/*  IEU0	Group			*/;	\
-	add		%sum, %x2, %sum		/*  IEU1				*/;	\
-	fpadd32		%F12, %f12, %F12	/*  FPA					*/;	\
-	fcmpgt32	%f10, %F10, %x6		/*  FPM		Group			*/;	\
-	inc		%x4			/*  IEU0				*/;	\
-	STORE8					/*  Store (optional)			*/;	\
-	fmovd		%F14, %B14		/*  FPA					*/;	\
-	srl		%x4, 1, %x4		/*  IEU0	Group			*/;	\
-	add		%sum, %x3, %sum		/*  IEU1				*/;	\
-	fpadd32		%F14, %f14, %F14	/*  FPA					*/;	\
-	fcmpgt32	%f12, %F12, %x7		/*  FPM		Group			*/;	\
-	subcc		%len, 64, %len		/*  IEU1				*/;	\
-	BRANCH					/*  CTI					*/;	\
-	fcmpgt32	%f14, %F14, %x8		/*  FPM		Group			*/;	\
+	LOAD					/*  Load	(Group)		*/;	\
+	faligndata	%A14, %F0, %A14		/*  FPA		Group		*/;	\
+	inc		%x5			/*  IEU0			*/;	\
+	STORE1					/*  Store (optional)		*/;	\
+	faligndata	%F0, %F2, %A0		/*  FPA		Group		*/;	\
+	srl		%x5, 1, %x5		/*  IEU0			*/;	\
+	add		%sum, %x4, %sum		/*  IEU1			*/;	\
+	fpadd32		%F0, %f0, %F0		/*  FPA		Group		*/;	\
+	inc		%x6			/*  IEU0			*/;	\
+	STORE2					/*  Store (optional)		*/;	\
+	faligndata	%F2, %F4, %A2		/*  FPA		Group		*/;	\
+	srl		%x6, 1, %x6		/*  IEU0			*/;	\
+	add		%sum, %x5, %sum		/*  IEU1			*/;	\
+	fpadd32		%F2, %f2, %F2		/*  FPA		Group		*/;	\
+	add		%src, 64, %src		/*  IEU0			*/;	\
+	fcmpgt32	%f0, %F0, %x1		/*  FPM				*/;	\
+	add		%dst, 64, %dst		/*  IEU1	Group		*/;	\
+	inc		%x7			/*  IEU0			*/;	\
+	STORE3					/*  Store (optional)		*/;	\
+	faligndata	%F4, %F6, %A4		/*  FPA				*/;	\
+	fpadd32		%F4, %f4, %F4		/*  FPA		Group		*/;	\
+	add		%sum, %x6, %sum		/*  IEU1			*/;	\
+	fcmpgt32	%f2, %F2, %x2		/*  FPM				*/;	\
+	srl		%x7, 1, %x7		/*  IEU0	Group		*/;	\
+	inc		%x8			/*  IEU1			*/;	\
+	STORE4					/*  Store (optional)		*/;	\
+	faligndata	%F6, %F8, %A6		/*  FPA				*/;	\
+	fpadd32		%F6, %f6, %F6		/*  FPA		Group		*/;	\
+	srl		%x8, 1, %x8		/*  IEU0			*/;	\
+	fcmpgt32	%f4, %F4, %x3		/*  FPM				*/;	\
+	add		%sum, %x7, %sum		/*  IEU0	Group		*/;	\
+	inc		%x1			/*  IEU1			*/;	\
+	STORE5					/*  Store (optional)		*/;	\
+	faligndata	%F8, %F10, %A8		/*  FPA				*/;	\
+	fpadd32		%F8, %f8, %F8		/*  FPA		Group		*/;	\
+	srl		%x1, 1, %x1		/*  IEU0			*/;	\
+	fcmpgt32	%f6, %F6, %x4		/*  FPM				*/;	\
+	add		%sum, %x8, %sum		/*  IEU0	Group		*/;	\
+	inc		%x2			/*  IEU1			*/;	\
+	STORE6					/*  Store (optional)		*/;	\
+	faligndata	%F10, %F12, %A10	/*  FPA				*/;	\
+	fpadd32		%F10, %f10, %F10	/*  FPA		Group		*/;	\
+	srl		%x2, 1, %x2		/*  IEU0			*/;	\
+	fcmpgt32	%f8, %F8, %x5		/*  FPM				*/;	\
+	add		%sum, %x1, %sum		/*  IEU0	Group		*/;	\
+	inc		%x3			/*  IEU1			*/;	\
+	STORE7					/*  Store (optional)		*/;	\
+	faligndata	%F12, %F14, %A12	/*  FPA				*/;	\
+	fpadd32		%F12, %f12, %F12	/*  FPA		Group		*/;	\
+	srl		%x3, 1, %x3		/*  IEU0			*/;	\
+	fcmpgt32	%f10, %F10, %x6		/*  FPM				*/;	\
+	add		%sum, %x2, %sum		/*  IEU0	Group		*/;	\
+	inc		%x4			/*  IEU1			*/;	\
+	STORE8					/*  Store (optional)		*/;	\
+	fmovd		%F14, %B14		/*  FPA				*/;	\
+	fpadd32		%F14, %f14, %F14	/*  FPA		Group		*/;	\
+	srl		%x4, 1, %x4		/*  IEU0			*/;	\
+	fcmpgt32	%f12, %F12, %x7		/*  FPM				*/;	\
+	add		%sum, %x3, %sum		/*  IEU0	Group		*/;	\
+	subcc		%len, 64, %len		/*  IEU1			*/;	\
+	BRANCH					/*  CTI				*/;	\
+	fcmpgt32	%f14, %F14, %x8		/*  FPM		Group		*/;
 
 #define END_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB,S0,S1,S2,S3,T0,T1,U0,fz) \
-	inc		%x5			/*  IEU0	Group			*/;	\
-	fpadd32		%f2, %f0, %S0		/*  FPA					*/;	\
-	srl		%x5, 1, %x5		/*  IEU0	Group			*/;	\
-	add		%sum, %x4, %sum		/*  IEU1				*/;	\
-	fpadd32		%f6, %f4, %S1		/*  FPA					*/;	\
-	inc		%x6			/*  IEU0	Group			*/;	\
-	add		%sum, %x5, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%f0, %S0, %x1		/*  FPM		Group			*/;	\
-	srl		%x6, 1, %x6		/*  IEU0				*/;	\
-	inc		%x7			/*  IEU1				*/;	\
-	fpadd32		%f10, %f8, %S2		/*  FPA					*/;	\
-	fcmpgt32	%f4, %S1, %x2		/*  FPM		Group			*/;	\
-	srl		%x7, 1, %x7		/*  IEU0				*/;	\
-	add		%sum, %x6, %sum		/*  IEU1				*/;	\
-	fpadd32		%f14, %f12, %S3		/*  FPA					*/;	\
-	inc		%x8			/*  IEU0	Group			*/;	\
-	add		%sum, %x7, %sum		/*  IEU1				*/;	\
-	fzero		%fz			/*  FPA					*/;	\
-	fcmpgt32	%f8, %S2, %x3		/*  FPM		Group			*/;	\
-	srl		%x8, 1, %x8		/*  IEU0				*/;	\
-	inc		%x1			/*  IEU1				*/;	\
-	fpadd32		%S0, %S1, %T0		/*  FPA					*/;	\
-	fcmpgt32	%f12, %S3, %x4		/*  FPM		Group			*/;	\
-	srl		%x1, 1, %x1		/*  IEU0				*/;	\
-	add		%sum, %x8, %sum		/*  IEU1				*/;	\
-	fpadd32		%S2, %S3, %T1		/*  FPA					*/;	\
-	inc		%x2			/*  IEU0	Group			*/;	\
-	add		%sum, %x1, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%S0, %T0, %x5		/*  FPM		Group			*/;	\
-	srl		%x2, 1, %x2		/*  IEU0				*/;	\
-	inc		%x3			/*  IEU1				*/;	\
-	fcmpgt32	%S2, %T1, %x6		/*  FPM		Group			*/;	\
-	srl		%x3, 1, %x3		/*  IEU0				*/;	\
-	add		%sum, %x2, %sum		/*  IEU1				*/;	\
-	inc		%x4			/*  IEU0	Group			*/;	\
-	add		%sum, %x3, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %f2, %x7		/*  FPM		Group			*/;	\
-	srl		%x4, 1, %x4		/*  IEU0				*/;	\
-	inc		%x5			/*  IEU1				*/;	\
-	fpadd32		%T0, %T1, %U0		/*  FPA					*/;	\
-	fcmpgt32	%fz, %f6, %x8		/*  FPM		Group			*/;	\
-	srl		%x5, 1, %x5		/*  IEU0				*/;	\
-	add		%sum, %x4, %sum		/*  IEU1				*/;	\
-	inc		%x6			/*  IEU0	Group			*/;	\
-	add		%sum, %x5, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %f10, %x1		/*  FPM		Group			*/;	\
-	srl		%x6, 1, %x6		/*  IEU0				*/;	\
-	inc		%x7			/*  IEU1				*/;	\
-	fcmpgt32	%fz, %f14, %x2		/*  FPM		Group			*/;	\
-	ba,pt		%xcc, ett		/*  CTI					*/;	\
-	 fmovd		%FA, %FB		/*  FPA					*/;	\
+	inc		%x5			/*  IEU0	Group		*/;	\
+	fpadd32		%f2, %f0, %S0		/*  FPA				*/;	\
+	add		%sum, %x4, %sum		/*  IEU1			*/;	\
+	srl		%x5, 1, %x5		/*  IEU0	Group		*/;	\
+	fpadd32		%f6, %f4, %S1		/*  FPA				*/;	\
+	inc		%x6			/*  IEU1			*/;	\
+	fpadd32		%f10, %f8, %S2		/*  FPA		Group		*/;	\
+	add		%sum, %x5, %sum		/*  IEU0			*/;	\
+	fcmpgt32	%f0, %S0, %x1		/*  FPM				*/;	\
+	fpadd32		%f14, %f12, %S3		/*  FPA		Group		*/;	\
+	srl		%x6, 1, %x6		/*  IEU0			*/;	\
+	fcmpgt32	%f4, %S1, %x2		/*  FPM				*/;	\
+	add		%sum, %x6, %sum		/*  IEU0	Group		*/;	\
+	fzero		%fz			/*  FPA				*/;	\
+	fcmpgt32	%f8, %S2, %x3		/*  FPM				*/;	\
+	inc		%x7			/*  IEU0	Group		*/;	\
+	inc		%x8			/*  IEU1			*/;	\
+	srl		%x7, 1, %x7		/*  IEU0	Group		*/;	\
+	inc		%x1			/*  IEU1			*/;	\
+	fpadd32		%S0, %S1, %T0		/*  FPA				*/;	\
+	fpadd32		%S2, %S3, %T1		/*  FPA		Group		*/;	\
+	add		%sum, %x7, %sum		/*  IEU0			*/;	\
+	fcmpgt32	%f12, %S3, %x4		/*  FPM				*/;	\
+	srl		%x8, 1, %x8		/*  IEU0	Group		*/;	\
+	inc		%x2			/*  IEU1			*/;	\
+	srl		%x1, 1, %x1		/*  IEU0	Group		*/;	\
+	add		%sum, %x8, %sum		/*  IEU1			*/;	\
+	add		%sum, %x1, %sum		/*  IEU0	Group		*/;	\
+	fcmpgt32	%S0, %T0, %x5		/*  FPM				*/;	\
+	srl		%x2, 1, %x2		/*  IEU0	Group		*/;	\
+	fcmpgt32	%S2, %T1, %x6		/*  FPM				*/;	\
+	inc		%x3			/*  IEU0	Group		*/;	\
+	add		%sum, %x2, %sum		/*  IEU1			*/;	\
+	srl		%x3, 1, %x3		/*  IEU0	Group		*/;	\
+	inc		%x4			/*  IEU1			*/;	\
+	fpadd32		%T0, %T1, %U0		/*  FPA		Group		*/;	\
+	add		%sum, %x3, %sum		/*  IEU0			*/;	\
+	fcmpgt32	%fz, %f2, %x7		/*  FPM				*/;	\
+	srl		%x4, 1, %x4		/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %f6, %x8		/*  FPM				*/;	\
+	inc		%x5			/*  IEU0	Group		*/;	\
+	add		%sum, %x4, %sum		/*  IEU1			*/;	\
+	srl		%x5, 1, %x5		/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %f10, %x1		/*  FPM				*/;	\
+	inc		%x6			/*  IEU0	Group		*/;	\
+	add		%sum, %x5, %sum		/*  IEU1			*/;	\
+	fmovd		%FA, %FB		/*  FPA		Group		*/;	\
+	fcmpgt32	%fz, %f14, %x2		/*  FPM				*/;	\
+	srl		%x6, 1, %x6		/*  IEU0	Group		*/;	\
+	ba,pt		%xcc, ett		/*  CTI				*/;	\
+	 inc		%x7			/*  IEU1			*/;
 
-#define END_THE_TRICK1(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB) 					\
+#define END_THE_TRICK1(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB) 				\
 	END_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB,f48,f50,f52,f54,f56,f58,f60,f62)
 
-#define END_THE_TRICK2(S0,S1,S2,S3,T0,T1,U0,U1,V0,fz) 						\
-	fpadd32		%U0, %U1, %V0		/*  FPA		Group			*/;	\
-	srl		%x7, 1, %x7		/*  IEU0				*/;	\
-	add		%sum, %x6, %sum		/*  IEU1				*/;	\
-	std		%V0, [%sp + STACKOFF]	/*  Store	Group			*/;	\
-	inc		%x8			/*  IEU0				*/;	\
-	sub		%sum, %x7, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %S1, %x3		/*  FPM		Group			*/;	\
-	srl		%x8, 1, %x8		/*  IEU0				*/;	\
-	inc		%x1			/*  IEU1				*/;	\
-	fcmpgt32	%fz, %S3, %x4		/*  FPM		Group			*/;	\
-	srl		%x1, 1, %x1		/*  IEU0				*/;	\
-	sub		%sum, %x8, %sum		/*  IEU1				*/;	\
-	ldx		[%sp + STACKOFF], %x8	/*  Load	Group			*/;	\
-	inc		%x2			/*  IEU0				*/;	\
-	sub		%sum, %x1, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %T1, %x5		/*  FPM		Group			*/;	\
-	srl		%x2, 1, %x2		/*  IEU0				*/;	\
-	inc		%x3			/*  IEU1				*/;	\
-	fcmpgt32	%T0, %U0, %x6		/*  FPM		Group			*/;	\
-	srl		%x3, 1, %x3		/*  IEU0				*/;	\
-	sub		%sum, %x2, %sum		/*  IEU1				*/;	\
-	inc		%x4			/*  IEU0	Group			*/;	\
-	sub		%sum, %x3, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %U1, %x7		/*  FPM		Group			*/;	\
-	srl		%x4, 1, %x4		/*  IEU0				*/;	\
-	inc		%x5			/*  IEU1				*/;	\
-	fcmpgt32	%U0, %V0, %x1		/*  FPM		Group			*/;	\
-	srl		%x5, 1, %x5		/*  IEU0				*/;	\
-	sub		%sum, %x4, %sum		/*  IEU1				*/;	\
-	fcmpgt32	%fz, %V0, %x2		/*  FPM		Group			*/;	\
-	inc		%x6			/*  IEU0				*/;	\
-	sub		%sum, %x5, %sum		/*  IEU1				*/;	\
-	srl		%x6, 1, %x6		/*  IEU0	Group			*/;	\
-	inc		%x7			/*  IEU1				*/;	\
-	srl		%x7, 1, %x7		/*  IEU0	Group			*/;	\
-	add		%sum, %x6, %sum		/*  IEU1				*/;	\
-	inc		%x1			/*  IEU0	Group			*/;	\
-	sub		%sum, %x7, %sum		/*  IEU1				*/;	\
-	srl		%x1, 1, %x1		/*  IEU0	Group			*/;	\
-	inc		%x2			/*  IEU1				*/;	\
-	srl		%x2, 1, %x2		/*  IEU0	Group			*/;	\
-	add		%sum, %x1, %sum		/*  IEU1				*/;	\
-	sub		%sum, %x2, %sum		/*  IEU0	Group			*/;	\
-	addcc		%sum, %x8, %sum		/*  IEU		Group			*/;	\
-	bcs,a,pn	%xcc, 33f		/*  CTI					*/;	\
-	 add		%sum, 1, %sum		/*  IEU0				*/;	\
-33:						/*  That's it				*/;
+#define END_THE_TRICK2(S0,S1,S2,S3,T0,T1,U0,U1,V0,fz) 					\
+	fpadd32		%U0, %U1, %V0		/*  FPA		Group		*/;	\
+	srl		%x7, 1, %x7		/*  IEU0			*/;	\
+	add		%sum, %x6, %sum		/*  IEU1			*/;	\
+	std		%V0, [%sp + STACKOFF]	/*  Store	Group		*/;	\
+	inc		%x8			/*  IEU0			*/;	\
+	sub		%sum, %x7, %sum		/*  IEU1			*/;	\
+	srl		%x8, 1, %x8		/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %S1, %x3		/*  FPM				*/;	\
+	inc		%x1			/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %S3, %x4		/*  FPM				*/;	\
+	srl		%x1, 1, %x1		/*  IEU0	Group		*/;	\
+	sub		%sum, %x8, %sum		/*  IEU1			*/;	\
+	ldx		[%sp + STACKOFF], %x8	/*  Load	Group		*/;	\
+	inc		%x2			/*  IEU0			*/;	\
+	sub		%sum, %x1, %sum		/*  IEU1			*/;	\
+	srl		%x2, 1, %x2		/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %T1, %x5		/*  FPM				*/;	\
+	inc		%x3			/*  IEU0	Group		*/;	\
+	fcmpgt32	%T0, %U0, %x6		/*  FPM				*/;	\
+	srl		%x3, 1, %x3		/*  IEU0	Group		*/;	\
+	sub		%sum, %x2, %sum		/*  IEU1			*/;	\
+	inc		%x4			/*  IEU0	Group		*/;	\
+	sub		%sum, %x3, %sum		/*  IEU1			*/;	\
+	srl		%x4, 1, %x4		/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %U1, %x7		/*  FPM				*/;	\
+	inc		%x5			/*  IEU0	Group		*/;	\
+	fcmpgt32	%U0, %V0, %x1		/*  FPM				*/;	\
+	srl		%x5, 1, %x5		/*  IEU0	Group		*/;	\
+	sub		%sum, %x4, %sum		/*  IEU1			*/;	\
+	sub		%sum, %x5, %sum		/*  IEU0	Group		*/;	\
+	fcmpgt32	%fz, %V0, %x2		/*  FPM				*/;	\
+	inc		%x6			/*  IEU0	Group		*/;	\
+	inc		%x7			/*  IEU1			*/;	\
+	srl		%x6, 1, %x6		/*  IEU0	Group		*/;	\
+	inc		%x1			/*  IEU1			*/;	\
+	srl		%x7, 1, %x7		/*  IEU0	Group		*/;	\
+	add		%sum, %x6, %sum		/*  IEU1			*/;	\
+	srl		%x1, 1, %x1		/*  IEU0	Group		*/;	\
+	sub		%sum, %x7, %sum		/*  IEU1			*/;	\
+	inc		%x2			/*  IEU0	Group		*/;	\
+	add		%sum, %x1, %sum		/*  IEU1			*/;	\
+	srl		%x2, 1, %x2		/*  IEU0	Group		*/;	\
+	sub		%sum, %x2, %sum		/*  IEU0	Group		*/;	\
+	addcc		%sum, %x8, %sum		/*  IEU1	Group		*/;	\
+	bcs,a,pn	%xcc, 33f		/*  CTI				*/;	\
+	 add		%sum, 1, %sum		/*  IEU0	(Group)		*/;	\
+33:						/*  That's it			*/;
 
 	.text
 	.globl		csum_partial_copy_user_vis
 	.align		32
-/* %asi should be either ASI_P or ASI_AIUS for csum_partial_copy resp. csum_partial_copy_from_user */
-/* This assumes that !((%src^%dst)&3) && !((%src|%dst)&1) && %len >= 256 */
+/* %asi should be either ASI_P or ASI_AIUS for csum_partial_copy resp.
+ * csum_partial_copy_from_user
+ * This assumes that !((%src^%dst)&3) && !((%src|%dst)&1) && %len >= 256
+ */
 csum_partial_copy_user_vis:
-	andcc		%dst, 7, %g0		/*  IEU1	Group			*/
-	be,pt		%icc, 4f		/*  CTI					*/
-	 and		%dst, 0x38, %o4		/*  IEU0				*/
-	mov		1, %g5			/*  IEU0	Group			*/
-	andcc		%dst, 2, %g0		/*  IEU1				*/
-	be,pt		%icc, 1f		/*  CTI					*/
-	 and		%dst, 4, %g7		/*  IEU0	Group			*/
-	lduh		[%src], %g2		/*  Load				*/
-	sub		%len, 2, %len		/*  IEU0	Group			*/
-	add		%dst, 2, %dst		/*  IEU1				*/
-	andcc		%dst, 4, %g7		/*  IEU1	Group			*/
-	sll		%g5, 16, %g5		/*  IEU0				*/
-	stha		%g2, [%dst - 2]	%asi	/*  Store	Group			*/
-	sll		%g2, 16, %g2		/*  IEU0	 			*/
-	add		%src, 2, %src		/*  IEU1				*/
-	addcc		%g2, %sum, %sum		/*  IEU1	Group			*/
-	bcs,a,pn	%icc, 1f		/*  CTI					*/
-	 add		%sum, %g5, %sum		/*  IEU0				*/
-1:	lduw		[%src], %g2		/*  Load				*/
-	brz,a,pn	%g7, 4f			/*  CTI+IEU1	Group			*/
-	 and		%dst, 0x38, %o4		/*  IEU0				*/
-	add		%dst, 4, %dst		/*  IEU0	Group			*/
-	sub		%len, 4, %len		/*  IEU1				*/
-	addcc		%g2, %sum, %sum		/*  IEU1	Group			*/
-	bcs,a,pn	%icc, 1f		/*  CTI					*/
-	 add		%sum, 1, %sum		/*  IEU0				*/
-1:	and		%dst, 0x38, %o4		/*  IEU0	Group			*/
-	stwa		%g2, [%dst - 4] %asi	/*  Store				*/
-	add		%src, 4, %src		/*  IEU1				*/
+	andcc		%dst, 7, %g0		/*  IEU1	Group		*/
+	be,pt		%icc, 4f		/*  CTI				*/
+	 and		%dst, 0x38, %o4		/*  IEU0			*/
+	mov		1, %g5			/*  IEU0	Group		*/
+	andcc		%dst, 2, %g0		/*  IEU1			*/
+	be,pt		%icc, 1f		/*  CTI				*/
+	 and		%dst, 4, %g7		/*  IEU0	Group		*/
+	lduh		[%src], %g2		/*  Load			*/
+	sub		%len, 2, %len		/*  IEU0	Group		*/
+	add		%dst, 2, %dst		/*  IEU1			*/
+	andcc		%dst, 4, %g7		/*  IEU1	Group		*/
+	sll		%g5, 16, %g5		/*  IEU0			*/
+	stha		%g2, [%dst - 2]	%asi	/*  Store	Group		*/
+	sll		%g2, 16, %g2		/*  IEU0	 		*/
+	add		%src, 2, %src		/*  IEU1			*/
+	addcc		%g2, %sum, %sum		/*  IEU1	Group		*/
+	bcs,a,pn	%icc, 1f		/*  CTI				*/
+	 add		%sum, %g5, %sum		/*  IEU0			*/
+1:	lduw		[%src], %g2		/*  Load			*/
+	brz,a,pn	%g7, 4f			/*  CTI+IEU1	Group		*/
+	 and		%dst, 0x38, %o4		/*  IEU0			*/
+	add		%dst, 4, %dst		/*  IEU0	Group		*/
+	sub		%len, 4, %len		/*  IEU1			*/
+	addcc		%g2, %sum, %sum		/*  IEU1	Group		*/
+	bcs,a,pn	%icc, 1f		/*  CTI				*/
+	 add		%sum, 1, %sum		/*  IEU0			*/
+1:	and		%dst, 0x38, %o4		/*  IEU0	Group		*/
+	stwa		%g2, [%dst - 4] %asi	/*  Store			*/
+	add		%src, 4, %src		/*  IEU1			*/
 4:
 #ifdef __KERNEL__
 	VISEntry
 #endif
-	mov		%src, %g7		/*  IEU1	Group			*/
-	fzero		%f48			/*  FPA					*/
-	alignaddr	%src, %g0, %src		/*  Single	Group			*/
-	subcc		%g7, %src, %g7		/*  IEU1	Group			*/
-	be,pt		%xcc, 1f		/*  CTI					*/
-	 mov		0x40, %g1		/*  IEU0				*/
-	lduw		[%src], %g2		/*  Load	Group			*/
-	subcc		%sum, %g2, %sum		/*  IEU1	Group+load stall	*/
-	bcs,a,pn	%icc, 1f		/*  CTI					*/
-	 sub		%sum, 1, %sum		/*  IEU0				*/
-1:	srl		%sum, 0, %sum		/*  IEU0	Group			*/
-	clr		%g5			/*  IEU1				*/
-	brz,pn		%o4, 3f			/*  CTI+IEU1	Group			*/
-	 sub		%g1, %o4, %g1		/*  IEU0				*/
-	ldd		[%src], %f0		/*  Load				*/
-	clr		%o4			/*  IEU0	Group			*/
-	andcc		%dst, 8, %g0		/*  IEU1				*/
-	be,pn		%icc, 1f		/*  CTI					*/
-	 ldd		[%src + 8], %f2		/*  Load	Group			*/
-	add		%src, 8, %src		/*  IEU0				*/
-	sub		%len, 8, %len		/*  IEU1				*/
-	fpadd32		%f0, %f48, %f50		/*  FPA					*/
-	addcc		%dst, 8, %dst		/*  IEU1	Group			*/
-	faligndata	%f0, %f2, %f16		/*  FPA					*/
-	fcmpgt32	%f48, %f50, %o4		/*  FPM		Group			*/
-	fmovd		%f2, %f0		/*  FPA		Group			*/
-	ldd		[%src + 8], %f2		/*  Load				*/
-	stda		%f16, [%dst - 8] %asi	/*  Store				*/
-	fmovd		%f50, %f48		/*  FPA					*/
-1:	andcc		%g1, 0x10, %g0		/*  IEU1	Group			*/
-	be,pn		%icc, 1f		/*  CTI					*/
-	 and		%g1, 0x20, %g1		/*  IEU0				*/
-	fpadd32		%f0, %f48, %f50		/*  FPA					*/
-	ldd		[%src + 16], %f4	/*  Load	Group			*/
-	add		%src, 16, %src		/*  IEU0				*/
-	add		%dst, 16, %dst		/*  IEU1				*/
-	faligndata	%f0, %f2, %f16		/*  FPA					*/
-	fcmpgt32	%f48, %f50, %g5		/*  FPM		Group			*/
-	sub		%len, 16, %len		/*  IEU0				*/
-	inc		%o4			/*  IEU1				*/
-	stda		%f16, [%dst - 16] %asi	/*  Store	Group			*/
-	fpadd32		%f2, %f50, %f48		/*  FPA					*/
-	srl		%o4, 1, %o5		/*  IEU0				*/
-	faligndata	%f2, %f4, %f18		/*  FPA		Group			*/
-	stda		%f18, [%dst - 8] %asi	/*  Store				*/
-	fcmpgt32	%f50, %f48, %o4		/*  FPM		Group			*/
-	add		%o5, %sum, %sum		/*  IEU0				*/
-	ldd		[%src + 8], %f2		/*  Load				*/
-	fmovd		%f4, %f0		/*  FPA					*/
-1:	brz,a,pn	%g1, 4f			/*  CTI+IEU1	Group			*/
-	 rd		%asi, %g2		/*  LSU		Group + 4 bubbles	*/
-	inc		%g5			/*  IEU0				*/
-	fpadd32		%f0, %f48, %f50		/*  FPA					*/
-	ldd		[%src + 16], %f4	/*  Load	Group			*/
-	srl		%g5, 1, %g5		/*  IEU0				*/
-	add		%dst, 32, %dst		/*  IEU1				*/
-	faligndata	%f0, %f2, %f16		/*  FPA					*/
-	fcmpgt32	%f48, %f50, %o5		/*  FPM		Group			*/
-	inc		%o4			/*  IEU0				*/
-	ldd		[%src + 24], %f6	/*  Load				*/
-	srl		%o4, 1, %o4		/*  IEU0	Group			*/
-	add		%g5, %sum, %sum		/*  IEU1				*/
-	ldd		[%src + 32], %f8	/*  Load				*/
-	fpadd32		%f2, %f50, %f48		/*  FPA					*/
-	faligndata	%f2, %f4, %f18		/*  FPA		Group			*/
-	sub		%len, 32, %len		/*  IEU0				*/
-	stda		%f16, [%dst - 32] %asi	/*  Store				*/
-	fcmpgt32	%f50, %f48, %g3		/*  FPM		Group			*/
-	inc		%o5			/*  IEU0				*/
-	add		%o4, %sum, %sum		/*  IEU1				*/
-	fpadd32		%f4, %f48, %f50		/*  FPA					*/
-	faligndata	%f4, %f6, %f20		/*  FPA		Group			*/
-	srl		%o5, 1, %o5		/*  IEU0				*/
-	fcmpgt32	%f48, %f50, %g5		/*  FPM		Group			*/
-	add		%o5, %sum, %sum		/*  IEU0				*/
-	stda		%f18, [%dst - 24] %asi	/*  Store				*/
-	fpadd32		%f6, %f50, %f48		/*  FPA					*/
-	inc		%g3			/*  IEU0	Group			*/
-	stda		%f20, [%dst - 16] %asi	/*  Store				*/
-	add		%src, 32, %src		/*  IEU1				*/
-	faligndata	%f6, %f8, %f22		/*  FPA					*/
-	fcmpgt32	%f50, %f48, %o4		/*  FPM		Group			*/
-	srl		%g3, 1, %g3		/*  IEU0				*/
-	stda		%f22, [%dst - 8] %asi	/*  Store				*/	
-	add		%g3, %sum, %sum		/*  IEU0	Group			*/
-3:	rd		%asi, %g2		/*  LSU		Group + 4 bubbles	*/
+	mov		%src, %g7		/*  IEU1	Group		*/
+	fzero		%f48			/*  FPA				*/
+	alignaddr	%src, %g0, %src		/*  Single	Group		*/
+	subcc		%g7, %src, %g7		/*  IEU1	Group		*/
+	be,pt		%xcc, 1f		/*  CTI				*/
+	 mov		0x40, %g1		/*  IEU0			*/
+	lduw		[%src], %g2		/*  Load	Group		*/
+	subcc		%sum, %g2, %sum		/*  IEU1	Group+load stall*/
+	bcs,a,pn	%icc, 1f		/*  CTI				*/
+	 sub		%sum, 1, %sum		/*  IEU0			*/
+1:	srl		%sum, 0, %sum		/*  IEU0	Group		*/
+	clr		%g5			/*  IEU1			*/
+	brz,pn		%o4, 3f			/*  CTI+IEU1	Group		*/
+	 sub		%g1, %o4, %g1		/*  IEU0			*/
+	ldd		[%src], %f0		/*  Load			*/
+	clr		%o4			/*  IEU0	Group		*/
+	andcc		%dst, 8, %g0		/*  IEU1			*/
+	be,pn		%icc, 1f		/*  CTI				*/
+	 ldd		[%src + 8], %f2		/*  Load	Group		*/
+	add		%src, 8, %src		/*  IEU0			*/
+	sub		%len, 8, %len		/*  IEU1			*/
+	fpadd32		%f0, %f48, %f50		/*  FPA				*/
+	addcc		%dst, 8, %dst		/*  IEU1	Group		*/
+	faligndata	%f0, %f2, %f16		/*  FPA				*/
+	fcmpgt32	%f48, %f50, %o4		/*  FPM		Group		*/
+	fmovd		%f2, %f0		/*  FPA		Group		*/
+	ldd		[%src + 8], %f2		/*  Load			*/
+	stda		%f16, [%dst - 8] %asi	/*  Store			*/
+	fmovd		%f50, %f48		/*  FPA				*/
+1:	andcc		%g1, 0x10, %g0		/*  IEU1	Group		*/
+	be,pn		%icc, 1f		/*  CTI				*/
+	 and		%g1, 0x20, %g1		/*  IEU0			*/
+	fpadd32		%f0, %f48, %f50		/*  FPA				*/
+	ldd		[%src + 16], %f4	/*  Load	Group		*/
+	add		%src, 16, %src		/*  IEU0			*/
+	add		%dst, 16, %dst		/*  IEU1			*/
+	faligndata	%f0, %f2, %f16		/*  FPA				*/
+	fcmpgt32	%f48, %f50, %g5		/*  FPM		Group		*/
+	sub		%len, 16, %len		/*  IEU0			*/
+	inc		%o4			/*  IEU1			*/
+	stda		%f16, [%dst - 16] %asi	/*  Store	Group		*/
+	fpadd32		%f2, %f50, %f48		/*  FPA				*/
+	srl		%o4, 1, %o5		/*  IEU0			*/
+	faligndata	%f2, %f4, %f18		/*  FPA		Group		*/
+	stda		%f18, [%dst - 8] %asi	/*  Store			*/
+	fcmpgt32	%f50, %f48, %o4		/*  FPM		Group		*/
+	add		%o5, %sum, %sum		/*  IEU0			*/
+	ldd		[%src + 8], %f2		/*  Load			*/
+	fmovd		%f4, %f0		/*  FPA				*/
+1:	brz,a,pn	%g1, 4f			/*  CTI+IEU1	Group		*/
+	 rd		%asi, %g2		/*  LSU		Group + 4 bubbles*/
+	inc		%g5			/*  IEU0			*/
+	fpadd32		%f0, %f48, %f50		/*  FPA				*/
+	ldd		[%src + 16], %f4	/*  Load	Group		*/
+	srl		%g5, 1, %g5		/*  IEU0			*/
+	add		%dst, 32, %dst		/*  IEU1			*/
+	faligndata	%f0, %f2, %f16		/*  FPA				*/
+	fcmpgt32	%f48, %f50, %o5		/*  FPM		Group		*/
+	inc		%o4			/*  IEU0			*/
+	ldd		[%src + 24], %f6	/*  Load			*/
+	srl		%o4, 1, %o4		/*  IEU0	Group		*/
+	add		%g5, %sum, %sum		/*  IEU1			*/
+	ldd		[%src + 32], %f8	/*  Load			*/
+	fpadd32		%f2, %f50, %f48		/*  FPA				*/
+	faligndata	%f2, %f4, %f18		/*  FPA		Group		*/
+	sub		%len, 32, %len		/*  IEU0			*/
+	stda		%f16, [%dst - 32] %asi	/*  Store			*/
+	fcmpgt32	%f50, %f48, %g3		/*  FPM		Group		*/
+	inc		%o5			/*  IEU0			*/
+	add		%o4, %sum, %sum		/*  IEU1			*/
+	fpadd32		%f4, %f48, %f50		/*  FPA				*/
+	faligndata	%f4, %f6, %f20		/*  FPA		Group		*/
+	srl		%o5, 1, %o5		/*  IEU0			*/
+	fcmpgt32	%f48, %f50, %g5		/*  FPM		Group		*/
+	add		%o5, %sum, %sum		/*  IEU0			*/
+	stda		%f18, [%dst - 24] %asi	/*  Store			*/
+	fpadd32		%f6, %f50, %f48		/*  FPA				*/
+	inc		%g3			/*  IEU0	Group		*/
+	stda		%f20, [%dst - 16] %asi	/*  Store			*/
+	add		%src, 32, %src		/*  IEU1			*/
+	faligndata	%f6, %f8, %f22		/*  FPA				*/
+	fcmpgt32	%f50, %f48, %o4		/*  FPM		Group		*/
+	srl		%g3, 1, %g3		/*  IEU0			*/
+	stda		%f22, [%dst - 8] %asi	/*  Store			*/	
+	add		%g3, %sum, %sum		/*  IEU0	Group		*/
+3:	rd		%asi, %g2		/*  LSU		Group + 4 bubbles*/
 #ifdef __KERNEL__
-4:	sethi		%hi(vis0s), %g7		/*  IEU0	Group			*/
-	or		%g2, ASI_BLK_OR, %g2	/*  IEU1				*/
+4:	sethi		%hi(vis0s), %g7		/*  IEU0	Group		*/
+	or		%g2, ASI_BLK_OR, %g2	/*  IEU1			*/
 #else
-4:	rd		%pc, %g7		/*  LSU		Group + 4 bubbles	*/
+4:	rd		%pc, %g7		/*  LSU		Group + 4 bubbles*/
 #endif
-	inc		%g5			/*  IEU0	Group			*/
-	and		%src, 0x38, %g3		/*  IEU1				*/	
-	membar		#StoreLoad		/*  LSU		Group			*/
-	srl		%g5, 1, %g5		/*  IEU0				*/
-	inc		%o4			/*  IEU1				*/
-	sll		%g3, 8, %g3		/*  IEU0	Group			*/
-	sub		%len, 0xc0, %len	/*  IEU1				*/
-	addcc		%g5, %sum, %sum		/*  IEU1	Group			*/
-	srl		%o4, 1, %o4		/*  IEU0				*/
-	add		%g7, %g3, %g7		/*  IEU0	Group			*/
-	add		%o4, %sum, %sum		/*  IEU1				*/
+	inc		%g5			/*  IEU0	Group		*/
+	and		%src, 0x38, %g3		/*  IEU1			*/	
+	membar		#StoreLoad		/*  LSU		Group		*/
+	srl		%g5, 1, %g5		/*  IEU0			*/
+	inc		%o4			/*  IEU1			*/
+	sll		%g3, 8, %g3		/*  IEU0	Group		*/
+	sub		%len, 0xc0, %len	/*  IEU1			*/
+	addcc		%g5, %sum, %sum		/*  IEU1	Group		*/
+	srl		%o4, 1, %o4		/*  IEU0			*/
+	add		%g7, %g3, %g7		/*  IEU0	Group		*/
+	add		%o4, %sum, %sum		/*  IEU1			*/
 #ifdef __KERNEL__
-	jmpl		%g7 + %lo(vis0s), %g0	/*  CTI+IEU1	Group			*/
+	jmpl		%g7 + %lo(vis0s), %g0	/*  CTI+IEU1	Group		*/
 #else
-	jmpl		%g7 + (vis0s - 4b), %g0	/*  CTI+IEU1	Group			*/
+	jmpl		%g7 + (vis0s - 4b), %g0	/*  CTI+IEU1	Group		*/
 #endif
-	 fzero		%f32			/*  FPA					*/
+	 fzero		%f32			/*  FPA				*/
 
 	.align		2048
-vis0s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	ldda		[%src] ASI_BLK_P, %f0	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	fmovd		%f48, %f62		/*  FPA		Group	f0 available	*/
-	faligndata	%f0, %f2, %f48		/*  FPA		Group	f2 available	*/
-	fcmpgt32	%f32, %f2, %x1		/*  FPM		Group	f4 available	*/
-	fpadd32		%f0, %f62, %f0		/*  FPA					*/
-	fcmpgt32	%f32, %f4, %x2		/*  FPM		Group	f6 available	*/
-	faligndata	%f2, %f4, %f50		/*  FPA					*/
-	fcmpgt32	%f62, %f0, %x3		/*  FPM		Group	f8 available	*/
-	faligndata	%f4, %f6, %f52		/*  FPA					*/
-	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group	f10 available	*/
-	inc		%x1			/*  IEU0				*/
-	faligndata	%f6, %f8, %f54		/*  FPA					*/
-	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group	f12 available	*/
-	srl		%x1, 1, %x1		/*  IEU0				*/
-	inc		%x2			/*  IEU1				*/
-	faligndata	%f8, %f10, %f56		/*  FPA					*/
-	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group	f14 available	*/
-	srl		%x2, 1, %x2		/*  IEU0				*/
-	add		%sum, %x1, %sum		/*  IEU1				*/
-	faligndata	%f10, %f12, %f58	/*  FPA					*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	inc		%x3			/*  IEU0				*/
-	add		%sum, %x2, %sum		/*  IEU1				*/
-	faligndata	%f12, %f14, %f60	/*  FPA					*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	srl		%x3, 1, %x3		/*  IEU0				*/
-	inc		%x4			/*  IEU1				*/
-	fmovd		%f14, %f62		/*  FPA					*/
-	srl		%x4, 1, %x4		/*  IEU0	Group			*/
-	add		%sum, %x3, %sum		/*  IEU1				*/
+vis0s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	ldda		[%src] ASI_BLK_P, %f0	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	fmovd		%f48, %f62		/*  FPA		Group	f0 available*/
+	faligndata	%f0, %f2, %f48		/*  FPA		Group	f2 available*/
+	fcmpgt32	%f32, %f2, %x1		/*  FPM		Group	f4 available*/
+	fpadd32		%f0, %f62, %f0		/*  FPA				*/
+	fcmpgt32	%f32, %f4, %x2		/*  FPM		Group	f6 available*/
+	faligndata	%f2, %f4, %f50		/*  FPA				*/
+	fcmpgt32	%f62, %f0, %x3		/*  FPM		Group	f8 available*/
+	faligndata	%f4, %f6, %f52		/*  FPA				*/
+	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group	f10 available*/
+	inc		%x1			/*  IEU0			*/
+	faligndata	%f6, %f8, %f54		/*  FPA				*/
+	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group	f12 available*/
+	srl		%x1, 1, %x1		/*  IEU0			*/
+	inc		%x2			/*  IEU1			*/
+	faligndata	%f8, %f10, %f56		/*  FPA				*/
+	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group	f14 available*/
+	srl		%x2, 1, %x2		/*  IEU0			*/
+	add		%sum, %x1, %sum		/*  IEU1			*/
+	faligndata	%f10, %f12, %f58	/*  FPA				*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	inc		%x3			/*  IEU0			*/
+	add		%sum, %x2, %sum		/*  IEU1			*/
+	faligndata	%f12, %f14, %f60	/*  FPA				*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	srl		%x3, 1, %x3		/*  IEU0			*/
+	inc		%x4			/*  IEU1			*/
+	fmovd		%f14, %f62		/*  FPA				*/
+	srl		%x4, 1, %x4		/*  IEU0	Group		*/
+	add		%sum, %x3, %sum		/*  IEU1			*/
 vis0:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
 			,f48,f50,f52,f54,f56,f58,f60,f62,f62,								
 			,LDBLK(f32),	STBLK,,,,,,,,									
@@ -468,36 +470,36 @@
 			,SYNC,		STBLK_XORASI(x1,x2),ST(f48,64),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),ST(f60,48),
 			,add %dst, 56, %dst; add %len, 192 - 8*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis1s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	sub		%src, 8, %src		/*  IEU0	Group			*/
-	ldda		[%src] ASI_BLK_P, %f0	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	fmovd		%f0, %f58		/*  FPA		Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/
-	fcmpgt32	%f32, %f2, %x2		/*  FPM		Group			*/
-	faligndata	%f2, %f4, %f48		/*  FPA					*/
-	fcmpgt32	%f32, %f4, %x3		/*  FPM		Group			*/
-	faligndata	%f4, %f6, %f50		/*  FPA					*/
-	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group			*/
-	faligndata	%f6, %f8, %f52		/*  FPA					*/
-	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group			*/
-	inc		%x2			/*  IEU1				*/
-	faligndata	%f8, %f10, %f54		/*  FPA					*/
-	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group			*/
-	srl		%x2, 1, %x2		/*  IEU0				*/
-	faligndata	%f10, %f12, %f56	/*  FPA					*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	inc		%x3			/*  IEU0				*/
-	add		%sum, %x2, %sum		/*  IEU1				*/
-	faligndata	%f12, %f14, %f58	/*  FPA					*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	srl		%x3, 1, %x3		/*  IEU0				*/
-	inc		%x4			/*  IEU1				*/
-	fmovd		%f14, %f60		/*  FPA					*/
-	srl		%x4, 1, %x4		/*  IEU0	Group			*/
-	add		%sum, %x3, %sum		/*  IEU1				*/
+vis1s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	sub		%src, 8, %src		/*  IEU0	Group		*/
+	ldda		[%src] ASI_BLK_P, %f0	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	fmovd		%f0, %f58		/*  FPA		Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/
+	fcmpgt32	%f32, %f2, %x2		/*  FPM		Group		*/
+	faligndata	%f2, %f4, %f48		/*  FPA				*/
+	fcmpgt32	%f32, %f4, %x3		/*  FPM		Group		*/
+	faligndata	%f4, %f6, %f50		/*  FPA				*/
+	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group		*/
+	faligndata	%f6, %f8, %f52		/*  FPA				*/
+	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group		*/
+	inc		%x2			/*  IEU1			*/
+	faligndata	%f8, %f10, %f54		/*  FPA				*/
+	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group		*/
+	srl		%x2, 1, %x2		/*  IEU0			*/
+	faligndata	%f10, %f12, %f56	/*  FPA				*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	inc		%x3			/*  IEU0			*/
+	add		%sum, %x2, %sum		/*  IEU1			*/
+	faligndata	%f12, %f14, %f58	/*  FPA				*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	srl		%x3, 1, %x3		/*  IEU0			*/
+	inc		%x4			/*  IEU1			*/
+	fmovd		%f14, %f60		/*  FPA				*/
+	srl		%x4, 1, %x4		/*  IEU0	Group		*/
+	add		%sum, %x3, %sum		/*  IEU1			*/
 vis1:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f62,f48,f50,f52,f54,f56,f58,f60,f60,
 			,LDBLK(f32),	,STBLK,,,,,,,
@@ -523,33 +525,33 @@
 			,SYNC,		,STBLK_XORASI(x1,x2),ST(f48,0),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),
 			,add %dst, 48, %dst; add %len, 192 - 7*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis2s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	sub		%src, 16, %src		/*  IEU0	Group			*/
-	ldda		[%src] ASI_BLK_P, %f0	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	fmovd		%f0, %f56		/*  FPA		Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/	
-	sub		%dst, 64, %dst		/*  IEU0				*/
-	fpsub32		%f2, %f2, %f2		/*  FPA		Group			*/
-	fcmpgt32	%f32, %f4, %x3		/*  FPM		Group			*/
-	faligndata	%f4, %f6, %f48		/*  FPA					*/
-	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group			*/
-	faligndata	%f6, %f8, %f50		/*  FPA					*/
-	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group			*/
-	faligndata	%f8, %f10, %f52		/*  FPA					*/
-	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group			*/
-	faligndata	%f10, %f12, %f54	/*  FPA					*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	inc		%x3			/*  IEU0				*/
-	faligndata	%f12, %f14, %f56	/*  FPA					*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	srl		%x3, 1, %x3		/*  IEU0				*/
-	inc		%x4			/*  IEU1				*/
-	fmovd		%f14, %f58		/*  FPA					*/
-	srl		%x4, 1, %x4		/*  IEU0	Group			*/
-	add		%sum, %x3, %sum		/*  IEU1				*/
+vis2s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	sub		%src, 16, %src		/*  IEU0	Group		*/
+	ldda		[%src] ASI_BLK_P, %f0	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	fmovd		%f0, %f56		/*  FPA		Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/	
+	sub		%dst, 64, %dst		/*  IEU0			*/
+	fpsub32		%f2, %f2, %f2		/*  FPA		Group		*/
+	fcmpgt32	%f32, %f4, %x3		/*  FPM		Group		*/
+	faligndata	%f4, %f6, %f48		/*  FPA				*/
+	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group		*/
+	faligndata	%f6, %f8, %f50		/*  FPA				*/
+	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group		*/
+	faligndata	%f8, %f10, %f52		/*  FPA				*/
+	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group		*/
+	faligndata	%f10, %f12, %f54	/*  FPA				*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	inc		%x3			/*  IEU0			*/
+	faligndata	%f12, %f14, %f56	/*  FPA				*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	srl		%x3, 1, %x3		/*  IEU0			*/
+	inc		%x4			/*  IEU1			*/
+	fmovd		%f14, %f58		/*  FPA				*/
+	srl		%x4, 1, %x4		/*  IEU0	Group		*/
+	add		%sum, %x3, %sum		/*  IEU1			*/
 vis2:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f60,f62,f48,f50,f52,f54,f56,f58,f58,
 			,LDBLK(f32),	,,STBLK,,,,,,
@@ -575,29 +577,29 @@
 			,SYNC,		,,STBLK_XORASI(x2,x3),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),ST(f56,96),
 			,add %dst, 104, %dst; add %len, 192 - 6*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis3s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	sub		%src, 24, %src		/*  IEU0	Group			*/
-	ldda		[%src] ASI_BLK_P, %f0	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	fmovd		%f0, %f54		/*  FPA		Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/
-	sub		%dst, 64, %dst		/*  IEU0				*/
-	fpsub32		%f2, %f2, %f2		/*  FPA		Group			*/
-	fpsub32		%f4, %f4, %f4		/*  FPA		Group			*/
-	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group			*/
-	faligndata	%f6, %f8, %f48		/*  FPA					*/
-	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group			*/
-	faligndata	%f8, %f10, %f50		/*  FPA					*/
-	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group			*/
-	faligndata	%f10, %f12, %f52	/*  FPA					*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	faligndata	%f12, %f14, %f54	/*  FPA					*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	fmovd		%f14, %f56		/*  FPA					*/
-	inc		%x4			/*  IEU0				*/
-	srl		%x4, 1, %x4		/*  IEU0	Group			*/
+vis3s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	sub		%src, 24, %src		/*  IEU0	Group		*/
+	ldda		[%src] ASI_BLK_P, %f0	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	fmovd		%f0, %f54		/*  FPA		Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/
+	sub		%dst, 64, %dst		/*  IEU0			*/
+	fpsub32		%f2, %f2, %f2		/*  FPA		Group		*/
+	fpsub32		%f4, %f4, %f4		/*  FPA		Group		*/
+	fcmpgt32	%f32, %f6, %x4		/*  FPM		Group		*/
+	faligndata	%f6, %f8, %f48		/*  FPA				*/
+	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group		*/
+	faligndata	%f8, %f10, %f50		/*  FPA				*/
+	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group		*/
+	faligndata	%f10, %f12, %f52	/*  FPA				*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	faligndata	%f12, %f14, %f54	/*  FPA				*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	fmovd		%f14, %f56		/*  FPA				*/
+	inc		%x4			/*  IEU0			*/
+	srl		%x4, 1, %x4		/*  IEU0	Group		*/
 vis3:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f58,f60,f62,f48,f50,f52,f54,f56,f56,
 			,LDBLK(f32),	,,,STBLK,,,,,
@@ -623,27 +625,27 @@
 			,SYNC,		,,,STBLK_XORASI(x3,x4),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),
 			,add %dst, 96, %dst; add %len, 192 - 5*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis4s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	sub		%src, 32, %src		/*  IEU0	Group			*/
-	ldda		[%src] ASI_BLK_P, %f0	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	fmovd		%f0, %f52		/*  FPA		Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/
-	sub		%dst, 64, %dst		/*  IEU0				*/
-	fpsub32		%f2, %f2, %f2		/*  FPA		Group			*/
-	fpsub32		%f4, %f4, %f4		/*  FPA		Group			*/
-	fpsub32		%f6, %f6, %f6		/*  FPA		Group			*/
-	clr		%x4			/*  IEU0				*/
-	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group			*/
-	faligndata	%f8, %f10, %f48		/*  FPA					*/
-	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group			*/
-	faligndata	%f10, %f12, %f50	/*  FPA					*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	faligndata	%f12, %f14, %f52	/*  FPA					*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	fmovd		%f14, %f54		/*  FPA					*/
+vis4s:	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	sub		%src, 32, %src		/*  IEU0	Group		*/
+	ldda		[%src] ASI_BLK_P, %f0	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	fmovd		%f0, %f52		/*  FPA		Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/
+	sub		%dst, 64, %dst		/*  IEU0			*/
+	fpsub32		%f2, %f2, %f2		/*  FPA		Group		*/
+	fpsub32		%f4, %f4, %f4		/*  FPA		Group		*/
+	fpsub32		%f6, %f6, %f6		/*  FPA		Group		*/
+	clr		%x4			/*  IEU0			*/
+	fcmpgt32	%f32, %f8, %x5		/*  FPM		Group		*/
+	faligndata	%f8, %f10, %f48		/*  FPA				*/
+	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group		*/
+	faligndata	%f10, %f12, %f50	/*  FPA				*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	faligndata	%f12, %f14, %f52	/*  FPA				*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	fmovd		%f14, %f54		/*  FPA				*/
 vis4:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f56,f58,f60,f62,f48,f50,f52,f54,f54,
 			,LDBLK(f32),	,,,,STBLK,,,,
@@ -669,27 +671,27 @@
 			,SYNC,		,,,,STBLK_XORASI(x4,x5),ST(f48,64),ST(f50,72),ST(f52,80),
 			,add %dst, 88, %dst; add %len, 192 - 4*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis5s:	ldd		[%src+0], %f10		/*  Load	Group			*/
-	ldd		[%src+8], %f12		/*  Load	Group			*/
-	ldd		[%src+16], %f14		/*  Load	Group			*/
-	add		%src, 24, %src		/*  IEU0	Group			*/
-	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f2		/*  FPM					*/
-	clr		%x4			/*  IEU0				*/
-	faddd		%f32, %f32, %f4		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f6		/*  FPM					*/
-	clr		%x5			/*  IEU0				*/
-	faddd		%f32, %f32, %f8		/*  FPA		Group			*/
-	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group			*/
-	sub		%dst, 64, %dst		/*  IEU0				*/
-	faligndata	%f10, %f12, %f48	/*  FPA					*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	faligndata	%f12, %f14, %f50	/*  FPA					*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	fmovd		%f14, %f52		/*  FPA					*/
+vis5s:	ldd		[%src+0], %f10		/*  Load	Group		*/
+	ldd		[%src+8], %f12		/*  Load	Group		*/
+	ldd		[%src+16], %f14		/*  Load	Group		*/
+	add		%src, 24, %src		/*  IEU0	Group		*/
+	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f2		/*  FPM				*/
+	clr		%x4			/*  IEU0			*/
+	faddd		%f32, %f32, %f4		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f6		/*  FPM				*/
+	clr		%x5			/*  IEU0			*/
+	faddd		%f32, %f32, %f8		/*  FPA		Group		*/
+	fcmpgt32	%f32, %f10, %x6		/*  FPM		Group		*/
+	sub		%dst, 64, %dst		/*  IEU0			*/
+	faligndata	%f10, %f12, %f48	/*  FPA				*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	faligndata	%f12, %f14, %f50	/*  FPA				*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	fmovd		%f14, %f52		/*  FPA				*/
 vis5:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f54,f56,f58,f60,f62,f48,f50,f52,f52,
 			,LDBLK(f32),	,,,,,STBLK,,,
@@ -715,26 +717,26 @@
 			,SYNC,		,,,,,STBLK_XORASI(x5,x6),ST(f48,64),ST(f50,72),
 			,add %dst, 80, %dst; add %len, 192 - 3*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis6s:	ldd		[%src+0], %f12		/*  Load	Group			*/
-	ldd		[%src+8], %f14		/*  Load	Group			*/
-	add		%src, 16, %src		/*  IEU0	Group			*/
-	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f2		/*  FPM					*/
-	clr		%x4			/*  IEU0				*/
-	faddd		%f32, %f32, %f4		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f6		/*  FPM					*/
-	clr		%x5			/*  IEU0				*/
-	faddd		%f32, %f32, %f8		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f10	/*  FPM					*/
-	clr		%x6			/*  IEU0				*/
-	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group			*/
-	sub		%dst, 64, %dst		/*  IEU0				*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	faligndata	%f12, %f14, %f48	/*  FPA					*/
-	fmovd		%f14, %f50		/*  FPA		Group			*/
+vis6s:	ldd		[%src+0], %f12		/*  Load	Group		*/
+	ldd		[%src+8], %f14		/*  Load	Group		*/
+	add		%src, 16, %src		/*  IEU0	Group		*/
+	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f2		/*  FPM				*/
+	clr		%x4			/*  IEU0			*/
+	faddd		%f32, %f32, %f4		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f6		/*  FPM				*/
+	clr		%x5			/*  IEU0			*/
+	faddd		%f32, %f32, %f8		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f10	/*  FPM				*/
+	clr		%x6			/*  IEU0			*/
+	fcmpgt32	%f32, %f12, %x7		/*  FPM		Group		*/
+	sub		%dst, 64, %dst		/*  IEU0			*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	faligndata	%f12, %f14, %f48	/*  FPA				*/
+	fmovd		%f14, %f50		/*  FPA		Group		*/
 vis6:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f52,f54,f56,f58,f60,f62,f48,f50,f50,
 			,LDBLK(f32),	,,,,,,STBLK,,
@@ -760,25 +762,25 @@
 			,SYNC,		,,,,,,STBLK_XORASI(x6,x7),ST(f48,64),
 			,add %dst, 72, %dst; add %len, 192 - 2*8, %len; ba,pt %icc, e1)
 	.align		2048
-vis7s:	ldd		[%src+0], %f14		/*  Load	Group			*/
-	add		%src, 8, %src		/*  IEU0	Group			*/
-	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group			*/
-	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group			*/
-	add		%src, 64, %src		/*  IEU0	Group			*/
-	fmovd		%f48, %f0		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f2		/*  FPM					*/
-	clr		%x4			/*  IEU0				*/
-	faddd		%f32, %f32, %f4		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f6		/*  FPM					*/
-	clr		%x5			/*  IEU0				*/
-	faddd		%f32, %f32, %f8		/*  FPA		Group			*/
-	fmuld		%f32, %f32, %f10	/*  FPM					*/
-	clr		%x6			/*  IEU0				*/
-	faddd		%f32, %f32, %f12	/*  FPA		Group			*/
-	clr		%x7			/*  IEU0				*/
-	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group			*/
-	sub		%dst, 64, %dst		/*  IEU0				*/
-	fmovd		%f14, %f48		/*  FPA					*/
+vis7s:	ldd		[%src+0], %f14		/*  Load	Group		*/
+	add		%src, 8, %src		/*  IEU0	Group		*/
+	wr		%g2, ASI_BLK_XOR, %asi	/*  LSU		Group		*/
+	ldda		[%src] ASI_BLK_P, %f16	/*  Load	Group		*/
+	add		%src, 64, %src		/*  IEU0	Group		*/
+	fmovd		%f48, %f0		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f2		/*  FPM				*/
+	clr		%x4			/*  IEU0			*/
+	faddd		%f32, %f32, %f4		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f6		/*  FPM				*/
+	clr		%x5			/*  IEU0			*/
+	faddd		%f32, %f32, %f8		/*  FPA		Group		*/
+	fmuld		%f32, %f32, %f10	/*  FPM				*/
+	clr		%x6			/*  IEU0			*/
+	faddd		%f32, %f32, %f12	/*  FPA		Group		*/
+	clr		%x7			/*  IEU0			*/
+	fcmpgt32	%f32, %f14, %x8		/*  FPM		Group		*/
+	sub		%dst, 64, %dst		/*  IEU0			*/
+	fmovd		%f14, %f48		/*  FPA				*/
 vis7:	DO_THE_TRICK(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,	
 			,f50,f52,f54,f56,f58,f60,f62,f48,f48,
 			,LDBLK(f32),	,,,,,,,STBLK,
@@ -806,104 +808,104 @@
 e1:	END_THE_TRICK1(	f0,f2,f4,f6,f8,f10,f12,f14,f16,f6)
 e2:	END_THE_TRICK1(	f16,f18,f20,f22,f24,f26,f28,f30,f32,f6)
 e3:	END_THE_TRICK1(	f32,f34,f36,f38,f40,f42,f44,f46,f0,f6)
-ett:	rd		%gsr, %x3		/*  LSU		Group+4bubbles		*/
-	andcc		%x3, 7, %x3		/*  IEU1	Group			*/
-	add		%dst, 8, %dst		/*  IEU0				*/
-	bne,pn		%icc, 1f		/*  CTI					*/
-	 fzero		%f10			/*  FPA					*/
-	brz,a,pn	%len, 2f		/*  CTI+IEU1	Group			*/
-	 stda		%f6, [%dst - 8] %asi	/*  Store				*/
-1:	cmp		%len, 8			/*  IEU1				*/
-	blu,pn		%icc, 3f		/*  CTI					*/
-	 sub		%src, 64, %src		/*  IEU0	Group			*/
-1:	ldd		[%src], %f2		/*  Load	Group			*/
-	fpadd32		%f10, %f2, %f12		/*  FPA		Group+load stall	*/
-	add		%src, 8, %src		/*  IEU0				*/
-	add		%dst, 8, %dst		/*  IEU1				*/
-	faligndata	%f6, %f2, %f14		/*  FPA		Group			*/
-	fcmpgt32	%f10, %f12, %x5		/*  FPM		Group			*/
-	stda		%f14, [%dst - 16] %asi	/*  Store				*/
-	fmovd		%f2, %f6		/*  FPA					*/
-	fmovd		%f12, %f10		/*  FPA		Group			*/
-	sub		%len, 8, %len		/*  IEU1				*/
-	fzero		%f16			/*  FPA		Group - FPU nop		*/
-	fzero		%f18			/*  FPA		Group - FPU nop		*/
-	inc		%x5			/*  IEU0				*/
-	srl		%x5, 1, %x5		/*  IEU0	Group (regdep)		*/
-	cmp		%len, 8			/*  IEU1				*/
-	bgeu,pt		%icc, 1b		/*  CTI					*/
-	 add		%x5, %sum, %sum		/*  IEU0	Group			*/
-3:	brz,a,pt	%x3, 2f			/*  CTI+IEU1				*/
-	 stda		%f6, [%dst - 8] %asi	/*  Store	Group			*/
-	sta		%f7, [%dst - 8]	%asi	/*  Store	Group			*/
-	sub		%dst, 4, %dst		/*  IEU0				*/
-	add		%len, 4, %len		/*  IEU1				*/
+ett:	rd		%gsr, %x3		/*  LSU		Group+4bubbles	*/
+	andcc		%x3, 7, %x3		/*  IEU1	Group		*/
+	add		%dst, 8, %dst		/*  IEU0			*/
+	bne,pn		%icc, 1f		/*  CTI				*/
+	 fzero		%f10			/*  FPA				*/
+	brz,a,pn	%len, 2f		/*  CTI+IEU1	Group		*/
+	 stda		%f6, [%dst - 8] %asi	/*  Store			*/
+1:	cmp		%len, 8			/*  IEU1			*/
+	blu,pn		%icc, 3f		/*  CTI				*/
+	 sub		%src, 64, %src		/*  IEU0	Group		*/
+1:	ldd		[%src], %f2		/*  Load	Group		*/
+	fpadd32		%f10, %f2, %f12		/*  FPA		Group+load stall*/
+	add		%src, 8, %src		/*  IEU0			*/
+	add		%dst, 8, %dst		/*  IEU1			*/
+	faligndata	%f6, %f2, %f14		/*  FPA		Group		*/
+	fcmpgt32	%f10, %f12, %x5		/*  FPM		Group		*/
+	stda		%f14, [%dst - 16] %asi	/*  Store			*/
+	fmovd		%f2, %f6		/*  FPA				*/
+	fmovd		%f12, %f10		/*  FPA		Group		*/
+	sub		%len, 8, %len		/*  IEU1			*/
+	fzero		%f16			/*  FPA		Group - FPU nop	*/
+	fzero		%f18			/*  FPA		Group - FPU nop	*/
+	inc		%x5			/*  IEU0			*/
+	srl		%x5, 1, %x5		/*  IEU0	Group (regdep)	*/
+	cmp		%len, 8			/*  IEU1			*/
+	bgeu,pt		%icc, 1b		/*  CTI				*/
+	 add		%x5, %sum, %sum		/*  IEU0	Group		*/
+3:	brz,a,pt	%x3, 2f			/*  CTI+IEU1			*/
+	 stda		%f6, [%dst - 8] %asi	/*  Store	Group		*/
+	sta		%f7, [%dst - 8]	%asi	/*  Store	Group		*/
+	sub		%dst, 4, %dst		/*  IEU0			*/
+	add		%len, 4, %len		/*  IEU1			*/
 2:
 #ifdef __KERNEL__
-	sub		%sp, 8, %sp		/*  IEU0	Group			*/
+	sub		%sp, 8, %sp		/*  IEU0	Group		*/
 #endif
 	END_THE_TRICK2(	f48,f50,f52,f54,f56,f58,f60,f10,f12,f62)
-	membar		#Sync			/*  LSU		Group			*/
+	membar		#Sync			/*  LSU		Group		*/
 #ifdef __KERNEL__
 	VISExit
-	add		%sp, 8, %sp		/*  IEU0	Group			*/
+	add		%sp, 8, %sp		/*  IEU0	Group		*/
 #endif
-23:	brnz,pn		%len, 26f		/*  CTI+IEU1	Group			*/
-24:	 sllx		%sum, 32, %g1		/*  IEU0				*/
-25:	addcc		%sum, %g1, %src		/*  IEU1	Group			*/
-	srlx		%src, 32, %src		/*  IEU0	Group (regdep)		*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%src, 1, %src		/*  IEU1				*/
+23:	brnz,pn		%len, 26f		/*  CTI+IEU1	Group		*/
+24:	 sllx		%sum, 32, %g1		/*  IEU0			*/
+25:	addcc		%sum, %g1, %src		/*  IEU1	Group		*/
+	srlx		%src, 32, %src		/*  IEU0	Group (regdep)	*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%src, 1, %src		/*  IEU1			*/
 #ifndef __KERNEL__
-1:	retl					/*  CTI		Group brk forced	*/
-	 srl		%src, 0, %src		/*  IEU0				*/
+1:	retl					/*  CTI		Group brk forced*/
+	 srl		%src, 0, %src		/*  IEU0			*/
 #else
-1:	sethi		%uhi(PAGE_OFFSET), %g4	/*  IEU0	Group			*/
-	retl					/*  CTI		Group brk forced	*/
-	 sllx		%g4, 32, %g4		/*  IEU0				*/
+1:	sethi		%uhi(PAGE_OFFSET), %g4	/*  IEU0	Group		*/
+	retl					/*  CTI		Group brk forced*/
+	 sllx		%g4, 32, %g4		/*  IEU0			*/
 #endif
-26:	andcc		%len, 8, %g0		/*  IEU1	Group			*/
-	be,pn		%icc, 1f		/*  CTI					*/
-	 lduw		[%src], %o4		/*  Load				*/
-	lduw		[%src+4], %g2		/*  Load	Group			*/
-	add		%src, 8, %src		/*  IEU0				*/
-	add		%dst, 8, %dst		/*  IEU1				*/
-	sllx		%o4, 32, %g5		/*  IEU0	Group			*/
-	stwa		%o4, [%dst - 8] %asi	/*  Store				*/
-	or		%g5, %g2, %g5		/*  IEU0	Group			*/
-	stwa		%g2, [%dst - 4]	%asi	/*  Store				*/
-	addcc		%g5, %sum, %sum		/*  IEU1	Group			*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%sum, 1, %sum		/*  IEU0				*/
-1:	andcc		%len, 4, %g0		/*  IEU1	Group			*/
-	be,a,pn		%icc, 1f		/*  CTI					*/
-	 clr		%g2			/*  IEU0				*/
-	lduw		[%src], %g7		/*  Load				*/
-	add		%src, 4, %src		/*  IEU0	Group			*/
-	add		%dst, 4, %dst		/*  IEU1				*/
-	sllx		%g7, 32, %g2		/*  IEU0	Group			*/
-	stwa		%g7, [%dst - 4] %asi	/*  Store				*/
-1:	andcc		%len, 2, %g0		/*  IEU1				*/
-	be,a,pn		%icc, 1f		/*  CTI					*/
-	 clr		%g3			/*  IEU0	Group			*/
-	lduh		[%src], %g7		/*  Load				*/
-	add		%src, 2, %src		/*  IEU1				*/
-	add		%dst, 2, %dst		/*  IEU0	Group			*/
-	sll		%g7, 16, %g3		/*  IEU0	Group			*/
-	stha		%g7, [%dst - 2] %asi	/*  Store				*/
-1:	andcc		%len, 1, %g0		/*  IEU1				*/
-	be,a,pn		%icc, 1f		/*  CTI					*/
-	 clr		%o5			/*  IEU0	Group			*/
-	ldub		[%src], %g7		/*  Load				*/
-	sll		%g7, 8, %o5		/*  IEU0	Group			*/
-	stba		%g7, [%dst] %asi		/*  Store				*/
-1:	or		%g2, %g3, %g3		/*  IEU1				*/
-	or		%o5, %g3, %g3		/*  IEU0	Group (regdep)		*/
-	addcc		%g3, %sum, %sum		/*  IEU1	Group (regdep)		*/
-	bcs,a,pn	%xcc, 1f		/*  CTI					*/
-	 add		%sum, 1, %sum		/*  IEU0				*/
-1:	ba,pt		%xcc, 25b		/*  CTI		Group			*/
-	 sllx		%sum, 32, %g1		/*  IEU0				*/
+26:	andcc		%len, 8, %g0		/*  IEU1	Group		*/
+	be,pn		%icc, 1f		/*  CTI				*/
+	 lduw		[%src], %o4		/*  Load			*/
+	lduw		[%src+4], %g2		/*  Load	Group		*/
+	add		%src, 8, %src		/*  IEU0			*/
+	add		%dst, 8, %dst		/*  IEU1			*/
+	sllx		%o4, 32, %g5		/*  IEU0	Group		*/
+	stwa		%o4, [%dst - 8] %asi	/*  Store			*/
+	or		%g5, %g2, %g5		/*  IEU0	Group		*/
+	stwa		%g2, [%dst - 4]	%asi	/*  Store			*/
+	addcc		%g5, %sum, %sum		/*  IEU1	Group		*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%sum, 1, %sum		/*  IEU0			*/
+1:	andcc		%len, 4, %g0		/*  IEU1	Group		*/
+	be,a,pn		%icc, 1f		/*  CTI				*/
+	 clr		%g2			/*  IEU0			*/
+	lduw		[%src], %g7		/*  Load			*/
+	add		%src, 4, %src		/*  IEU0	Group		*/
+	add		%dst, 4, %dst		/*  IEU1			*/
+	sllx		%g7, 32, %g2		/*  IEU0	Group		*/
+	stwa		%g7, [%dst - 4] %asi	/*  Store			*/
+1:	andcc		%len, 2, %g0		/*  IEU1			*/
+	be,a,pn		%icc, 1f		/*  CTI				*/
+	 clr		%g3			/*  IEU0	Group		*/
+	lduh		[%src], %g7		/*  Load			*/
+	add		%src, 2, %src		/*  IEU1			*/
+	add		%dst, 2, %dst		/*  IEU0	Group		*/
+	sll		%g7, 16, %g3		/*  IEU0	Group		*/
+	stha		%g7, [%dst - 2] %asi	/*  Store			*/
+1:	andcc		%len, 1, %g0		/*  IEU1			*/
+	be,a,pn		%icc, 1f		/*  CTI				*/
+	 clr		%o5			/*  IEU0	Group		*/
+	ldub		[%src], %g7		/*  Load			*/
+	sll		%g7, 8, %o5		/*  IEU0	Group		*/
+	stba		%g7, [%dst] %asi	/*  Store			*/
+1:	or		%g2, %g3, %g3		/*  IEU1			*/
+	or		%o5, %g3, %g3		/*  IEU0	Group (regdep)	*/
+	addcc		%g3, %sum, %sum		/*  IEU1	Group (regdep)	*/
+	bcs,a,pn	%xcc, 1f		/*  CTI				*/
+	 add		%sum, 1, %sum		/*  IEU0			*/
+1:	ba,pt		%xcc, 25b		/*  CTI		Group		*/
+	 sllx		%sum, 32, %g1		/*  IEU0			*/
 
 #ifdef __KERNEL__
 end:
diff -u --recursive --new-file v2.3.47/linux/drivers/Makefile linux/drivers/Makefile
--- v2.3.47/linux/drivers/Makefile	Sun Feb 20 21:12:38 2000
+++ linux/drivers/Makefile	Fri Feb 25 10:26:42 2000
@@ -57,6 +57,11 @@
 MOD_SUB_DIRS += macintosh
 endif
 
+ifdef CONFIG_PPC
+SUB_DIRS += macintosh
+MOD_SUB_DIRS += macintosh
+endif
+
 ifeq ($(CONFIG_USB),y)
 SUB_DIRS += usb
 MOD_SUB_DIRS += usb
@@ -75,7 +80,7 @@
   endif
 endif 
 
-ifdef CONFIG_SGI
+ifdef CONFIG_SGI_IP22
 SUB_DIRS += sgi
 MOD_SUB_DIRS += sgi
 endif
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/Config.in linux/drivers/atm/Config.in
--- v2.3.47/linux/drivers/atm/Config.in	Thu Feb 10 17:11:06 2000
+++ linux/drivers/atm/Config.in	Mon Feb 21 16:32:27 2000
@@ -51,4 +51,29 @@
       bool '  Enable debugging messages' CONFIG_ATM_IA_DEBUG
     fi
 fi
+if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SBUS" = "y" ]; then
+  tristate 'FORE Systems 200E-series' CONFIG_ATM_FORE200E
+  if [ "$CONFIG_ATM_FORE200E" != "n" ]; then
+    if [ "$CONFIG_PCI" = "y" ]; then
+      bool '  PCA-200E support' CONFIG_ATM_FORE200E_PCA y
+      if [ "$CONFIG_ATM_FORE200E_PCA" = "y" ]; then
+	bool '   Use default PCA-200E firmware (normally enabled)' CONFIG_ATM_FORE200E_PCA_DEFAULT_FW
+        if [ "$CONFIG_ATM_FORE200E_PCA_DEFAULT_FW" = "n" ]; then
+          string '   Pathname of user-supplied binary firmware' CONFIG_ATM_FORE200E_PCA_FW
+        fi
+      fi
+    fi
+    if [ "$CONFIG_SBUS" = "y" ]; then
+      bool '  SBA-200E support' CONFIG_ATM_FORE200E_SBA y
+      if [ "$CONFIG_ATM_FORE200E_SBA" = "y" ]; then
+        bool '   Use default SBA-200E firmware (normally enabled)' CONFIG_ATM_FORE200E_SBA_DEFAULT_FW
+        if [ "$CONFIG_ATM_FORE200E_SBA_DEFAULT_FW" = "n" ]; then
+          string '   Pathname of user-supplied binary firmware' CONFIG_ATM_FORE200E_SBA_FW ""
+        fi
+      fi
+    fi
+    int  '  Maximum number of tx retries' CONFIG_ATM_FORE200E_TX_RETRY 16
+    int  '  Debugging level (0-3)' CONFIG_ATM_FORE200E_DEBUG 0
+  fi
+fi
 endmenu
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/Makefile linux/drivers/atm/Makefile
--- v2.3.47/linux/drivers/atm/Makefile	Thu Feb 10 17:11:06 2000
+++ linux/drivers/atm/Makefile	Mon Feb 21 16:32:27 2000
@@ -100,6 +100,58 @@
   LX_OBJS += $(NEED_IDT77105_LX)
 endif
 
+ifeq ($(CONFIG_ATM_FORE200E_PCA),y)
+FORE200E_FW_OBJS += fore200e_pca_fw.o
+  ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y)
+#   guess the target endianess to choose the right PCA-200E firmware image
+    CONFIG_ATM_FORE200E_PCA_FW := $(shell if test -n "`$(CC) -E -dM ../../include/asm/byteorder.h | grep ' __LITTLE_ENDIAN '`"; then echo pca200e.bin; else echo pca200e_ecd.bin2; fi)
+  endif
+endif
+ifeq ($(CONFIG_ATM_FORE200E_SBA),y)
+FORE200E_FW_OBJS += fore200e_sba_fw.o
+  ifeq ($(CONFIG_ATM_FORE200E_SBA_DEFAULT_FW),y)
+    CONFIG_ATM_FORE200E_SBA_FW := sba200e_ecd.bin2
+  endif
+endif
+ifeq ($(CONFIG_ATM_FORE200E),y)
+L_OBJS += fore200e.o $(FORE200E_FW_OBJS)
+else
+  ifeq ($(CONFIG_ATM_FORE200E),m)
+  M_OBJS += fore_200e.o
+  endif
+endif
+
 EXTRA_CFLAGS=-g
 
 include $(TOPDIR)/Rules.make
+
+# FORE Systems 200E-series firmware magic
+fore200e_pca_fw.c: $(patsubst "%", %, $(CONFIG_ATM_FORE200E_PCA_FW)) \
+	  fore200e_mkfirm
+	./fore200e_mkfirm -k -b _fore200e_pca_fw \
+	  -i $(CONFIG_ATM_FORE200E_PCA_FW) -o $@
+
+fore200e_sba_fw.c: $(patsubst "%", %, $(CONFIG_ATM_FORE200E_SBA_FW)) \
+	  fore200e_mkfirm
+	./fore200e_mkfirm -k -b _fore200e_sba_fw \
+	  -i $(CONFIG_ATM_FORE200E_SBA_FW) -o $@
+
+fore200e_mkfirm: fore200e_mkfirm.c
+	$(HOSTCC) $(HOSTCFLAGS) $< -o $@
+
+# deal with the various suffixes of the firmware images
+%.bin:  %.data
+	objcopy -Iihex $< -Obinary $@.gz
+	gzip -df $@.gz
+
+%.bin1: %.data
+	objcopy -Iihex $< -Obinary $@.gz
+	gzip -df $@.gz
+
+%.bin2: %.data
+	objcopy -Iihex $< -Obinary $@.gz
+	gzip -df $@.gz
+
+# module build
+fore_200e.o: fore200e.o $(FORE200E_FW_OBJS)
+	$(LD) -r -o $@ $< $(FORE200E_FW_OBJS)
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/atmdev_init.c linux/drivers/atm/atmdev_init.c
--- v2.3.47/linux/drivers/atm/atmdev_init.c	Thu Feb 10 17:11:06 2000
+++ linux/drivers/atm/atmdev_init.c	Mon Feb 21 16:32:27 2000
@@ -28,6 +28,9 @@
 #ifdef CONFIG_ATM_IA
 extern int ia_detect(void);
 #endif
+#ifdef CONFIG_ATM_FORE200E
+extern int fore200e_detect(void);
+#endif
 
 
 int __init atmdev_init(void)
@@ -55,6 +58,9 @@
 #endif
 #ifdef CONFIG_ATM_IA
 	devs += ia_detect();
+#endif
+#ifdef CONFIG_ATM_FORE200E
+        devs += fore200e_detect();
 #endif
 	return devs;
 }
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/eni.c linux/drivers/atm/eni.c
--- v2.3.47/linux/drivers/atm/eni.c	Thu Feb 10 17:11:06 2000
+++ linux/drivers/atm/eni.c	Mon Feb 21 16:32:27 2000
@@ -156,7 +156,8 @@
 
 static struct atm_dev *eni_boards = NULL;
 
-static u32 *zeroes = NULL; /* aligned "magic" zeroes */
+static u32 *cpu_zeroes = NULL; /* aligned "magic" zeroes */
+static dma_addr_t zeroes;
 
 /* Read/write registers on card */
 #define eni_in(r)	readl(eni_dev->reg+(r)*4)
@@ -349,18 +350,21 @@
 	struct eni_vcc *eni_vcc;
 	u32 dma_rd,dma_wr;
 	u32 dma[RX_DMA_BUF*2];
-	unsigned long paddr,here;
+	dma_addr_t paddr;
+	unsigned long here;
 	int i,j;
 
 	eni_dev = ENI_DEV(vcc->dev);
 	eni_vcc = ENI_VCC(vcc);
 	paddr = 0; /* GCC, shut up */
 	if (skb) {
-		paddr = (unsigned long) skb->data;
+		paddr = pci_map_single(eni_dev->pci_dev,skb->data,skb->len,
+		    PCI_DMA_FROMDEVICE);
+		ENI_PRV_PADDR(skb) = paddr;
 		if (paddr & 3)
 			printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %d has "
 			    "mis-aligned RX data (0x%lx)\n",vcc->dev->number,
-			    vcc->vci,paddr);
+			    vcc->vci,(unsigned long) paddr);
 		ENI_PRV_SIZE(skb) = size+skip;
 		    /* PDU plus descriptor */
 		ATM_SKB(skb)->vcc = vcc;
@@ -390,7 +394,7 @@
 			if (init > words) init = words;
 			dma[j++] = MID_DT_WORD | (init << MID_DMA_COUNT_SHIFT) |
 			    (vcc->vci << MID_DMA_VCI_SHIFT);
-			dma[j++] = virt_to_bus((void *) paddr);
+			dma[j++] = paddr;
 			paddr += init << 2;
 			words -= init;
 		}
@@ -399,7 +403,7 @@
 			dma[j++] = MID_DT_16W | ((words >> 4) <<
 			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
 			    MID_DMA_VCI_SHIFT);
-			dma[j++] = virt_to_bus((void *) paddr);
+			dma[j++] = paddr;
 			paddr += (words & ~15) << 2;
 			words &= 15;
 		}
@@ -409,7 +413,7 @@
 			dma[j++] = MID_DT_8W | ((words >> 3) <<
 			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
 			    MID_DMA_VCI_SHIFT);
-			dma[j++] = virt_to_bus((void *) paddr);
+			dma[j++] = paddr;
 			paddr += (words & ~7) << 2;
 			words &= 7;
 		}
@@ -419,7 +423,7 @@
 			dma[j++] = MID_DT_4W | ((words >> 2) <<
 			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
 			    MID_DMA_VCI_SHIFT);
-			dma[j++] = virt_to_bus((void *) paddr);
+			dma[j++] = paddr;
 			paddr += (words & ~3) << 2;
 			words &= 3;
 		}
@@ -429,7 +433,7 @@
 			dma[j++] = MID_DT_2W | ((words >> 1) <<
 			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
 			    MID_DMA_VCI_SHIFT);
-			dma[j++] = virt_to_bus((void *) paddr);
+			dma[j++] = paddr;
 			paddr += (words & ~1) << 2;
 			words &= 1;
 		}
@@ -437,7 +441,7 @@
 		if (words) {
 			dma[j++] = MID_DT_WORD | (words << MID_DMA_COUNT_SHIFT)
 			    | (vcc->vci << MID_DMA_VCI_SHIFT);
-			dma[j++] = virt_to_bus((void *) paddr);
+			dma[j++] = paddr;
 		}
 	}
 	if (size != eff) {
@@ -447,8 +451,7 @@
 	}
 	if (!j || j > 2*RX_DMA_BUF) {
 		printk(KERN_CRIT DEV_LABEL "!j or j too big!!!\n");
-		if (skb) kfree_skb(skb);
-		return -1;
+		goto trouble;
 	}
 	dma[j-2] |= MID_DMA_END;
 	j = j >> 1;
@@ -461,8 +464,7 @@
 	if (!NEPMOK(dma_wr,j+j+1,dma_rd,NR_DMA_RX)) { /* @@@ +1 is ugly */
 		printk(KERN_WARNING DEV_LABEL "(itf %d): RX DMA full\n",
 		    vcc->dev->number);
-		if (skb) kfree_skb(skb);
-		return -1;
+		goto trouble;
 	}
         for (i = 0; i < j; i++) {
 		writel(dma[i*2],eni_dev->rx_dma+dma_wr*8);
@@ -472,12 +474,19 @@
 	if (skb) {
 		ENI_PRV_POS(skb) = eni_vcc->descr+size+1;
 		skb_queue_tail(&eni_dev->rx_queue,skb);
-eni_vcc->last = skb;
+		eni_vcc->last = skb;
 rx_enqueued++;
 	}
 	eni_vcc->descr = here;
 	eni_out(dma_wr,MID_DMA_WR_RX);
 	return 0;
+
+trouble:
+	if (paddr)
+		pci_unmap_single(eni_dev->pci_dev,paddr,skb->len,
+		    PCI_DMA_FROMDEVICE);
+	if (skb) dev_kfree_skb_irq(skb);
+	return -1;
 }
 
 
@@ -747,7 +756,9 @@
 		}
 		eni_vcc->rxing--;
 		eni_vcc->rx_pos = ENI_PRV_POS(skb) & (eni_vcc->words-1);
-		if (!skb->len) kfree_skb(skb);
+		pci_unmap_single(eni_dev->pci_dev,ENI_PRV_PADDR(skb),skb->len,
+		    PCI_DMA_TODEVICE);
+		if (!skb->len) dev_kfree_skb_irq(skb);
 		else {
 			EVENT("pushing (len=%ld)\n",skb->len,0);
 			if (vcc->qos.aal == ATM_AAL0)
@@ -902,13 +913,13 @@
 enum enq_res { enq_ok,enq_next,enq_jam };
 
 
-static inline void put_dma(int chan,u32 *dma,int *j,unsigned long paddr,
+static inline void put_dma(int chan,u32 *dma,int *j,dma_addr_t paddr,
     u32 size)
 {
 	u32 init,words;
 
-	DPRINTK("put_dma: 0x%lx+0x%x\n",paddr,size);
-	EVENT("put_dma: 0x%lx+0x%lx\n",paddr,size);
+	DPRINTK("put_dma: 0x%lx+0x%x\n",(unsigned long) paddr,size);
+	EVENT("put_dma: 0x%lx+0x%lx\n",(unsigned long) paddr,size);
 #if 0 /* don't complain anymore */
 	if (paddr & 3)
 		printk(KERN_ERR "put_dma: unaligned addr (0x%lx)\n",paddr);
@@ -918,10 +929,11 @@
 	if (paddr & 3) {
 		init = 4-(paddr & 3);
 		if (init > size || size < 7) init = size;
-		DPRINTK("put_dma: %lx DMA: %d/%d bytes\n",paddr,init,size);
+		DPRINTK("put_dma: %lx DMA: %d/%d bytes\n",
+		    (unsigned long) paddr,init,size);
 		dma[(*j)++] = MID_DT_BYTE | (init << MID_DMA_COUNT_SHIFT) |
 		    (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = virt_to_bus((void *) paddr);
+		dma[(*j)++] = paddr;
 		paddr += init;
 		size -= init;
 	}
@@ -930,10 +942,11 @@
 	if (words && (paddr & 31)) {
 		init = 8-((paddr & 31) >> 2);
 		if (init > words) init = words;
-		DPRINTK("put_dma: %lx DMA: %d/%d words\n",paddr,init,words);
+		DPRINTK("put_dma: %lx DMA: %d/%d words\n",
+		    (unsigned long) paddr,init,words);
 		dma[(*j)++] = MID_DT_WORD | (init << MID_DMA_COUNT_SHIFT) |
 		    (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = virt_to_bus((void *) paddr);
+		dma[(*j)++] = paddr;
 		paddr += init << 2;
 		words -= init;
 	}
@@ -943,18 +956,18 @@
 		    words);
 		dma[(*j)++] = MID_DT_16W | ((words >> 4) << MID_DMA_COUNT_SHIFT)
 		    | (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = virt_to_bus((void *) paddr);
+		dma[(*j)++] = paddr;
 		paddr += (words & ~15) << 2;
 		words &= 15;
 	}
 #endif
 #ifdef CONFIG_ATM_ENI_BURST_TX_8W /* recommended */
 	if (words & ~7) {
-		DPRINTK("put_dma: %lx DMA: %d*8/%d words\n",paddr,words >> 3,
-		    words);
+		DPRINTK("put_dma: %lx DMA: %d*8/%d words\n",
+		    (unsigned long) paddr,words >> 3,words);
 		dma[(*j)++] = MID_DT_8W | ((words >> 3) << MID_DMA_COUNT_SHIFT)
 		    | (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = virt_to_bus((void *) paddr);
+		dma[(*j)++] = paddr;
 		paddr += (words & ~7) << 2;
 		words &= 7;
 	}
@@ -965,7 +978,7 @@
 		    words);
 		dma[(*j)++] = MID_DT_4W | ((words >> 2) << MID_DMA_COUNT_SHIFT)
 		    | (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = virt_to_bus((void *) paddr);
+		dma[(*j)++] = paddr;
 		paddr += (words & ~3) << 2;
 		words &= 3;
 	}
@@ -976,23 +989,25 @@
 		    words);
 		dma[(*j)++] = MID_DT_2W | ((words >> 1) << MID_DMA_COUNT_SHIFT)
 		    | (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = virt_to_bus((void *) paddr);
+		dma[(*j)++] = paddr;
 		paddr += (words & ~1) << 2;
 		words &= 1;
 	}
 #endif
 	if (words) {
-		DPRINTK("put_dma: %lx DMA: %d words\n",paddr,words);
+		DPRINTK("put_dma: %lx DMA: %d words\n",(unsigned long) paddr,
+		    words);
 		dma[(*j)++] = MID_DT_WORD | (words << MID_DMA_COUNT_SHIFT) |
 		    (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = virt_to_bus((void *) paddr);
+		dma[(*j)++] = paddr;
 		paddr += words << 2;
 	}
 	if (size) {
-		DPRINTK("put_dma: %lx DMA: %d bytes\n",paddr,size);
+		DPRINTK("put_dma: %lx DMA: %d bytes\n",(unsigned long) paddr,
+		    size);
 		dma[(*j)++] = MID_DT_BYTE | (size << MID_DMA_COUNT_SHIFT) |
 		    (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = virt_to_bus((void *) paddr);
+		dma[(*j)++] = paddr;
 	}
 }
 
@@ -1003,6 +1018,7 @@
 	struct eni_dev *eni_dev;
 	struct eni_vcc *eni_vcc;
 	struct eni_tx *tx;
+	dma_addr_t paddr;
 	u32 dma_rd,dma_wr;
 	u32 size; /* in words */
 	int aal5,dma_size,i,j;
@@ -1079,6 +1095,9 @@
 		    vcc->dev->number);
 		return enq_jam;
 	}
+	paddr = pci_map_single(eni_dev->pci_dev,skb->data,skb->len,
+	    PCI_DMA_TODEVICE);
+	ENI_PRV_PADDR(skb) = paddr;
 	/* prepare DMA queue entries */
 	j = 0;
 	eni_dev->dma[j++] = (((tx->tx_pos+TX_DESCR_SIZE) & (tx->words-1)) <<
@@ -1086,21 +1105,17 @@
 	     MID_DT_JK;
 	j++;
 	if (!ATM_SKB(skb)->iovcnt)
-		if (aal5)
-			put_dma(tx->index,eni_dev->dma,&j,
-			    (unsigned long) skb->data,skb->len);
-		else put_dma(tx->index,eni_dev->dma,&j,
-			    (unsigned long) skb->data+4,skb->len-4);
+		if (aal5) put_dma(tx->index,eni_dev->dma,&j,paddr,skb->len);
+		else put_dma(tx->index,eni_dev->dma,&j,paddr+4,skb->len-4);
 	else {
-DPRINTK("doing direct send\n");
+DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */
 		for (i = 0; i < ATM_SKB(skb)->iovcnt; i++)
 			put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
 			    ((struct iovec *) skb->data)[i].iov_base,
 			    ((struct iovec *) skb->data)[i].iov_len);
 	}
 	if (skb->len & 3)
-		put_dma(tx->index,eni_dev->dma,&j,
-		    (unsigned long) zeroes,4-(skb->len & 3));
+		put_dma(tx->index,eni_dev->dma,&j,zeroes,4-(skb->len & 3));
 	/* JK for AAL5 trailer - AAL0 doesn't need it, but who cares ... */
 	eni_dev->dma[j++] = (((tx->tx_pos+size) & (tx->words-1)) <<
 	     MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) |
@@ -1188,8 +1203,10 @@
 			break;
 		}
 		ENI_VCC(vcc)->txing -= ENI_PRV_SIZE(skb);
+		pci_unmap_single(eni_dev->pci_dev,ENI_PRV_PADDR(skb),skb->len,
+		    PCI_DMA_TODEVICE);
 		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb(skb);
+		else dev_kfree_skb_irq(skb);
 		vcc->stats->tx++;
 		wake_up(&eni_dev->tx_wait);
 dma_complete++;
@@ -1670,7 +1687,7 @@
 	    (eni_dev->asic ? PCI_COMMAND_PARITY | PCI_COMMAND_SERR : 0)))) {
 		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory "
 		    "(0x%02x)\n",dev->number,error);
-		return error;
+		return -EIO;
 	}
 	printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%lx,irq=%d,",
 	    dev->number,revision,real_base,eni_dev->irq);
@@ -2020,7 +2037,6 @@
 	if (!skb) {
 		printk(KERN_CRIT "!skb in eni_send ?\n");
 		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb(skb);
 		return -EINVAL;
 	}
 	if (vcc->qos.aal == ATM_AAL0) {
@@ -2195,7 +2211,14 @@
 	struct atm_dev *dev;
 	struct eni_dev *eni_dev;
 	int devs,type;
+	struct sk_buff *skb;
 
+	DPRINTK("eni_detect\n");
+	if (sizeof(skb->cb) < sizeof(struct eni_skb_prv)) {
+		printk(KERN_ERR "eni_detect: skb->cb is too small (%d < %d)\n",
+		    sizeof(skb->cb),sizeof(struct eni_skb_prv));
+		return 0;
+	}
 	eni_dev = (struct eni_dev *) kmalloc(sizeof(struct eni_dev),
 	    GFP_KERNEL);
 	if (!eni_dev) return -ENOMEM;
@@ -2208,8 +2231,9 @@
 		    PCI_DEVICE_ID_EF_ATM_ASIC : PCI_DEVICE_ID_EF_ATM_FPGA,
 		    pci_dev))) {
 			if (!devs) {
-				zeroes = kmalloc(4,GFP_KERNEL);
-				if (!zeroes) {
+				cpu_zeroes = pci_alloc_consistent(pci_dev,
+				    ENI_ZEROES_SIZE,&zeroes);
+				if (!cpu_zeroes) {
 					kfree(eni_dev);
 					return -ENOMEM;
 				}
@@ -2231,11 +2255,12 @@
 			if (!eni_dev) break;
 		}
 	}
-	kfree(eni_dev);
-	if (!devs && zeroes) {
-		kfree(zeroes);
-		zeroes = NULL;
+	if (!devs && cpu_zeroes) {
+		pci_free_consistent(eni_dev->pci_dev,ENI_ZEROES_SIZE,
+		    cpu_zeroes,zeroes);
+		cpu_zeroes = NULL;
 	}
+	kfree(eni_dev);
 	return devs;
 }
 
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/eni.h linux/drivers/atm/eni.h
--- v2.3.47/linux/drivers/atm/eni.h	Thu Feb 10 17:11:06 2000
+++ linux/drivers/atm/eni.h	Mon Feb 21 16:32:27 2000
@@ -27,6 +27,8 @@
 #define DEFAULT_RX_MULT	300		/* max_sdu*3 */
 #define DEFAULT_TX_MULT	300		/* max_sdu*3 */
 
+#define ENI_ZEROES_SIZE	  4		/* need that many DMA-able zero bytes */
+
 
 struct eni_free {
 	unsigned long start;		/* counting in bytes */
@@ -113,9 +115,11 @@
 	struct atm_skb_data _;		/* reserved */
 	unsigned long pos;		/* position of next descriptor */
 	int size;			/* PDU size in reassembly buffer */
+	dma_addr_t paddr;		/* DMA handle */
 };
 
 #define ENI_PRV_SIZE(skb) (((struct eni_skb_prv *) (skb)->cb)->size)
 #define ENI_PRV_POS(skb) (((struct eni_skb_prv *) (skb)->cb)->pos)
+#define ENI_PRV_PADDR(skb) (((struct eni_skb_prv *) (skb)->cb)->paddr)
 
 #endif
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/fore200e.c linux/drivers/atm/fore200e.c
--- v2.3.47/linux/drivers/atm/fore200e.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/atm/fore200e.c	Mon Feb 21 16:32:27 2000
@@ -0,0 +1,2973 @@
+/*
+  $Id: fore200e.c,v 1.1 2000/02/21 16:04:31 davem Exp $
+
+  A FORE Systems 200E-series driver for ATM on Linux.
+  Christophe Lizzi (lizzi@cnam.fr), October 1999-February 2000.
+
+  Based on the PCA-200E driver from Uwe Dannowski (Uwe.Dannowski@inf.tu-dresden.de).
+
+  This driver simultaneously supports PCA-200E and SBA-200E adapters
+  on i386, alpha (untested), powerpc, sparc and sparc64 architectures.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/init.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
+#include <linux/atmdev.h>
+#include <linux/sonet.h>
+#include <linux/atm_suni.h>
+#include <asm/io.h>
+#include <asm/string.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_ATM_FORE200E_PCA
+#include <linux/pci.h>
+#endif
+
+#ifdef CONFIG_ATM_FORE200E_SBA
+#include <asm/idprom.h>
+#include <asm/sbus.h>
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+#include <asm/pgtable.h>
+#endif
+
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
+#include "fore200e.h"
+#include "suni.h"
+
+#if 1   /* ensure correct handling of 52-byte AAL0 SDUs used by atmdump-like apps */
+#define FORE200E_52BYTE_AAL0_SDU
+#endif
+
+#define FORE200E_VERSION "0.2a"
+
+
+#define FORE200E         "fore200e: "
+
+#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
+#define DPRINTK(level, format, args...)  do { if (CONFIG_ATM_FORE200E_DEBUG >= (level)) \
+                                                  printk(FORE200E format, ##args); } while(0)
+#else
+#define DPRINTK(level, format, args...)  while(0)
+#endif
+
+
+#define FORE200E_ALIGN(addr, alignment) \
+        ((((unsigned long)(addr) + (alignment - 1)) & ~(alignment - 1)) - (unsigned long)(addr))
+
+#define FORE200E_DMA_INDEX(dma_addr, type, index)  ((dma_addr) + (index) * sizeof(type))
+
+#define FORE200E_INDEX(virt_addr, type, index)     (&((type *)(virt_addr))[ index ])
+
+#define FORE200E_NEXT_ENTRY(index, modulo)    (index = ++(index) % (modulo))
+
+
+#define MSECS(ms)  (((ms)*HZ/1000)+1)
+
+
+extern const struct atmdev_ops   fore200e_ops;
+extern const struct fore200e_bus fore200e_bus[];
+
+static struct fore200e* fore200e_boards = NULL;
+
+
+#ifdef MODULE
+MODULE_AUTHOR("Christophe Lizzi - credits to Uwe Dannowski and Heikki Vatiainen");
+MODULE_DESCRIPTION("FORE Systems 200E-series ATM driver - version " FORE200E_VERSION);
+MODULE_SUPPORTED_DEVICE("PCA-200E, SBA-200E");
+#endif
+
+
+static const int fore200e_rx_buf_nbr[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = {
+    { BUFFER_S1_NBR, BUFFER_L1_NBR },
+    { BUFFER_S2_NBR, BUFFER_L2_NBR }
+};
+
+static const int fore200e_rx_buf_size[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = {
+    { BUFFER_S1_SIZE, BUFFER_L1_SIZE },
+    { BUFFER_S2_SIZE, BUFFER_L2_SIZE }
+};
+
+
+#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
+static const char* fore200e_traffic_class[] = { "NONE", "UBR", "CBR", "VBR", "ABR", "ANY" };
+#endif
+
+
+#if 0 /* currently unused */
+static int 
+fore200e_fore2atm_aal(enum fore200e_aal aal)
+{
+    switch(aal) {
+    case FORE200E_AAL0:  return ATM_AAL0;
+    case FORE200E_AAL34: return ATM_AAL34;
+    case FORE200E_AAL5:  return ATM_AAL5;
+    }
+
+    return -EINVAL;
+}
+#endif
+
+
+static enum fore200e_aal
+fore200e_atm2fore_aal(int aal)
+{
+    switch(aal) {
+    case ATM_AAL0:  return FORE200E_AAL0;
+    case ATM_AAL34: return FORE200E_AAL34;
+    case ATM_AAL1:
+    case ATM_AAL2:
+    case ATM_AAL5:  return FORE200E_AAL5;
+    }
+
+    return -EINVAL;
+}
+
+
+static char*
+fore200e_irq_itoa(int irq)
+{
+#if defined(__sparc_v9__)
+    return __irq_itoa(irq);
+#else
+    static char str[8];
+    sprintf(str, "%d", irq);
+    return str;
+#endif
+}
+
+
+static void*
+fore200e_kmalloc(int size, int flags)
+{
+    void* chunk = kmalloc(size, flags);
+
+    if (chunk)
+	memset(chunk, 0x00, size);
+    else
+	printk(FORE200E "kmalloc() failed, requested size = %d, flags = 0x%x\n", size, flags);
+    
+    return chunk;
+}
+
+
+static void
+fore200e_kfree(void* chunk)
+{
+    kfree(chunk);
+}
+
+
+/* allocate and align a chunk of memory intended to hold the data behing exchanged
+   between the driver and the adapter (using streaming DVMA on SBUS hosts) */
+
+static int
+fore200e_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int alignment)
+{
+    unsigned long offset = 0;
+
+    if (alignment <= sizeof(int))
+	alignment = 0;
+
+    chunk->alloc_size = size + alignment;
+    chunk->align_size = size;
+
+    chunk->alloc_addr = fore200e_kmalloc(chunk->alloc_size, GFP_KERNEL | GFP_DMA);
+    if (chunk->alloc_addr == NULL)
+	return -ENOMEM;
+
+    if (alignment > 0)
+	offset = FORE200E_ALIGN(chunk->alloc_addr, alignment); 
+    
+    chunk->align_addr = chunk->alloc_addr + offset;
+
+    chunk->dma_addr = fore200e->bus->dma_map(fore200e, chunk->align_addr, chunk->align_size);
+    
+    return 0;
+}
+
+
+/* free a chunk of memory */
+
+static void
+fore200e_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
+{
+    fore200e->bus->dma_unmap(fore200e, chunk->dma_addr, chunk->dma_size);
+
+    fore200e_kfree(chunk->alloc_addr);
+}
+
+
+
+#if 0 /* currently unused */
+static int
+fore200e_checkup(struct fore200e* fore200e)
+{
+    u32 hb1, hb2;
+
+    hb1 = fore200e->bus->read(&fore200e->cp_queues->heartbeat);
+    fore200e_spin(10);
+    hb2 = fore200e->bus->read(&fore200e->cp_queues->heartbeat);
+    
+    if (hb2 <= hb1) {
+	printk(FORE200E "device %s heartbeat is not counting upwards, hb1 = %x; hb2 = %x\n",
+	       fore200e->name, hb1, hb2);
+	return -EIO;
+    }
+    printk(FORE200E "device %s heartbeat is ok\n", fore200e->name);
+    
+    return 0;
+}
+#endif 
+
+
+static void
+fore200e_spin(int msecs)
+{
+    unsigned long timeout = jiffies + MSECS(msecs);
+    while (jiffies < timeout);
+}
+
+
+static int
+fore200e_poll(struct fore200e* fore200e, volatile u32* addr, u32 val, int msecs)
+{
+    unsigned long timeout = jiffies + MSECS(msecs);
+    int           ok;
+
+    mb();
+    do {
+	if ((ok = (*addr == val)) || (*addr & STATUS_ERROR))
+	    break;
+
+    } while (jiffies < timeout);
+
+#if 1
+    if (!ok) {
+	printk(FORE200E "cmd polling failed, got status 0x%08x, expected 0x%08x\n",
+	       *addr, val);
+    }
+#endif
+
+    return ok;
+}
+
+
+static int
+fore200e_io_poll(struct fore200e* fore200e, volatile u32* addr, u32 val, int msecs)
+{
+    unsigned long timeout = jiffies + MSECS(msecs);
+    int           ok;
+
+    do {
+	if ((ok = (fore200e->bus->read(addr) == val)))
+	    break;
+
+    } while (jiffies < timeout);
+
+#if 1
+    if (!ok) {
+	printk(FORE200E "I/O polling failed, got status 0x%08x, expected 0x%08x\n",
+	       fore200e->bus->read(addr), val);
+    }
+#endif
+
+    return ok;
+}
+
+
+static void
+fore200e_free_rx_buf(struct fore200e* fore200e)
+{
+    int scheme, magn, nbr;
+    struct buffer* buffer;
+
+    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
+	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
+
+	    if ((buffer = fore200e->host_bsq[ scheme ][ magn ].buffer) != NULL) {
+
+		for (nbr = 0; nbr < fore200e_rx_buf_nbr[ scheme ][ magn ]; nbr++) {
+
+		    struct chunk* data = &buffer[ nbr ].data;
+
+		    if (data->alloc_addr != NULL)
+			fore200e_chunk_free(fore200e, data);
+		}
+	    }
+	}
+    }
+}
+
+
+static void
+fore200e_uninit_bs_queue(struct fore200e* fore200e)
+{
+    int scheme, magn;
+    
+    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
+	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
+
+	    struct chunk* status    = &fore200e->host_bsq[ scheme ][ magn ].status;
+	    struct chunk* rbd_block = &fore200e->host_bsq[ scheme ][ magn ].rbd_block;
+	    
+	    if (status->alloc_addr)
+		fore200e->bus->dma_chunk_free(fore200e, status);
+	    
+	    if (rbd_block->alloc_addr)
+		fore200e->bus->dma_chunk_free(fore200e, rbd_block);
+	}
+    }
+}
+
+
+static int
+fore200e_reset(struct fore200e* fore200e, int diag)
+{
+    int ok;
+
+    fore200e->cp_monitor = (struct cp_monitor*)(fore200e->virt_base + FORE200E_CP_MONITOR_OFFSET);
+    
+    fore200e->bus->write(BSTAT_COLD_START, &fore200e->cp_monitor->bstat);
+
+    fore200e->bus->reset(fore200e);
+
+    if (diag) {
+	ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_SELFTEST_OK, 1000);
+	if (ok == 0) {
+	    
+	    printk(FORE200E "device %s self-test failed\n", fore200e->name);
+	    return -ENODEV;
+	}
+
+	printk(FORE200E "device %s self-test passed\n", fore200e->name);
+	
+	fore200e->state = FORE200E_STATE_RESET;
+    }
+
+    return 0;
+}
+
+
+static void
+fore200e_shutdown(struct fore200e* fore200e)
+{
+    printk(FORE200E "removing device %s at 0x%lx, IRQ %s\n",
+	   fore200e->name, fore200e->phys_base, 
+	   fore200e_irq_itoa(fore200e->irq));
+    
+    if (fore200e->state > FORE200E_STATE_RESET) {
+	/* first, reset the board to prevent further interrupts or data transfers */
+	fore200e_reset(fore200e, 0);
+    }
+    
+    /* then, release all allocated resources */
+    switch(fore200e->state) {
+
+    case FORE200E_STATE_COMPLETE:
+	if (fore200e->stats)
+	    kfree(fore200e->stats);
+
+    case FORE200E_STATE_IRQ:
+	free_irq(fore200e->irq, fore200e->atm_dev);
+
+    case FORE200E_STATE_ALLOC_BUF:
+	fore200e_free_rx_buf(fore200e);
+
+    case FORE200E_STATE_INIT_BSQ:
+	fore200e_uninit_bs_queue(fore200e);
+
+    case FORE200E_STATE_INIT_RXQ:
+	fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_rxq.status);
+	fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_rxq.rpd);
+
+    case FORE200E_STATE_INIT_TXQ:
+	fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_txq.status);
+	fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_txq.tpd);
+
+    case FORE200E_STATE_INIT_CMDQ:
+	fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_cmdq.status);
+
+    case FORE200E_STATE_INITIALIZE:
+	/* nothing to do for that state */
+
+    case FORE200E_STATE_START_FW:
+	/* nothing to do for that state */
+
+    case FORE200E_STATE_LOAD_FW:
+	/* nothing to do for that state */
+
+    case FORE200E_STATE_RESET:
+	/* nothing to do for that state */
+
+    case FORE200E_STATE_MAP:
+	fore200e->bus->unmap(fore200e);
+
+    case FORE200E_STATE_CONFIGURE:
+	/* nothing to do for that state */
+
+    case FORE200E_STATE_REGISTER:
+	/* XXX shouldn't we *start* by deregistering the device? */
+	atm_dev_deregister(fore200e->atm_dev);
+
+    case FORE200E_STATE_BLANK:
+	/* nothing to do for that state */
+    }
+}
+
+
+#ifdef CONFIG_ATM_FORE200E_PCA
+
+static u32 fore200e_pca_read(volatile u32* addr)
+{
+    /* on big-endian hosts, the board is configured to convert
+       the endianess of slave RAM accesses  */
+    return le32_to_cpu(readl(addr));
+}
+
+
+static void fore200e_pca_write(u32 val, volatile u32* addr)
+{
+    /* on big-endian hosts, the board is configured to convert
+       the endianess of slave RAM accesses  */
+    writel(cpu_to_le32(val), addr);
+}
+
+
+static u32
+fore200e_pca_dma_map(struct fore200e* fore200e, void* virt_addr, int size)
+{
+    u32 dma_addr = pci_map_single((struct pci_dev*)fore200e->bus_dev, virt_addr, size, PCI_DMA_BIDIRECTIONAL);
+
+    DPRINTK(3, "PCI DVMA mapping: virt_addr = 0x%p, size = %d --> dma_addr = 0x%08x\n",
+	    virt_addr, size, dma_addr);
+    
+    return dma_addr;
+}
+
+
+static void
+fore200e_pca_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size)
+{
+    DPRINTK(3, "PCI DVMA unmapping: dma_addr = 0x%08x, size = %d\n", dma_addr, size);
+
+    pci_unmap_single((struct pci_dev*)fore200e->bus_dev, dma_addr, size,
+      PCI_DMA_BIDIRECTIONAL);
+}
+
+
+static void
+fore200e_pca_dma_sync(struct fore200e* fore200e, u32 dma_addr, int size)
+{
+    DPRINTK(3, "PCI DVMA sync: dma_addr = 0x%08x, size = %d\n", dma_addr, size);
+
+    pci_dma_sync_single((struct pci_dev*)fore200e->bus_dev, dma_addr, size,
+      PCI_DMA_BIDIRECTIONAL);
+}
+
+
+/* allocate a DMA consistent chunk of memory intended to act as a communication mechanism
+   (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */
+
+static int
+fore200e_pca_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int nbr, int alignment)
+{
+#if defined(__sparc_v9__)
+    /* returned chunks are page-aligned */
+    chunk->alloc_addr = pci_alloc_consistent((struct pci_dev*)fore200e->bus_dev,
+					     chunk->alloc_size,
+					     &chunk->dma_addr);
+    
+    if (chunk->alloc_addr == NULL || chunk->dma_addr == 0)
+	return -ENOMEM;
+
+    chunk->align_addr = chunk->alloc_addr;
+#else
+    if (fore200e_chunk_alloc(fore200e, chunk, size * nbr, alignment) < 0)
+	return -ENOMEM;
+    
+    chunk->dma_addr = fore200e_pca_dma_map(fore200e, chunk->align_addr, chunk->align_size);
+#endif
+    
+    return 0;
+}
+
+
+/* free a DMA consistent chunk of memory */
+
+static void
+fore200e_pca_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
+{
+#if defined(__sparc_v9__)
+    pci_free_consistent((struct pci_dev*)fore200e->bus_dev,
+			chunk->alloc_size,
+			chunk->alloc_addr,
+			chunk->dma_addr);
+#else
+    fore200e_pca_dma_unmap(fore200e, chunk->dma_addr, chunk->dma_size);
+    
+    fore200e_chunk_free(fore200e, chunk);
+#endif
+}
+
+
+static int
+fore200e_pca_irq_check(struct fore200e* fore200e)
+{
+    /* this is a 1 bit register */
+    return readl(fore200e->regs.pca.psr);
+}
+
+
+static void
+fore200e_pca_irq_ack(struct fore200e* fore200e)
+{
+    writel(PCA200E_HCR_CLRINTR, fore200e->regs.pca.hcr);
+}
+
+
+static void
+fore200e_pca_reset(struct fore200e* fore200e)
+{
+    writel(PCA200E_HCR_RESET, fore200e->regs.pca.hcr);
+    fore200e_spin(10);
+    writel(0, fore200e->regs.pca.hcr);
+}
+
+
+static int __init
+fore200e_pca_map(struct fore200e* fore200e)
+{
+    DPRINTK(2, "device %s being mapped in memory\n", fore200e->name);
+
+    fore200e->virt_base = ioremap(fore200e->phys_base, PCA200E_IOSPACE_LENGTH);
+    
+    if (fore200e->virt_base == NULL) {
+	printk(FORE200E "can't map device %s\n", fore200e->name);
+	return -EFAULT;
+    }
+
+    DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
+
+    /* gain access to the PCA-200E specific registers  */
+    fore200e->regs.pca.hcr = (u32*)(fore200e->virt_base + PCA200E_HCR_OFFSET);
+    fore200e->regs.pca.imr = (u32*)(fore200e->virt_base + PCA200E_IMR_OFFSET);
+    fore200e->regs.pca.psr = (u32*)(fore200e->virt_base + PCA200E_PSR_OFFSET);
+
+    fore200e->state = FORE200E_STATE_MAP;
+    return 0;
+}
+
+
+static void
+fore200e_pca_unmap(struct fore200e* fore200e)
+{
+    DPRINTK(2, "device %s being unmapped from memory\n", fore200e->name);
+
+    /* XXX iounmap() does nothing on PowerPC (at least in 2.2.12 and 2.3.41),
+       this leads to a kernel panic if the module is loaded and unloaded several times */
+    if (fore200e->virt_base != NULL)
+	iounmap(fore200e->virt_base);
+}
+
+
+static int __init
+fore200e_pca_configure(struct fore200e* fore200e)
+{
+    struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev;
+    u8              master_ctrl;
+
+    DPRINTK(2, "device %s being configured\n", fore200e->name);
+
+    if ((pci_dev->irq == 0) || (pci_dev->irq == 0xFF)) {
+	printk(FORE200E "incorrect IRQ setting - misconfigured PCI-PCI bridge?\n");
+	return -EIO;
+    }
+
+	pci_read_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, &master_ctrl);
+
+    master_ctrl = master_ctrl
+#if 0
+	| PCA200E_CTRL_DIS_CACHE_RD
+        | PCA200E_CTRL_DIS_WRT_INVAL
+#endif
+#if defined(__BIG_ENDIAN)
+	/* request the PCA board to convert the endianess of slave RAM accesses */
+	| PCA200E_CTRL_CONVERT_ENDIAN
+#endif
+	| PCA200E_CTRL_LARGE_PCI_BURSTS;
+    
+    pci_write_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, master_ctrl);
+
+    fore200e->state = FORE200E_STATE_CONFIGURE;
+    return 0;
+}
+
+
+static struct fore200e* __init
+fore200e_pca_detect(const struct fore200e_bus* bus, int index)
+{
+    struct fore200e* fore200e;
+    struct pci_dev*  pci_dev = NULL;
+    int              count = index;
+    
+    if (pci_present() == 0) {
+	printk(FORE200E "no PCI subsystem\n");
+	return NULL;
+    }
+
+    do {
+	pci_dev = pci_find_device(PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, pci_dev);
+	if (pci_dev == NULL)
+	    return NULL;
+    } while (count--);
+    
+    fore200e = fore200e_kmalloc(sizeof(struct fore200e), GFP_KERNEL);
+    if (fore200e == NULL)
+	return NULL;
+
+    fore200e->bus       = bus;
+    fore200e->bus_dev   = pci_dev;    
+    fore200e->irq       = pci_dev->irq;
+    fore200e->phys_base = (pci_dev->resource[0].start & PCI_BASE_ADDRESS_MEM_MASK);
+
+#if defined(__powerpc__)
+    fore200e->phys_base += KERNELBASE;
+#endif
+
+    sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1);
+
+    pci_set_master(pci_dev);
+
+    return fore200e;
+}
+
+
+static int __init
+fore200e_pca_prom_read(struct fore200e* fore200e, struct prom_data* prom)
+{
+    struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
+    struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
+    struct prom_opcode      opcode;
+    int                     ok;
+    u32                     prom_dma;
+
+    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
+
+    opcode.opcode = OPCODE_GET_PROM;
+    opcode.pad    = 0;
+
+    prom_dma = fore200e->bus->dma_map(fore200e, prom, sizeof(struct prom_data));
+
+    fore200e->bus->write(prom_dma, &entry->cp_entry->cmd.prom_block.prom_haddr);
+    
+    *entry->status = STATUS_PENDING;
+
+    fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.prom_block.opcode);
+
+    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
+
+    *entry->status = STATUS_FREE;
+
+    fore200e->bus->dma_unmap(fore200e, prom_dma, sizeof(struct prom_data));
+
+    if (ok == 0) {
+	printk(FORE200E "unable to get PROM data from device %s\n", fore200e->name);
+	return -EIO;
+    }
+
+#if defined(__BIG_ENDIAN)
+    
+#define swap_here(addr) (*((u32*)(addr)) = swab32( *((u32*)(addr)) ))
+
+    /* MAC address is stored as little-endian */
+    swap_here(&prom->mac_addr[0]);
+    swap_here(&prom->mac_addr[4]);
+#endif
+    
+    return 0;
+}
+
+
+static int
+fore200e_pca_proc_read(struct fore200e* fore200e, char *page)
+{
+    struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev;
+
+    return sprintf(page, "   PCI bus/slot/function:\t%d/%d/%d\n",
+		   pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
+}
+
+#endif /* CONFIG_ATM_FORE200E_PCA */
+
+
+
+
+#ifdef CONFIG_ATM_FORE200E_SBA
+
+static u32
+fore200e_sba_read(volatile u32* addr)
+{
+    return sbus_readl(addr);
+}
+
+
+static void
+fore200e_sba_write(u32 val, volatile u32* addr)
+{
+    sbus_writel(val, addr);
+}
+
+
+static u32
+fore200e_sba_dma_map(struct fore200e* fore200e, void* virt_addr, int size)
+{
+    u32 dma_addr = sbus_map_single((struct sbus_dev*)fore200e->bus_dev, virt_addr, size);
+
+    DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d --> dma_addr = 0x%08x\n", virt_addr, size, dma_addr);
+    
+    return dma_addr;
+}
+
+
+static void
+fore200e_sba_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size)
+{
+    DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d\n", dma_addr, size);
+
+    sbus_unmap_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size);
+}
+
+
+static void
+fore200e_sba_dma_sync(struct fore200e* fore200e, u32 dma_addr, int size)
+{
+    DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d\n", dma_addr, size);
+    
+    sbus_dma_sync_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size);
+}
+
+
+/* allocate a DVMA consistent chunk of memory intended to act as a communication mechanism
+   (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */
+
+static int
+fore200e_sba_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int nbr, int alignment)
+{
+    chunk->alloc_size = chunk->align_size = size * nbr;
+
+    /* returned chunks are page-aligned */
+    chunk->alloc_addr = sbus_alloc_consistent((struct sbus_dev*)fore200e->bus_dev,
+					      chunk->alloc_size,
+					      &chunk->dma_addr);
+
+    if (chunk->alloc_addr == NULL || chunk->dma_addr == 0)
+	return -ENOMEM;
+
+    chunk->align_addr = chunk->alloc_addr;
+    
+    return 0;
+}
+
+
+/* free a DVMA consistent chunk of memory */
+
+static void
+fore200e_sba_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
+{
+    sbus_free_consistent((struct sbus_dev*)fore200e->bus_dev,
+			 chunk->alloc_size,
+			 chunk->alloc_addr,
+			 chunk->dma_addr);
+}
+
+
+static void
+fore200e_sba_irq_enable(struct fore200e* fore200e)
+{
+    u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
+    fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr);
+}
+
+
+static int
+fore200e_sba_irq_check(struct fore200e* fore200e)
+{
+    return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ;
+}
+
+
+static void
+fore200e_sba_irq_ack(struct fore200e* fore200e)
+{
+    u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
+    fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr);
+}
+
+
+static void
+fore200e_sba_reset(struct fore200e* fore200e)
+{
+    fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr);
+    fore200e_spin(10);
+    fore200e->bus->write(0, fore200e->regs.sba.hcr);
+}
+
+
+static int __init
+fore200e_sba_map(struct fore200e* fore200e)
+{
+    struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev;
+    unsigned int bursts;
+
+    /* gain access to the SBA-200E specific registers  */
+    
+    fore200e->regs.sba.hcr = (u32*)sbus_ioremap(&sbus_dev->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR");
+    fore200e->regs.sba.bsr = (u32*)sbus_ioremap(&sbus_dev->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR");
+    fore200e->regs.sba.isr = (u32*)sbus_ioremap(&sbus_dev->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR");
+    fore200e->virt_base    = (u32*)sbus_ioremap(&sbus_dev->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM");
+
+    if (fore200e->virt_base == NULL) {
+	printk(FORE200E "unable to map RAM of device %s\n", fore200e->name);
+	return -EFAULT;
+    }
+
+    DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
+    
+    fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */
+
+    /* get the supported DVMA burst sizes */
+    bursts = prom_getintdefault(sbus_dev->bus->prom_node, "burst-sizes", 0x00);
+
+    if (sbus_can_dma_64bit(sbus_dev))
+	sbus_set_sbus64(sbus_dev, bursts);
+
+#if 0
+    if (bursts & DMA_BURST16)
+	fore200e->bus->write(SBA200E_BSR_BURST16, fore200e->regs.sba.bsr);
+    else
+    if (bursts & DMA_BURST8)
+       fore200e->bus->write(SBA200E_BSR_BURST8, fore200e->regs.sba.bsr);
+    else
+    if (bursts & DMA_BURST4)
+        fore200e->bus->write(SBA200E_BSR_BURST4, fore200e->regs.sba.bsr);
+#endif
+
+    fore200e->state = FORE200E_STATE_MAP;
+    return 0;
+}
+
+
+static void
+fore200e_sba_unmap(struct fore200e* fore200e)
+{
+    sbus_iounmap((ulong)fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH);
+    sbus_iounmap((ulong)fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH);
+    sbus_iounmap((ulong)fore200e->regs.sba.isr, SBA200E_ISR_LENGTH);
+    sbus_iounmap((ulong)fore200e->virt_base,    SBA200E_RAM_LENGTH);
+}
+
+
+static int __init
+fore200e_sba_configure(struct fore200e* fore200e)
+{
+    fore200e->state = FORE200E_STATE_CONFIGURE;
+    return 0;
+}
+
+
+static struct fore200e* __init
+fore200e_sba_detect(const struct fore200e_bus* bus, int index)
+{
+    struct fore200e*          fore200e;
+    struct sbus_bus* sbus_bus;
+    struct sbus_dev* sbus_dev = NULL;
+    
+    unsigned int     count = 0;
+    
+    for_each_sbus (sbus_bus) {
+	for_each_sbusdev (sbus_dev, sbus_bus) {
+	    if (strcmp(sbus_dev->prom_name, SBA200E_PROM_NAME) == 0) {
+		if (count >= index)
+		    goto found;
+		count++;
+	    }
+	}
+    }
+    return NULL;
+    
+  found:
+#if 1
+    if (sbus_dev->num_registers != 4) {
+	printk(FORE200E "this %s device has %d instead of 4 registers\n",
+	       bus->model_name, sbus_dev->num_registers);
+	return NULL;
+    }
+#endif
+
+    fore200e = fore200e_kmalloc(sizeof(struct fore200e), GFP_KERNEL);
+    if (fore200e == NULL)
+	return NULL;
+
+    fore200e->bus     = bus;
+    fore200e->bus_dev = sbus_dev;
+    fore200e->irq     = sbus_dev->irqs[ 0 ];
+
+    fore200e->phys_base = (unsigned long)sbus_dev;
+
+    sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1);
+    
+    return fore200e;
+}
+
+
+static int __init
+fore200e_sba_prom_read(struct fore200e* fore200e, struct prom_data* prom)
+{
+    struct sbus_dev* sbus_dev = (struct sbus_dev*) fore200e->bus_dev;
+    int                       len;
+
+    len = prom_getproperty(sbus_dev->prom_node, "macaddrlo2", &prom->mac_addr[ 4 ], 4);
+    if (len < 0)
+	return -EBUSY;
+
+    len = prom_getproperty(sbus_dev->prom_node, "macaddrhi4", &prom->mac_addr[ 2 ], 4);
+    if (len < 0)
+	return -EBUSY;
+    
+    prom_getproperty(sbus_dev->prom_node, "serialnumber",
+		     (char*)&prom->serial_number, sizeof(prom->serial_number));
+    
+    prom_getproperty(sbus_dev->prom_node, "promversion",
+		     (char*)&prom->hw_revision, sizeof(prom->hw_revision));
+    
+    return 0;
+}
+
+
+static int
+fore200e_sba_proc_read(struct fore200e* fore200e, char *page)
+{
+    struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev;
+
+    return sprintf(page, "   SBUS slot/device:\t\t%d/'%s'\n", sbus_dev->slot, sbus_dev->prom_name);
+}
+#endif /* CONFIG_ATM_FORE200E_SBA */
+
+
+static void
+fore200e_irq_tx(struct fore200e* fore200e)
+{
+    struct host_txq_entry* entry;
+    int i;
+    
+    entry = fore200e->host_txq.host_entry;
+
+    for (i = 0; i < QUEUE_SIZE_TX; i++) {
+
+	if (*entry->status & STATUS_COMPLETE) {
+
+	    DPRINTK(3, "TX COMPLETED: entry = %p, vcc = %p, skb = %p\n", entry, entry->vcc, entry->skb);
+
+	    /* free copy of misaligned data */
+	    if (entry->data)
+		kfree(entry->data);
+
+	    /* remove DMA mapping */
+	    fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length);
+
+	    /* notify tx completion */
+	    if (entry->vcc->pop)
+		entry->vcc->pop(entry->vcc, entry->skb);
+	    else
+		dev_kfree_skb_irq(entry->skb);
+
+	    /* check error condition */
+	    if (*entry->status & STATUS_ERROR)
+		entry->vcc->stats->tx_err++;
+	    else
+		entry->vcc->stats->tx++;
+
+	    *entry->status = STATUS_FREE;
+	    
+	    fore200e->host_txq.txing--;
+	}
+	entry++;
+    }
+}
+
+
+static void
+fore200e_supply(struct fore200e* fore200e)
+{
+    int  scheme, magn, i;
+
+    struct host_bsq*       bsq;
+    struct host_bsq_entry* entry;
+    struct buffer*         buffer;
+
+    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
+	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
+
+	    bsq = &fore200e->host_bsq[ scheme ][ magn ];
+
+	    if (fore200e_rx_buf_nbr[ scheme ][ magn ] - bsq->count > RBD_BLK_SIZE) {
+
+		DPRINTK(2, "supplying rx buffers to queue %d / %d, count = %d\n",
+			scheme, magn, bsq->count);
+
+		entry = &bsq->host_entry[ bsq->head ];
+		
+		FORE200E_NEXT_ENTRY(bsq->head, QUEUE_SIZE_BS);
+
+		for (i = 0; i < RBD_BLK_SIZE; i++) {
+
+		    buffer = &bsq->buffer[ bsq->free ];
+		    
+		    FORE200E_NEXT_ENTRY(bsq->free, fore200e_rx_buf_nbr[ scheme ][ magn ]);
+		    
+		    entry->rbd_block->rbd[ i ].buffer_haddr = buffer->data.dma_addr;
+		    entry->rbd_block->rbd[ i ].handle       = FORE200E_BUF2HDL(buffer);
+		}
+
+		/* increase the number of supplied rx buffers */
+		bsq->count += RBD_BLK_SIZE;
+		
+		*entry->status = STATUS_PENDING;
+		fore200e->bus->write(entry->rbd_block_dma, &entry->cp_entry->rbd_block_haddr);
+	    }
+	}
+    }
+}
+
+
+
+static struct atm_vcc* 
+fore200e_find_vcc(struct fore200e* fore200e, struct rpd* rpd)
+{
+    struct atm_vcc* vcc;
+
+    for (vcc = fore200e->atm_dev->vccs; vcc; vcc = vcc->next) {
+
+	if (vcc->vpi == rpd->atm_header.vpi && vcc->vci == rpd->atm_header.vci)
+	    break;
+    }
+    
+    return vcc;
+}
+
+
+static void
+fore200e_push_rpd(struct fore200e* fore200e, struct rpd* rpd)
+{
+    struct atm_vcc*      vcc;
+    struct sk_buff*      skb;
+    struct buffer*       buffer;
+    struct fore200e_vcc* fore200e_vcc;
+    int                  i, pdu_len = 0;
+#ifdef FORE200E_52BYTE_AAL0_SDU
+    u32                  cell_header = 0;
+#endif
+
+    vcc = fore200e_find_vcc(fore200e, rpd);
+    if (vcc == NULL) {
+	
+	printk(FORE200E "no vcc found for PDU received on %d.%d.%d\n",
+	       fore200e->atm_dev->number, rpd->atm_header.vpi, rpd->atm_header.vci);
+	return;
+    }
+
+    fore200e_vcc = FORE200E_VCC(vcc);
+
+#ifdef FORE200E_52BYTE_AAL0_SDU
+    if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.rxtp.max_sdu == ATM_AAL0_SDU)) {
+
+	cell_header = (rpd->atm_header.gfc << ATM_HDR_GFC_SHIFT) |
+	              (rpd->atm_header.vpi << ATM_HDR_VPI_SHIFT) |
+                      (rpd->atm_header.vci << ATM_HDR_VCI_SHIFT) |
+                      (rpd->atm_header.plt << ATM_HDR_PTI_SHIFT) | 
+                       rpd->atm_header.clp;
+	pdu_len = 4;
+    }
+#endif
+    
+    /* compute total PDU length */
+    for (i = 0; i < rpd->nseg; i++)
+	pdu_len += rpd->rsd[ i ].length;
+    
+    skb = alloc_skb(pdu_len, GFP_ATOMIC);
+    if (skb == NULL) {
+	
+	printk(FORE200E "unable to alloc new skb, rx PDU length = %d\n", pdu_len);
+	vcc->stats->rx_drop++;
+	return;
+    } 
+
+    skb->stamp = vcc->timestamp = xtime;
+    
+#ifdef FORE200E_52BYTE_AAL0_SDU
+    if (cell_header) {
+	*((u32*)skb_put(skb, 4)) = cell_header;
+    }
+#endif
+
+    /* reassemble segments */
+    for (i = 0; i < rpd->nseg; i++) {
+	
+	/* rebuild rx buffer address from rsd handle */
+	buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
+	
+	/* ensure DMA synchronisation */
+	    fore200e->bus->dma_sync(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length);
+	
+	memcpy(skb_put(skb, rpd->rsd[ i ].length), buffer->data.align_addr, rpd->rsd[ i ].length);
+    }
+    
+    DPRINTK(3, "rx skb: len = %d, truesize = %d\n", skb->len, skb->truesize);
+    
+    if (pdu_len < fore200e_vcc->rx_min_pdu)
+	fore200e_vcc->rx_min_pdu = pdu_len;
+    if (pdu_len > fore200e_vcc->rx_max_pdu)
+	fore200e_vcc->rx_max_pdu = pdu_len;
+
+    /* push PDU */
+    if (atm_charge(vcc, skb->truesize) == 0) {
+
+	DPRINTK(2, "receive buffers saturated for %d.%d.%d - PDU dropped\n",
+		vcc->itf, vcc->vpi, vcc->vci);
+
+	dev_kfree_skb_irq(skb);
+	return;
+    }
+
+    vcc->push(vcc, skb);
+    vcc->stats->rx++;
+}
+
+
+static void
+fore200e_collect_rpd(struct fore200e* fore200e, struct rpd* rpd)
+{
+    struct buffer* buffer;
+    int            i;
+    
+    for (i = 0; i < rpd->nseg; i++) {
+
+	/* rebuild rx buffer address from rsd handle */
+	buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
+
+	/* decrease the number of supplied rx buffers */
+	fore200e->host_bsq[ buffer->scheme ][ buffer->magn ].count--;
+    }
+}
+
+
+static void
+fore200e_irq_rx(struct fore200e* fore200e)
+{
+    struct host_rxq*       rxq = &fore200e->host_rxq;
+    struct host_rxq_entry* entry;
+
+    for (;;) {
+	
+	entry = &rxq->host_entry[ rxq->head ];
+
+	/* no more received PDUs */
+	if ((*entry->status & STATUS_COMPLETE) == 0)
+	    break;
+
+	FORE200E_NEXT_ENTRY(rxq->head, QUEUE_SIZE_RX);
+
+	if ((*entry->status & STATUS_ERROR) == 0) {
+
+	    fore200e_push_rpd(fore200e, entry->rpd);
+	}
+	else {
+	    printk(FORE200E "damaged PDU on %d.%d.%d\n", 
+		   fore200e->atm_dev->number, entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
+	}
+
+	fore200e_collect_rpd(fore200e, entry->rpd);
+
+	fore200e_supply(fore200e);
+
+	/* rewrite the rpd address to ack the received PDU */
+	fore200e->bus->write(entry->rpd_dma, &entry->cp_entry->rpd_haddr);
+	*entry->status = STATUS_FREE;
+    }
+}
+
+
+static void
+fore200e_interrupt(int irq, void* dev, struct pt_regs* regs)
+{
+    struct fore200e* fore200e = FORE200E_DEV((struct atm_dev*)dev);
+
+    if (fore200e->bus->irq_check(fore200e) == 0) {
+	
+	DPRINTK(3, "unexpected interrupt on device %c\n", fore200e->name[9]);
+	return;
+    }
+    DPRINTK(3, "valid interrupt on device %c\n", fore200e->name[9]);
+
+    fore200e_irq_rx(fore200e);
+
+    if (fore200e->host_txq.txing)
+	fore200e_irq_tx(fore200e);
+    
+    fore200e->bus->irq_ack(fore200e);
+}
+
+
+static int
+fore200e_select_scheme(struct atm_vcc* vcc)
+{
+    int scheme;
+
+#if 1
+    /* fairly balance VCs over (identical) buffer schemes */
+    scheme =  vcc->vci % 2 ? BUFFER_SCHEME_ONE : BUFFER_SCHEME_TWO;
+#else
+    /* bit 7 of VPI magically selects the second buffer scheme */
+    if (vcc->vpi & (1<<7)) {
+	vcc->vpi &= ((1<<7) - 1);    /* reset the magic bit */
+	scheme = BUFFER_SCHEME_TWO;
+    }
+    else {
+	scheme = BUFFER_SCHEME_ONE;
+    }
+#endif
+    
+    DPRINTK(1, "vpvc %d.%d.%d uses the %s buffer scheme\n",
+	    vcc->itf, vcc->vpi, vcc->vci, scheme == BUFFER_SCHEME_ONE ? "first" : "second");
+
+    return scheme;
+}
+
+
+
+static int 
+fore200e_activate_vcin(struct fore200e* fore200e, int activate, struct atm_vcc* vcc, int mtu)
+{
+    struct host_cmdq*        cmdq  = &fore200e->host_cmdq;
+    struct host_cmdq_entry*  entry = &cmdq->host_entry[ cmdq->head ];
+    struct activate_opcode   activ_opcode;
+    struct deactivate_opcode deactiv_opcode;
+    struct vpvc              vpvc;
+    int                      ok;
+    enum fore200e_aal        aal = fore200e_atm2fore_aal(vcc->qos.aal);
+
+    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
+    
+    if (activate) {
+	FORE200E_VCC(vcc)->scheme = fore200e_select_scheme(vcc);
+	
+	activ_opcode.opcode = OPCODE_ACTIVATE_VCIN;
+	activ_opcode.aal    = aal;
+	activ_opcode.scheme = FORE200E_VCC(vcc)->scheme;
+	activ_opcode.pad    = 0;
+    }
+    else {
+	deactiv_opcode.opcode = OPCODE_DEACTIVATE_VCIN;
+	deactiv_opcode.pad    = 0;
+    }
+
+    vpvc.vci = vcc->vci;
+    vpvc.vpi = vcc->vpi;
+
+    *entry->status = STATUS_PENDING;
+
+    if (activate) {
+
+#ifdef FORE200E_52BYTE_AAL0_SDU
+	mtu = 48;
+#endif
+	/* the MTU is unused by the cp, except in the case of AAL0 */
+	fore200e->bus->write(mtu,                        &entry->cp_entry->cmd.activate_block.mtu);
+	fore200e->bus->write(*(u32*)&vpvc,         (u32*)&entry->cp_entry->cmd.activate_block.vpvc);
+	fore200e->bus->write(*(u32*)&activ_opcode, (u32*)&entry->cp_entry->cmd.activate_block.opcode);
+    }
+    else {
+	fore200e->bus->write(*(u32*)&vpvc,           (u32*)&entry->cp_entry->cmd.deactivate_block.vpvc);
+	fore200e->bus->write(*(u32*)&deactiv_opcode, (u32*)&entry->cp_entry->cmd.deactivate_block.opcode);
+    }
+
+    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
+
+    *entry->status = STATUS_FREE;
+
+    if (ok == 0) {
+	printk(FORE200E "unable to %s vpvc %d.%d on device %s\n",
+	       activate ? "open" : "close", vcc->vpi, vcc->vci, fore200e->name);
+	return -EIO;
+    }
+
+    DPRINTK(1, "vpvc %d.%d %sed on device %s\n", vcc->vpi, vcc->vci, 
+	    activate ? "open" : "clos", fore200e->name);
+
+    return 0;
+}
+
+
+static int
+fore200e_walk_vccs(struct atm_vcc *vcc, short *vpi, int *vci)
+{
+    struct atm_vcc* walk;
+
+    /* find a free VPI */
+    if (*vpi == ATM_VPI_ANY) {
+
+	for (*vpi = 0, walk = vcc->dev->vccs; walk; walk = walk->next) {
+
+	    if ((walk->vci == *vci) && (walk->vpi == *vpi)) {
+		(*vpi)++;
+		walk = vcc->dev->vccs;
+	    }
+	}
+    }
+
+    /* find a free VCI */
+    if (*vci == ATM_VCI_ANY) {
+	
+	for (*vci = ATM_NOT_RSV_VCI, walk = vcc->dev->vccs; walk; walk = walk->next) {
+
+	    if ((walk->vpi = *vpi) && (walk->vci == *vci)) {
+		*vci = walk->vci + 1;
+		walk = vcc->dev->vccs;
+	    }
+	}
+    }
+
+    return 0;
+}
+
+
+#define FORE200E_MAX_BACK2BACK_CELLS 255    /* XXX depends on CDVT */
+
+static void
+fore200e_rate_ctrl(struct atm_qos* qos, struct tpd_rate* rate)
+{
+    if (qos->txtp.max_pcr < ATM_OC3_PCR) {
+    
+	/* compute the data cells to idle cells ratio from the PCR */
+	rate->data_cells = qos->txtp.max_pcr * FORE200E_MAX_BACK2BACK_CELLS / ATM_OC3_PCR;
+	rate->idle_cells = FORE200E_MAX_BACK2BACK_CELLS - rate->data_cells;
+    }
+    else {
+	/* disable rate control */
+	rate->data_cells = rate->idle_cells = 0;
+    }
+}
+
+
+static int
+fore200e_open(struct atm_vcc *vcc, short vpi, int vci)
+{
+    struct fore200e*     fore200e = FORE200E_DEV(vcc->dev);
+    struct fore200e_vcc* fore200e_vcc;
+    
+    /* find a free VPI/VCI */
+    fore200e_walk_vccs(vcc, &vpi, &vci);
+
+    vcc->vpi = vpi;
+    vcc->vci = vci;
+
+    /* ressource checking only? */
+    if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
+	return 0;
+
+    vcc->flags |= ATM_VF_ADDR;
+    vcc->itf    = vcc->dev->number;
+
+    DPRINTK(2, "opening %d.%d.%d:%d QoS = (tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
+	    "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d)\n",
+	    vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
+	    fore200e_traffic_class[ vcc->qos.txtp.traffic_class ],
+	    vcc->qos.txtp.min_pcr, vcc->qos.txtp.max_pcr, vcc->qos.txtp.max_cdv, vcc->qos.txtp.max_sdu,
+	    fore200e_traffic_class[ vcc->qos.rxtp.traffic_class ],
+	    vcc->qos.rxtp.min_pcr, vcc->qos.rxtp.max_pcr, vcc->qos.rxtp.max_cdv, vcc->qos.rxtp.max_sdu);
+    
+    if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
+	
+	down(&fore200e->rate_sf);
+	if (fore200e->available_cell_rate < vcc->qos.txtp.max_pcr) {
+	    up(&fore200e->rate_sf);
+	    return -EAGAIN;
+	}
+	/* reserving the pseudo-CBR bandwidth at this point grants us
+	   to reduce the length of the critical section protected
+	   by 'rate_sf'. in counterpart, we have to reset the available
+	   bandwidth if we later encounter an error */
+
+	fore200e->available_cell_rate -= vcc->qos.txtp.max_pcr;
+	up(&fore200e->rate_sf);
+    }
+    
+    fore200e_vcc = fore200e_kmalloc(sizeof(struct fore200e_vcc), GFP_KERNEL);
+    if (fore200e_vcc == NULL) {
+	down(&fore200e->rate_sf);
+	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
+	up(&fore200e->rate_sf);
+	return -ENOMEM;
+    }
+
+    FORE200E_VCC(vcc) = fore200e_vcc;
+    
+    if (fore200e_activate_vcin(fore200e, 1, vcc, vcc->qos.rxtp.max_sdu) < 0) {
+	kfree(fore200e_vcc);
+	down(&fore200e->rate_sf);
+	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
+	up(&fore200e->rate_sf);
+	return -EBUSY;
+    }
+    
+#ifdef MODULE
+    MOD_INC_USE_COUNT;
+#endif
+
+    /* compute rate control parameters */
+    if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
+	
+	fore200e_rate_ctrl(&vcc->qos, &fore200e_vcc->rate);
+
+	DPRINTK(3, "tx on %d.%d.%d:%d, tx PCR = %d, rx PCR = %d, data_cells = %u, idle_cells = %u\n",
+		vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
+		vcc->qos.txtp.max_pcr, vcc->qos.rxtp.max_pcr, 
+		fore200e_vcc->rate.data_cells, fore200e_vcc->rate.idle_cells);
+    }
+    
+    fore200e_vcc->tx_min_pdu = fore200e_vcc->rx_min_pdu = 65536;
+    fore200e_vcc->tx_max_pdu = fore200e_vcc->rx_max_pdu = 0;
+    
+    vcc->flags |= ATM_VF_READY;
+    return 0;
+}
+
+
+
+static void
+fore200e_close(struct atm_vcc* vcc)
+{
+    struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
+    
+    DPRINTK(2, "closing %d.%d.%d:%d\n", vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal));
+    
+    fore200e_activate_vcin(fore200e, 0, vcc, 0);
+    
+#ifdef MODULE
+    MOD_DEC_USE_COUNT;
+#endif
+	
+    kfree(FORE200E_VCC(vcc));
+	
+    if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
+	down(&fore200e->rate_sf);
+	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
+	up(&fore200e->rate_sf);
+    }
+}
+
+
+#if 0
+#define FORE200E_SYNC_SEND    /* wait tx completion before returning */
+#endif
+
+
+static int
+fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+    struct fore200e*       fore200e     = FORE200E_DEV(vcc->dev);
+    struct fore200e_vcc*   fore200e_vcc = FORE200E_VCC(vcc);
+    struct host_txq*       txq          = &fore200e->host_txq;
+    struct host_txq_entry* entry;
+    struct tpd*            tpd;
+    struct tpd_haddr       tpd_haddr;
+    unsigned long          flags;
+    int                    retry        = CONFIG_ATM_FORE200E_TX_RETRY;
+    int                    tx_copy      = 0;
+    int                    tx_len       = skb->len;
+    u32*                   cell_header  = NULL;
+    unsigned char*         skb_data;
+    int                    skb_len;
+
+#ifdef FORE200E_52BYTE_AAL0_SDU
+    if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.txtp.max_sdu == ATM_AAL0_SDU)) {
+	cell_header = (u32*) skb->data;
+	skb_data    = skb->data + 4;    /* skip 4-byte cell header */
+	skb_len     = tx_len = skb->len  - 4;
+
+	DPRINTK(3, "skipping user-supplied cell header 0x%08x", *cell_header);
+    }
+    else 
+#endif
+    {
+	skb_data = skb->data;
+	skb_len  = skb->len;
+    }
+    
+  retry_here:
+    
+    spin_lock_irqsave(&fore200e->tx_lock, flags);
+
+    entry = &txq->host_entry[ txq->head ];
+    
+    if (*entry->status != STATUS_FREE) {
+	
+	/* try to free completed tx queue entries */
+	fore200e_irq_tx(fore200e);
+	
+	if (*entry->status != STATUS_FREE) {
+	    
+	    spin_unlock_irqrestore(&fore200e->tx_lock, flags);
+
+	    /* retry once again? */
+	    if(--retry > 0)
+		goto retry_here;
+	    
+	    vcc->stats->tx_err++;
+	    
+	    printk(FORE200E "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
+		   fore200e->name, fore200e->cp_queues->heartbeat);
+	    
+	    return -EIO;
+	}
+    }
+
+    tpd = entry->tpd;
+
+    if (((unsigned long)skb_data) & 0x3) {
+
+	DPRINTK(2, "misaligned tx PDU on device %s\n", fore200e->name);
+	tx_copy = 1;
+	tx_len  = skb_len;
+    }
+
+    if ((vcc->qos.aal == ATM_AAL0) && (skb_len % ATM_CELL_PAYLOAD)) {
+
+	/* this simply NUKES the PCA-200E board */
+	DPRINTK(2, "incomplete tx AAL0 PDU on device %s\n", fore200e->name);
+	tx_copy = 1;
+	tx_len  = ((skb_len / ATM_CELL_PAYLOAD) + 1) * ATM_CELL_PAYLOAD;
+    }
+    
+    if (tx_copy) {
+	
+	entry->data = kmalloc(tx_len, GFP_ATOMIC | GFP_DMA);
+	if (entry->data == NULL) {
+	    
+	    spin_unlock_irqrestore(&fore200e->tx_lock, flags);
+	    return -ENOMEM;
+	}
+
+	memcpy(entry->data, skb_data, skb_len);
+	if (skb_len < tx_len)
+	    memset(entry->data + skb_len, 0x00, tx_len - skb_len);
+	
+	tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, entry->data, tx_len);
+    }
+    else {
+	entry->data = NULL;
+	tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, skb_data, tx_len);
+    }
+
+    tpd->tsd[ 0 ].length = tx_len;
+
+    FORE200E_NEXT_ENTRY(txq->head, QUEUE_SIZE_TX);
+    txq->txing++;
+
+    spin_unlock_irqrestore(&fore200e->tx_lock, flags);
+    
+    /* ensure DMA synchronisation */
+	fore200e->bus->dma_sync(fore200e, tpd->tsd[ 0 ].buffer, tpd->tsd[ 0 ].length);
+    
+    DPRINTK(3, "tx on %d.%d.%d:%d, len = %u (%u)\n", 
+	    vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
+	    tpd->tsd[0].length, skb_len);
+
+    if (skb_len < fore200e_vcc->tx_min_pdu)
+	fore200e_vcc->tx_min_pdu = skb_len;
+    if (skb_len > fore200e_vcc->tx_max_pdu)
+	fore200e_vcc->tx_max_pdu = skb_len;
+    
+    entry->vcc = vcc;
+    entry->skb = skb;
+
+    /* set tx rate control information */
+    tpd->rate.data_cells = fore200e_vcc->rate.data_cells;
+    tpd->rate.idle_cells = fore200e_vcc->rate.idle_cells;
+
+    if (cell_header) {
+	tpd->atm_header.clp = (*cell_header & ATM_HDR_CLP);
+	tpd->atm_header.plt = (*cell_header & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT;
+	tpd->atm_header.vci = (*cell_header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;
+	tpd->atm_header.vpi = (*cell_header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;
+	tpd->atm_header.gfc = (*cell_header & ATM_HDR_GFC_MASK) >> ATM_HDR_GFC_SHIFT;
+    }
+    else {
+	/* set the ATM header, common to all cells conveying the PDU */
+	tpd->atm_header.clp = 0;
+	tpd->atm_header.plt = 0;
+	tpd->atm_header.vci = vcc->vci;
+	tpd->atm_header.vpi = vcc->vpi;
+	tpd->atm_header.gfc = 0;
+    }
+
+    tpd->spec.length = tx_len;
+    tpd->spec.nseg   = 1;
+    tpd->spec.aal    = fore200e_atm2fore_aal(vcc->qos.aal);
+#ifdef FORE200E_SYNC_SEND
+    tpd->spec.intr   = 0;
+#else
+    tpd->spec.intr   = 1;
+#endif
+
+    tpd_haddr.size  = sizeof(struct tpd) / 32;    /* size is expressed in 32 byte blocks */
+    tpd_haddr.pad   = 0;
+    tpd_haddr.haddr = entry->tpd_dma >> 5;        /* shift the address, as we are in a bitfield */
+
+    *entry->status = STATUS_PENDING;
+    fore200e->bus->write(*(u32*)&tpd_haddr, (u32*)&entry->cp_entry->tpd_haddr);
+
+
+#ifdef FORE200E_SYNC_SEND
+    {
+	int ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 10);
+
+	fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length);
+	
+	if (ok == 0) {
+	    printk(FORE200E "synchronous tx on %d:%d:%d failed\n", vcc->itf, vcc->vpi, vcc->vci);
+
+	    entry->vcc->stats->tx_err++;
+	    return -EIO;
+	}
+	entry->vcc->stats->tx++;
+
+	DPRINTK(3, "synchronous tx on %d:%d:%d succeeded\n", vcc->itf, vcc->vpi, vcc->vci);
+
+	/* free tmp copy of misaligned data */
+	if (entry->data)
+	    kfree(entry->data);
+	
+	/* notify tx completion */
+	if (vcc->pop)
+	    vcc->pop(vcc, skb);
+	else
+	    dev_kfree_skb(skb);
+    }
+#endif
+
+    return 0;
+}
+
+
+static int
+fore200e_getstats(struct fore200e* fore200e)
+{
+    struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
+    struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
+    struct stats_opcode     opcode;
+    int                     ok;
+    u32                     stats_dma_addr;
+
+    if (fore200e->stats == NULL) {
+	fore200e->stats = fore200e_kmalloc(sizeof(struct stats), GFP_KERNEL | GFP_DMA);
+	if (fore200e->stats == NULL)
+	    return -ENOMEM;
+    }
+    
+    stats_dma_addr = fore200e->bus->dma_map(fore200e, fore200e->stats, sizeof(struct stats));
+    
+    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
+
+    opcode.opcode = OPCODE_GET_STATS;
+    opcode.pad    = 0;
+
+    fore200e->bus->write(stats_dma_addr, &entry->cp_entry->cmd.stats_block.stats_haddr);
+    
+    *entry->status = STATUS_PENDING;
+
+    fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.stats_block.opcode);
+
+    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
+
+    *entry->status = STATUS_FREE;
+
+    fore200e->bus->dma_unmap(fore200e, stats_dma_addr, sizeof(struct stats));
+    
+    if (ok == 0) {
+	printk(FORE200E "unable to get statistics from device %s\n", fore200e->name);
+	return -EIO;
+    }
+
+    return 0;
+}
+
+
+static int
+fore200e_getsockopt (struct atm_vcc* vcc, int level, int optname, void* optval, int optlen)
+{
+    // struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
+
+    DPRINTK(2, "getsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
+	    vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
+
+    return -EINVAL;
+}
+
+
+static int
+fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void* optval, int optlen)
+{
+    // struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
+    
+    DPRINTK(2, "setsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
+	    vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
+    
+    return -EINVAL;
+}
+
+
+#if 0 /* currently unused */
+static int
+fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs)
+{
+    struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
+    struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
+    struct oc3_opcode       opcode;
+    int                     ok;
+    u32                     oc3_regs_dma_addr;
+
+    oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs));
+
+    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
+
+    opcode.opcode = OPCODE_GET_OC3;
+    opcode.reg    = 0;
+    opcode.value  = 0;
+    opcode.mask   = 0;
+
+    fore200e->bus->write(oc3_regs_dma_addr, &entry->cp_entry->cmd.oc3_block.regs_haddr);
+    
+    *entry->status = STATUS_PENDING;
+
+    fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.oc3_block.opcode);
+
+    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
+
+    *entry->status = STATUS_FREE;
+
+    fore200e->bus_dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs));
+    
+    if (ok == 0) {
+	printk(FORE200E "unable to get OC-3 regs of device %s\n", fore200e->name);
+	return -EIO;
+    }
+
+    return 0;
+}
+#endif
+
+
+static int
+fore200e_set_oc3(struct fore200e* fore200e, u32 reg, u32 value, u32 mask)
+{
+    struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
+    struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
+    struct oc3_opcode       opcode;
+    int                     ok;
+
+    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
+
+    opcode.opcode = OPCODE_SET_OC3;
+    opcode.reg    = reg;
+    opcode.value  = value;
+    opcode.mask   = mask;
+
+    fore200e->bus->write(0, &entry->cp_entry->cmd.oc3_block.regs_haddr);
+    
+    *entry->status = STATUS_PENDING;
+
+    fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.oc3_block.opcode);
+
+    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
+
+    *entry->status = STATUS_FREE;
+
+    if (ok == 0) {
+	printk(FORE200E "unable to set OC-3 reg 0x%02x of device %s\n", reg, fore200e->name);
+	return -EIO;
+    }
+
+    return 0;
+}
+
+
+static int
+fore200e_setloop(struct fore200e* fore200e, int loop_mode)
+{
+    u32 mct_value, mct_mask;
+    int error;
+
+    if (!capable(CAP_NET_ADMIN))
+	return -EPERM;
+    
+    switch (loop_mode) {
+
+    case SUNI_LM_NONE:
+	mct_value = 0; 
+	mct_mask  = SUNI_MCT_DLE | SUNI_MCT_LLE;
+	break;
+	
+    case SUNI_LM_DIAG:
+	mct_value = mct_mask = SUNI_MCT_DLE;
+	break;
+
+    case SUNI_LM_LOOP:
+	mct_value = mct_mask = SUNI_MCT_LLE;
+	break;
+
+    default:
+	return -EINVAL;
+    }
+
+    error = fore200e_set_oc3(fore200e, SUNI_MCT, mct_value, mct_mask);
+    if ( error == 0)
+	fore200e->loop_mode = loop_mode;
+
+    return error;
+}
+
+
+static inline unsigned int
+fore200e_swap(unsigned int in)
+{
+#if defined(__LITTLE_ENDIAN)
+    return swab32(in);
+#else
+    return in;
+#endif
+}
+
+
+static int
+fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats* arg)
+{
+    struct sonet_stats tmp;
+
+    if (fore200e_getstats(fore200e) < 0)
+	return -EIO;
+
+    tmp.section_bip = fore200e_swap(fore200e->stats->oc3.section_bip8_errors);
+    tmp.line_bip    = fore200e_swap(fore200e->stats->oc3.line_bip24_errors);
+    tmp.path_bip    = fore200e_swap(fore200e->stats->oc3.path_bip8_errors);
+    tmp.line_febe   = fore200e_swap(fore200e->stats->oc3.line_febe_errors);
+    tmp.path_febe   = fore200e_swap(fore200e->stats->oc3.path_febe_errors);
+    tmp.corr_hcs    = fore200e_swap(fore200e->stats->oc3.corr_hcs_errors);
+    tmp.uncorr_hcs  = fore200e_swap(fore200e->stats->oc3.ucorr_hcs_errors);
+    tmp.tx_cells    = fore200e_swap(fore200e->stats->aal0.cells_transmitted)  +
+	              fore200e_swap(fore200e->stats->aal34.cells_transmitted) +
+	              fore200e_swap(fore200e->stats->aal5.cells_transmitted);
+    tmp.rx_cells    = fore200e_swap(fore200e->stats->aal0.cells_received)     +
+	              fore200e_swap(fore200e->stats->aal34.cells_received)    +
+	              fore200e_swap(fore200e->stats->aal5.cells_received);
+
+    if (arg)
+	return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0;	
+    
+    return 0;
+}
+
+
+static int
+fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void* arg)
+{
+    struct fore200e* fore200e = FORE200E_DEV(dev);
+    
+    DPRINTK(2, "ioctl cmd = 0x%x (%u), arg = 0x%p (%lu)\n", cmd, cmd, arg, (unsigned long)arg);
+
+    switch (cmd) {
+
+    case SONET_GETSTAT:
+	return fore200e_fetch_stats(fore200e, (struct sonet_stats*)arg);
+
+    case SONET_GETDIAG:
+	return put_user(0, (int*)arg) ? -EFAULT : 0;
+	
+    case SUNI_SETLOOP:
+	return fore200e_setloop(fore200e, (int)(unsigned long)arg);
+
+    case SUNI_GETLOOP:
+	return put_user(fore200e->loop_mode, (int*)arg) ? -EFAULT : 0;
+    }
+
+    return -ENOSYS; /* not implemented */
+}
+
+
+static int
+fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags)
+{
+    struct fore200e_vcc* fore200e_vcc = FORE200E_VCC(vcc);
+    struct fore200e*     fore200e     = FORE200E_DEV(vcc->dev);
+
+    DPRINTK(2, "change_qos %d.%d.%d, "
+	    "(tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
+	    "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d), flags = 0x%x\n"
+	    "available_cell_rate = %u",
+	    vcc->itf, vcc->vpi, vcc->vci,
+	    fore200e_traffic_class[ qos->txtp.traffic_class ],
+	    qos->txtp.min_pcr, qos->txtp.max_pcr, qos->txtp.max_cdv, qos->txtp.max_sdu,
+	    fore200e_traffic_class[ qos->rxtp.traffic_class ],
+	    qos->rxtp.min_pcr, qos->rxtp.max_pcr, qos->rxtp.max_cdv, qos->rxtp.max_sdu,
+	    flags, fore200e->available_cell_rate);
+
+    if ((qos->txtp.traffic_class == ATM_CBR) && (qos->txtp.max_pcr > 0)) {
+
+	down(&fore200e->rate_sf);
+	if (fore200e->available_cell_rate + vcc->qos.txtp.max_pcr < qos->txtp.max_pcr) {
+	    up(&fore200e->rate_sf);
+	    return -EAGAIN;
+	}
+
+	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
+	fore200e->available_cell_rate -= qos->txtp.max_pcr;
+	up(&fore200e->rate_sf);
+	
+	memcpy(&vcc->qos, qos, sizeof(struct atm_qos));
+	
+	/* update rate control parameters */
+	fore200e_rate_ctrl(qos, &fore200e_vcc->rate);
+
+	vcc->flags |= ATM_VF_HASQOS;
+	return 0;
+    }
+    
+    return -EINVAL;
+}
+    
+
+static int __init
+fore200e_irq_request(struct fore200e* fore200e)
+{
+    if (request_irq(fore200e->irq, fore200e_interrupt, SA_SHIRQ, fore200e->name, fore200e->atm_dev) < 0) {
+
+	printk(FORE200E "unable to reserve IRQ %s for device %s\n",
+	       fore200e_irq_itoa(fore200e->irq), fore200e->name);
+	return -EBUSY;
+    }
+
+    printk(FORE200E "IRQ %s reserved for device %s\n",
+	   fore200e_irq_itoa(fore200e->irq), fore200e->name);
+
+    fore200e->state = FORE200E_STATE_IRQ;
+    return 0;
+}
+
+
+static int __init
+fore200e_get_esi(struct fore200e* fore200e)
+{
+    struct prom_data* prom = fore200e_kmalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA);
+    int ok, i;
+
+    ok = fore200e->bus->prom_read(fore200e, prom);
+    if (ok < 0)
+	return -EBUSY;
+	
+    printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %02x:%02x:%02x:%02x:%02x:%02x\n", 
+	   fore200e->name, 
+	   (prom->hw_revision & 0xFF) + '@',    /* probably meaningless with SBA boards */
+	   prom->serial_number & 0xFFFF,
+	   prom->mac_addr[ 2 ], prom->mac_addr[ 3 ], prom->mac_addr[ 4 ],
+	   prom->mac_addr[ 5 ], prom->mac_addr[ 6 ], prom->mac_addr[ 7 ]);
+	
+    for (i = 0; i < ESI_LEN; i++) {
+	fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ];
+    }
+    
+    fore200e_kfree(prom);
+
+    return 0;
+}
+
+
+static int __init
+fore200e_alloc_rx_buf(struct fore200e* fore200e)
+{
+    int scheme, magn, nbr, size, i;
+
+    struct host_bsq* bsq;
+    struct buffer*   buffer;
+
+    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
+	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
+
+	    bsq = &fore200e->host_bsq[ scheme ][ magn ];
+
+	    nbr  = fore200e_rx_buf_nbr[ scheme ][ magn ];
+	    size = fore200e_rx_buf_size[ scheme ][ magn ];
+
+	    DPRINTK(2, "rx buffers %d / %d are being allocated\n", scheme, magn);
+
+	    /* allocate the array of receive buffers */
+	    buffer = bsq->buffer = fore200e_kmalloc(nbr * sizeof(struct buffer), GFP_KERNEL);
+
+	    if (buffer == NULL)
+		return -ENOMEM;
+
+	    for (i = 0; i < nbr; i++) {
+
+		buffer[ i ].scheme = scheme;
+		buffer[ i ].magn   = magn;
+
+		/* allocate the receive buffer body */
+		if (fore200e_chunk_alloc(fore200e,
+					 &buffer[ i ].data, size, fore200e->bus->buffer_alignment) < 0) {
+		    
+		    while (i > 0)
+			fore200e_chunk_free(fore200e, &buffer[ --i ].data);
+		    fore200e_kfree(buffer);
+		    
+		    return -ENOMEM;
+		}
+	    }
+	    /* set next free buffer index */
+	    bsq->free = 0;
+	}
+    }
+
+    fore200e->state = FORE200E_STATE_ALLOC_BUF;
+    return 0;
+}
+
+
+static int __init
+fore200e_init_bs_queue(struct fore200e* fore200e)
+{
+    int scheme, magn, i;
+
+    struct host_bsq*     bsq;
+    struct cp_bsq_entry* cp_entry;
+
+    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
+	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
+
+	    DPRINTK(2, "buffer supply queue %d / %d is being initialized\n", scheme, magn);
+
+	    bsq = &fore200e->host_bsq[ scheme ][ magn ];
+
+	    /* allocate and align the array of status words */
+	    if (fore200e->bus->dma_chunk_alloc(fore200e,
+					       &bsq->status,
+					       sizeof(enum status), 
+					       QUEUE_SIZE_BS,
+					       fore200e->bus->status_alignment) < 0) {
+		return -ENOMEM;
+	    }
+
+	    /* allocate and align the array of receive buffer descriptors */
+	    if (fore200e->bus->dma_chunk_alloc(fore200e,
+					       &bsq->rbd_block,
+					       sizeof(struct rbd_block),
+					       QUEUE_SIZE_BS,
+					       fore200e->bus->descr_alignment) < 0) {
+		
+		fore200e->bus->dma_chunk_free(fore200e, &bsq->status);
+		return -ENOMEM;
+	    }
+	    
+	    /* get the base address of the cp resident buffer supply queue entries */
+	    cp_entry = (struct cp_bsq_entry*)(fore200e->virt_base + 
+		       fore200e->bus->read(&fore200e->cp_queues->cp_bsq[ scheme ][ magn ]));
+	    
+	    /* fill the host resident and cp resident buffer supply queue entries */
+	    for (i = 0; i < QUEUE_SIZE_BS; i++) {
+		
+		bsq->host_entry[ i ].status = 
+		                     FORE200E_INDEX(bsq->status.align_addr, enum status, i);
+	        bsq->host_entry[ i ].rbd_block =
+		                     FORE200E_INDEX(bsq->rbd_block.align_addr, struct rbd_block, i);
+		bsq->host_entry[ i ].rbd_block_dma =
+		                     FORE200E_DMA_INDEX(bsq->rbd_block.dma_addr, struct rbd_block, i);
+		bsq->host_entry[ i ].cp_entry      = &cp_entry[ i ];
+		
+		*bsq->host_entry[ i ].status   = STATUS_FREE;
+		
+		fore200e->bus->write(FORE200E_DMA_INDEX(bsq->status.dma_addr, enum status, i), 
+				     &cp_entry[ i ].status_haddr);
+	    }
+	}
+    }
+
+    fore200e->state = FORE200E_STATE_INIT_BSQ;
+    return 0;
+}
+
+
+static int __init
+fore200e_init_rx_queue(struct fore200e* fore200e)
+{
+    struct host_rxq*     rxq =  &fore200e->host_rxq;
+    struct cp_rxq_entry* cp_entry;
+    int i;
+
+    DPRINTK(2, "receive queue is being initialized\n");
+
+    /* allocate and align the array of status words */
+    if (fore200e->bus->dma_chunk_alloc(fore200e,
+				       &rxq->status,
+				       sizeof(enum status), 
+				       QUEUE_SIZE_RX,
+				       fore200e->bus->status_alignment) < 0) {
+	return -ENOMEM;
+    }
+
+    /* allocate and align the array of receive PDU descriptors */
+    if (fore200e->bus->dma_chunk_alloc(fore200e,
+				       &rxq->rpd,
+				       sizeof(struct rpd), 
+				       QUEUE_SIZE_RX,
+				       fore200e->bus->descr_alignment) < 0) {
+	
+	fore200e->bus->dma_chunk_free(fore200e, &rxq->status);
+	return -ENOMEM;
+    }
+
+    /* get the base address of the cp resident rx queue entries */
+    cp_entry = (struct cp_rxq_entry*)(fore200e->virt_base + 
+				      fore200e->bus->read(&fore200e->cp_queues->cp_rxq));
+
+    /* fill the host resident and cp resident rx entries */
+    for (i=0; i < QUEUE_SIZE_RX; i++) {
+	
+	rxq->host_entry[ i ].status = 
+	                     FORE200E_INDEX(rxq->status.align_addr, enum status, i);
+	rxq->host_entry[ i ].rpd = 
+	                     FORE200E_INDEX(rxq->rpd.align_addr, struct rpd, i);
+	rxq->host_entry[ i ].rpd_dma = 
+	                     FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i);
+	rxq->host_entry[ i ].cp_entry = &cp_entry[ i ];
+
+	*rxq->host_entry[ i ].status = STATUS_FREE;
+
+	fore200e->bus->write(FORE200E_DMA_INDEX(rxq->status.dma_addr, enum status, i), 
+			     &cp_entry[ i ].status_haddr);
+
+	fore200e->bus->write(FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i),
+			     &cp_entry[ i ].rpd_haddr);
+    }
+
+    /* set the head entry of the queue */
+    rxq->head = 0;
+
+    fore200e->state = FORE200E_STATE_INIT_RXQ;
+    return 0;
+}
+
+
+static int __init
+fore200e_init_tx_queue(struct fore200e* fore200e)
+{
+    struct host_txq*     txq =  &fore200e->host_txq;
+    struct cp_txq_entry* cp_entry;
+    int i;
+
+    DPRINTK(2, "transmit queue is being initialized\n");
+
+    /* allocate and align the array of status words */
+    if (fore200e->bus->dma_chunk_alloc(fore200e,
+				       &txq->status,
+				       sizeof(enum status), 
+				       QUEUE_SIZE_TX,
+				       fore200e->bus->status_alignment) < 0) {
+	return -ENOMEM;
+    }
+
+    /* allocate and align the array of transmit PDU descriptors */
+    if (fore200e->bus->dma_chunk_alloc(fore200e,
+				       &txq->tpd,
+				       sizeof(struct tpd), 
+				       QUEUE_SIZE_TX,
+				       fore200e->bus->descr_alignment) < 0) {
+	
+	fore200e->bus->dma_chunk_free(fore200e, &txq->status);
+	return -ENOMEM;
+    }
+
+    /* get the base address of the cp resident tx queue entries */
+    cp_entry = (struct cp_txq_entry*)(fore200e->virt_base + 
+				      fore200e->bus->read(&fore200e->cp_queues->cp_txq));
+
+    /* fill the host resident and cp resident tx entries */
+    for (i=0; i < QUEUE_SIZE_TX; i++) {
+	
+	txq->host_entry[ i ].status = 
+	                     FORE200E_INDEX(txq->status.align_addr, enum status, i);
+	txq->host_entry[ i ].tpd = 
+	                     FORE200E_INDEX(txq->tpd.align_addr, struct tpd, i);
+	txq->host_entry[ i ].tpd_dma  = 
+                             FORE200E_DMA_INDEX(txq->tpd.dma_addr, struct tpd, i);
+	txq->host_entry[ i ].cp_entry = &cp_entry[ i ];
+
+	*txq->host_entry[ i ].status = STATUS_FREE;
+	
+	fore200e->bus->write(FORE200E_DMA_INDEX(txq->status.dma_addr, enum status, i), 
+			     &cp_entry[ i ].status_haddr);
+	
+        /* although there is a one-to-one mapping of tx queue entries and tpds,
+	   we do not write here the DMA (physical) base address of each tpd into
+	   the related cp resident entry, because the cp relies on this write
+	   operation to detect that a new pdu has been submitted for tx */
+}
+
+    /* set the head entry of the queue */
+    txq->head = 0;
+
+    fore200e->state = FORE200E_STATE_INIT_TXQ;
+    return 0;
+}
+
+
+static int __init
+fore200e_init_cmd_queue(struct fore200e* fore200e)
+{
+    struct host_cmdq*     cmdq =  &fore200e->host_cmdq;
+    struct cp_cmdq_entry* cp_entry;
+    int i;
+
+    DPRINTK(2, "command queue is being initialized\n");
+
+    /* allocate and align the array of status words */
+    if (fore200e->bus->dma_chunk_alloc(fore200e,
+				       &cmdq->status,
+				 sizeof(enum status), 
+				 QUEUE_SIZE_CMD,
+				 fore200e->bus->status_alignment) < 0) {
+	return -ENOMEM;
+    }
+    
+    /* get the base address of the cp resident cmd queue entries */
+    cp_entry = (struct cp_cmdq_entry*)(fore200e->virt_base + 
+				       fore200e->bus->read(&fore200e->cp_queues->cp_cmdq));
+
+    /* fill the host resident and cp resident cmd entries */
+    for (i=0; i < QUEUE_SIZE_CMD; i++) {
+	
+	cmdq->host_entry[ i ].status   = 
+                              FORE200E_INDEX(cmdq->status.align_addr, enum status, i);
+	cmdq->host_entry[ i ].cp_entry = &cp_entry[ i ];
+
+	*cmdq->host_entry[ i ].status = STATUS_FREE;
+
+	fore200e->bus->write(FORE200E_DMA_INDEX(cmdq->status.dma_addr, enum status, i), 
+                             &cp_entry[ i ].status_haddr);
+    }
+
+    /* set the head entry of the queue */
+    cmdq->head = 0;
+
+    fore200e->state = FORE200E_STATE_INIT_CMDQ;
+    return 0;
+}
+
+
+static void __init
+fore200e_param_bs_queue(struct fore200e* fore200e,
+			enum buffer_scheme scheme, enum buffer_magn magn,
+			int queue_length, int pool_size, int supply_blksize)
+{
+    struct bs_spec* bs_spec = &fore200e->cp_queues->init.bs_spec[ scheme ][ magn ];
+
+    /* dumb value; the firmware doesn't allow us to activate a VC while
+       selecting a buffer scheme with zero-sized rbd pools */
+
+    if (pool_size == 0)
+	pool_size = 64;
+
+    fore200e->bus->write(queue_length,                           &bs_spec->queue_length);
+    fore200e->bus->write(fore200e_rx_buf_size[ scheme ][ magn ], &bs_spec->buffer_size);
+    fore200e->bus->write(pool_size,                              &bs_spec->pool_size);
+    fore200e->bus->write(supply_blksize,                         &bs_spec->supply_blksize);
+}
+
+
+static int __init
+fore200e_initialize(struct fore200e* fore200e)
+{
+    struct cp_queues* cpq;
+    int               ok, scheme, magn;
+
+    DPRINTK(2, "device %s being initialized\n", fore200e->name);
+
+    spin_lock_init(&fore200e->tx_lock);
+    init_MUTEX(&fore200e->rate_sf);
+    
+    cpq = fore200e->cp_queues = (struct cp_queues*) (fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET);
+
+    /* enable cp to host interrupts */
+    fore200e->bus->write(1, &cpq->imask);
+
+    if (fore200e->bus->irq_enable)
+	fore200e->bus->irq_enable(fore200e);
+    
+    fore200e->bus->write(NBR_CONNECT, &cpq->init.num_connect);
+
+    fore200e->bus->write(QUEUE_SIZE_CMD, &cpq->init.cmd_queue_len);
+    fore200e->bus->write(QUEUE_SIZE_RX,  &cpq->init.rx_queue_len);
+    fore200e->bus->write(QUEUE_SIZE_TX,  &cpq->init.tx_queue_len);
+
+    fore200e->bus->write(RSD_EXTENSION,  &cpq->init.rsd_extension);
+    fore200e->bus->write(TSD_EXTENSION,  &cpq->init.tsd_extension);
+
+    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++)
+	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++)
+	    fore200e_param_bs_queue(fore200e, scheme, magn,
+				    QUEUE_SIZE_BS, 
+				    fore200e_rx_buf_nbr[ scheme ][ magn ],
+				    RBD_BLK_SIZE);
+
+    /* issue the initialize command */
+    fore200e->bus->write(STATUS_PENDING,    &cpq->init.status);
+    fore200e->bus->write(OPCODE_INITIALIZE, &cpq->init.opcode);
+
+    ok = fore200e_io_poll(fore200e, &cpq->init.status, STATUS_COMPLETE, 3000);
+    if (ok == 0) {
+	printk(FORE200E "device %s initialization failed\n", fore200e->name);
+	return -ENODEV;
+    }
+
+    printk(FORE200E "device %s initialized\n", fore200e->name);
+
+    fore200e->state = FORE200E_STATE_INITIALIZE;
+    return 0;
+}
+
+
+static void __init
+fore200e_monitor_putc(struct fore200e* fore200e, char c)
+{
+    struct cp_monitor* monitor = fore200e->cp_monitor;
+
+#if 0
+    printk("%c", c);
+#endif
+    fore200e->bus->write(((u32) c) | FORE200E_CP_MONITOR_UART_AVAIL, &monitor->soft_uart.send);
+}
+
+
+static int __init
+fore200e_monitor_getc(struct fore200e* fore200e)
+{
+    struct cp_monitor* monitor = fore200e->cp_monitor;
+    unsigned long      timeout = jiffies + MSECS(50);
+    int                c;
+
+    while (jiffies < timeout) {
+
+	c = (int) fore200e->bus->read(&monitor->soft_uart.recv);
+
+	if (c & FORE200E_CP_MONITOR_UART_AVAIL) {
+
+	    fore200e->bus->write(FORE200E_CP_MONITOR_UART_FREE, &monitor->soft_uart.recv);
+#if 0
+	    printk("%c", c & 0xFF);
+#endif
+	    return c & 0xFF;
+	}
+    }
+
+    return -1;
+}
+
+
+static void __init
+fore200e_monitor_puts(struct fore200e* fore200e, char* str)
+{
+    while(*str) {
+
+	/* the i960 monitor doesn't accept any new character if it has something to say */
+	while (fore200e_monitor_getc(fore200e) >= 0);
+	
+	fore200e_monitor_putc(fore200e, *str++);
+    }
+
+    while (fore200e_monitor_getc(fore200e) >= 0);
+}
+
+
+static int __init
+fore200e_start_fw(struct fore200e* fore200e)
+{
+    int               ok;
+    char              cmd[ 48 ];
+    struct fw_header* fw_header = (struct fw_header*) fore200e->bus->fw_data;
+
+    DPRINTK(2, "device %s firmware being started\n", fore200e->name);
+
+    sprintf(cmd, "\rgo %x\r", le32_to_cpu(fw_header->start_offset));
+
+    fore200e_monitor_puts(fore200e, cmd);
+
+    ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000);
+    if (ok == 0) {
+	printk(FORE200E "device %s firmware didn't start\n", fore200e->name);
+	return -ENODEV;
+    }
+
+    printk(FORE200E "device %s firmware started\n", fore200e->name);
+
+    fore200e->state = FORE200E_STATE_START_FW;
+    return 0;
+}
+
+
+static int __init
+fore200e_load_fw(struct fore200e* fore200e)
+{
+    u32* fw_data = (u32*) fore200e->bus->fw_data;
+    u32  fw_size = (u32) *fore200e->bus->fw_size / sizeof(u32);
+
+    struct fw_header* fw_header = (struct fw_header*) fw_data;
+
+    u32* load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset);
+
+    DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n", 
+	    fore200e->name, load_addr, fw_size);
+
+#if 1
+    if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) {
+	printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name);
+	return -ENODEV;
+    }
+#endif
+
+    for (; fw_size--; fw_data++, load_addr++)
+	fore200e->bus->write(le32_to_cpu(*fw_data), load_addr);
+
+    fore200e->state = FORE200E_STATE_LOAD_FW;
+    return 0;
+}
+
+
+static int __init
+fore200e_register(struct fore200e* fore200e)
+{
+    struct atm_dev* atm_dev;
+
+    DPRINTK(2, "device %s being registered\n", fore200e->name);
+
+    atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1, 0); 
+    if (atm_dev == NULL) {
+	printk(FORE200E "unable to register device %s\n", fore200e->name);
+	return -ENODEV;
+    }
+
+    FORE200E_DEV(atm_dev) = fore200e;
+    fore200e->atm_dev = atm_dev;
+
+    atm_dev->ci_range.vpi_bits = 8;
+    atm_dev->ci_range.vci_bits = 10;
+
+    fore200e->available_cell_rate = ATM_OC3_PCR;
+
+    fore200e->state = FORE200E_STATE_REGISTER;
+    return 0;
+}
+
+
+static int __init
+fore200e_init(struct fore200e* fore200e)
+{
+    if (fore200e_register(fore200e) < 0)
+	return -ENODEV;
+    
+    if (fore200e->bus->configure(fore200e) < 0)
+	return -ENODEV;
+
+    if (fore200e->bus->map(fore200e) < 0)
+	return -ENODEV;
+
+    if (fore200e_reset(fore200e, 1) < 0)
+	return -ENODEV;
+
+    if (fore200e_load_fw(fore200e) < 0)
+	return -ENODEV;
+
+    if (fore200e_start_fw(fore200e) < 0)
+	return -ENODEV;
+
+    if (fore200e_initialize(fore200e) < 0)
+	return -ENODEV;
+
+    if (fore200e_init_cmd_queue(fore200e) < 0)
+	return -ENOMEM;
+
+    if (fore200e_init_tx_queue(fore200e) < 0)
+	return -ENOMEM;
+
+    if (fore200e_init_rx_queue(fore200e) < 0)
+	return -ENOMEM;
+
+    if (fore200e_init_bs_queue(fore200e) < 0)
+	return -ENOMEM;
+
+    if (fore200e_alloc_rx_buf(fore200e) < 0)
+	return -ENOMEM;
+
+    if (fore200e_get_esi(fore200e) < 0)
+	return -EIO;
+
+    if (fore200e_irq_request(fore200e) < 0)
+	return -EBUSY;
+
+    fore200e_supply(fore200e);
+    
+    /* all done, board initialization is now complete */
+    fore200e->state = FORE200E_STATE_COMPLETE;
+    return 0;
+}
+
+
+int __init
+fore200e_detect(void)
+{
+    const struct fore200e_bus* bus;
+    struct       fore200e*     fore200e;
+    int                        index, link;
+
+    printk(FORE200E "FORE Systems 200E-series driver - version " FORE200E_VERSION "\n");
+
+    /* for each configured bus interface */
+    for (link = 0, bus = fore200e_bus; bus->model_name; bus++) {
+
+	/* detect all boards present on that bus */
+	for (index = 0; (fore200e = bus->detect(bus, index)); index++) {
+	    
+	    printk(FORE200E "device %s found at 0x%lx, IRQ %s\n",
+		   fore200e->bus->model_name, 
+		   fore200e->phys_base, fore200e_irq_itoa(fore200e->irq));
+
+	    sprintf(fore200e->name, "%s-%d", bus->model_name, index);
+
+	    if (fore200e_init(fore200e) < 0) {
+
+		fore200e_shutdown(fore200e);
+		break;
+	    }
+
+	    link++;
+
+	    fore200e->next  = fore200e_boards;
+	    fore200e_boards = fore200e;
+	}
+    }
+
+#if 0 /* XXX uncomment this to forbid module unloading */
+#ifdef MODULE
+    if (link > 0)
+	MOD_INC_USE_COUNT;
+#endif
+#endif
+
+    return link;
+}
+
+
+#ifdef MODULE
+static void
+fore200e_cleanup(struct fore200e** head)
+{
+    struct fore200e* fore200e = *head;
+
+    fore200e_shutdown(fore200e);
+
+    *head = fore200e->next;
+
+    kfree(fore200e);
+}
+#endif
+
+
+static int
+fore200e_proc_read(struct atm_dev *dev,loff_t* pos,char* page)
+{
+    struct fore200e* fore200e  = FORE200E_DEV(dev);
+    int              len, left = *pos;
+
+    if (!left--) {
+
+	if (fore200e_getstats(fore200e) < 0)
+	    return -EIO;
+
+	len = sprintf(page,"\n"
+		       " device:\n"
+		       "   internal name:\t\t%s\n", fore200e->name);
+
+	/* print bus-specific information */
+	if (fore200e->bus->proc_read)
+	    len += fore200e->bus->proc_read(fore200e, page + len);
+	
+	len += sprintf(page + len,
+		"   interrupt line:\t\t%s\n"
+		"   physical base address:\t0x%p\n"
+		"   virtual base address:\t0x%p\n"
+		"   factory address (ESI):\t%02x:%02x:%02x:%02x:%02x:%02x\n"
+		"   board serial number:\t\t%d\n\n",
+		fore200e_irq_itoa(fore200e->irq),
+		(void*)fore200e->phys_base,
+		(void*)fore200e->virt_base,
+		fore200e->esi[0], fore200e->esi[1], fore200e->esi[2],
+		fore200e->esi[3], fore200e->esi[4], fore200e->esi[5],
+		fore200e->esi[4] * 256 + fore200e->esi[5]);
+
+	return len;
+    }
+
+    if (!left--)
+	return sprintf(page,
+		       "   supplied small bufs (1):\t%d\n"
+		       "   supplied large bufs (1):\t%d\n"
+		       "   supplied small bufs (2):\t%d\n"
+		       "   supplied large bufs (2):\t%d\n",
+		       fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_SMALL ].count,
+		       fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_LARGE ].count,
+		       fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_SMALL ].count,
+		       fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_LARGE ].count);
+    if (!left--) {
+	u32 hb = fore200e->bus->read(&fore200e->cp_queues->heartbeat);
+
+	len = sprintf(page,"\n\n"
+		      " cell processor:\n"
+		      "   heartbeat state:\t\t");
+	
+	if (hb >> 16 != 0xDEAD)
+	    len += sprintf(page + len, "0x%08x\n", hb);
+	else
+	    len += sprintf(page + len, "*** FATAL ERROR %04x ***\n", hb & 0xFFFF);
+
+	return len;
+    }
+
+    if (!left--) {
+	static const char* media_name[] = {
+	    "unshielded twisted pair",
+	    "multimode optical fiber ST",
+	    "multimode optical fiber SC",
+	    "single-mode optical fiber ST",
+	    "single-mode optical fiber SC",
+	    "unknown"
+	};
+
+	static const char* oc3_mode[] = {
+	    "normal operation",
+	    "diagnostic loopback",
+	    "line loopback"
+	};
+
+	u32 fw_release     = fore200e->bus->read(&fore200e->cp_queues->fw_release);
+	u32 mon960_release = fore200e->bus->read(&fore200e->cp_queues->mon960_release);
+	u32 oc3_revision   = fore200e->bus->read(&fore200e->cp_queues->oc3_revision);
+	u32 media_index    = FORE200E_MEDIA_INDEX(fore200e->bus->read(&fore200e->cp_queues->media_type));
+
+	if (media_index < 0 || media_index > 4)
+	    media_index = 5;
+	
+	return sprintf(page,
+		       "   firmware release:\t\t%d.%d.%d\n"
+		       "   monitor release:\t\t%d.%d\n"
+		       "   media type:\t\t\t%s\n"
+		       "   OC-3 revision:\t\t0x%x\n"
+                       "   OC-3 mode:\t\t\t%s",
+		       fw_release >> 16, fw_release << 16 >> 24,  fw_release << 24 >> 24,
+		       mon960_release >> 16, mon960_release << 16 >> 16,
+		       media_name[ media_index ],
+		       oc3_revision,
+		       oc3_mode[ fore200e->loop_mode ]);
+    }
+
+    if (!left--) {
+	struct cp_monitor* cp_monitor = fore200e->cp_monitor;
+
+	return sprintf(page,
+		       "\n\n"
+		       " monitor:\n"
+		       "   version number:\t\t%d\n"
+		       "   boot status word:\t\t0x%08x\n",
+		       fore200e->bus->read(&cp_monitor->mon_version),
+		       fore200e->bus->read(&cp_monitor->bstat));
+    }
+
+    if (!left--)
+	return sprintf(page,
+		       "\n"
+		       " device statistics:\n"
+		       "  4b5b:\n"
+		       "     crc_header_errors:\t\t%10u\n"
+		       "     framing_errors:\t\t%10u\n",
+		       fore200e_swap(fore200e->stats->phy.crc_header_errors),
+		       fore200e_swap(fore200e->stats->phy.framing_errors));
+    
+    if (!left--)
+	return sprintf(page, "\n"
+		       "  OC-3:\n"
+		       "     section_bip8_errors:\t%10u\n"
+		       "     path_bip8_errors:\t\t%10u\n"
+		       "     line_bip24_errors:\t\t%10u\n"
+		       "     line_febe_errors:\t\t%10u\n"
+		       "     path_febe_errors:\t\t%10u\n"
+		       "     corr_hcs_errors:\t\t%10u\n"
+		       "     ucorr_hcs_errors:\t\t%10u\n",
+		       fore200e_swap(fore200e->stats->oc3.section_bip8_errors),
+		       fore200e_swap(fore200e->stats->oc3.path_bip8_errors),
+		       fore200e_swap(fore200e->stats->oc3.line_bip24_errors),
+		       fore200e_swap(fore200e->stats->oc3.line_febe_errors),
+		       fore200e_swap(fore200e->stats->oc3.path_febe_errors),
+		       fore200e_swap(fore200e->stats->oc3.corr_hcs_errors),
+		       fore200e_swap(fore200e->stats->oc3.ucorr_hcs_errors));
+
+    if (!left--)
+	return sprintf(page,"\n"
+		       "   ATM:\t\t\t\t     cells\n"
+		       "     TX:\t\t\t%10u\n"
+		       "     RX:\t\t\t%10u\n"
+		       "     vpi out of range:\t\t%10u\n"
+		       "     vpi no conn:\t\t%10u\n"
+		       "     vci out of range:\t\t%10u\n"
+		       "     vci no conn:\t\t%10u\n",
+		       fore200e_swap(fore200e->stats->atm.cells_transmitted),
+		       fore200e_swap(fore200e->stats->atm.cells_received),
+		       fore200e_swap(fore200e->stats->atm.vpi_bad_range),
+		       fore200e_swap(fore200e->stats->atm.vpi_no_conn),
+		       fore200e_swap(fore200e->stats->atm.vci_bad_range),
+		       fore200e_swap(fore200e->stats->atm.vci_no_conn));
+    
+    if (!left--)
+	return sprintf(page,"\n"
+		       "   AAL0:\t\t\t     cells\n"
+		       "     TX:\t\t\t%10u\n"
+		       "     RX:\t\t\t%10u\n"
+		       "     dropped:\t\t\t%10u\n",
+		       fore200e_swap(fore200e->stats->aal0.cells_transmitted),
+		       fore200e_swap(fore200e->stats->aal0.cells_received),
+		       fore200e_swap(fore200e->stats->aal0.cells_dropped));
+    
+    if (!left--)
+	return sprintf(page,"\n"
+		       "   AAL3/4:\n"
+		       "     SAR sublayer:\t\t     cells\n"
+		       "       TX:\t\t\t%10u\n"
+		       "       RX:\t\t\t%10u\n"
+		       "       dropped:\t\t\t%10u\n"
+		       "       CRC errors:\t\t%10u\n"
+		       "       protocol errors:\t\t%10u\n\n"
+		       "     CS  sublayer:\t\t      PDUs\n"
+		       "       TX:\t\t\t%10u\n"
+		       "       RX:\t\t\t%10u\n"
+		       "       dropped:\t\t\t%10u\n"
+		       "       protocol errors:\t\t%10u\n",
+		       fore200e_swap(fore200e->stats->aal34.cells_transmitted),
+		       fore200e_swap(fore200e->stats->aal34.cells_received),
+		       fore200e_swap(fore200e->stats->aal34.cells_dropped),
+		       fore200e_swap(fore200e->stats->aal34.cells_crc_errors),
+		       fore200e_swap(fore200e->stats->aal34.cells_protocol_errors),
+		       fore200e_swap(fore200e->stats->aal34.cspdus_transmitted),
+		       fore200e_swap(fore200e->stats->aal34.cspdus_received),
+		       fore200e_swap(fore200e->stats->aal34.cspdus_dropped),
+		       fore200e_swap(fore200e->stats->aal34.cspdus_protocol_errors));
+    
+    if (!left--)
+	return sprintf(page,"\n"
+		       "   AAL5:\n"
+		       "     SAR sublayer:\t\t     cells\n"
+		       "       TX:\t\t\t%10u\n"
+		       "       RX:\t\t\t%10u\n"
+		       "       dropped:\t\t\t%10u\n"
+		       "       congestions:\t\t%10u\n\n"
+		       "     CS  sublayer:\t\t      PDUs\n"
+		       "       TX:\t\t\t%10u\n"
+		       "       RX:\t\t\t%10u\n"
+		       "       dropped:\t\t\t%10u\n"
+		       "       CRC errors:\t\t%10u\n"
+		       "       protocol errors:\t\t%10u\n",
+		       fore200e_swap(fore200e->stats->aal5.cells_transmitted),
+		       fore200e_swap(fore200e->stats->aal5.cells_received),
+		       fore200e_swap(fore200e->stats->aal5.cells_dropped),
+		       fore200e_swap(fore200e->stats->aal5.congestion_experienced),
+		       fore200e_swap(fore200e->stats->aal5.cspdus_transmitted),
+		       fore200e_swap(fore200e->stats->aal5.cspdus_received),
+		       fore200e_swap(fore200e->stats->aal5.cspdus_dropped),
+		       fore200e_swap(fore200e->stats->aal5.cspdus_crc_errors),
+		       fore200e_swap(fore200e->stats->aal5.cspdus_protocol_errors));
+    
+    if (!left--)
+	return sprintf(page,"\n"
+		       "   AUX:\t\t       allocation failures\n"
+		       "     small b1:\t\t\t%10u\n"
+		       "     large b1:\t\t\t%10u\n"
+		       "     small b2:\t\t\t%10u\n"
+		       "     large b2:\t\t\t%10u\n"
+		       "     RX PDUs:\t\t\t%10u\n",
+		       fore200e_swap(fore200e->stats->aux.small_b1_failed),
+		       fore200e_swap(fore200e->stats->aux.large_b1_failed),
+		       fore200e_swap(fore200e->stats->aux.small_b2_failed),
+		       fore200e_swap(fore200e->stats->aux.large_b2_failed),
+		       fore200e_swap(fore200e->stats->aux.rpd_alloc_failed));
+    
+    if (!left--)
+	return sprintf(page,"\n"
+		       " receive carrier:\t\t\t%s\n",
+		       fore200e->stats->aux.receive_carrier ? "ON" : "OFF!");
+    
+    if (!left--) {
+	struct atm_vcc *vcc;
+	struct fore200e_vcc* fore200e_vcc;
+	
+	len = sprintf(page,"\n"    
+		      " VCCs:\n  address\tVPI.VCI:AAL\t(min/max tx PDU size) (min/max rx PDU size)\n");
+	
+	for (vcc = fore200e->atm_dev->vccs; vcc; vcc = vcc->next) {
+
+	    fore200e_vcc = FORE200E_VCC(vcc);
+	    
+	    len += sprintf(page + len,
+			   "  %x\t%d.%d:%d\t\t(%d/%d)\t(%d/%d)\n",
+			   (u32)(unsigned long)vcc,
+			   vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
+			   fore200e_vcc->tx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->tx_min_pdu,
+			   fore200e_vcc->tx_max_pdu,
+			   fore200e_vcc->rx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->rx_min_pdu,
+			   fore200e_vcc->rx_max_pdu
+		);
+	}
+
+	return len;
+    }
+    
+    return 0;
+}
+
+
+#ifdef MODULE
+unsigned int
+init_module(void)
+{
+    DPRINTK(1, "module loaded\n");
+    return fore200e_detect() == 0;
+}
+
+void
+cleanup_module(void)
+{
+    while (fore200e_boards) {
+	fore200e_cleanup(&fore200e_boards);
+    }
+    DPRINTK(1, "module being removed\n");
+}
+#endif
+
+
+static const struct atmdev_ops fore200e_ops =
+{
+    NULL, /* fore200e_dev_close   */
+    fore200e_open,
+    fore200e_close,
+    fore200e_ioctl,
+    fore200e_getsockopt,
+    fore200e_setsockopt,
+    fore200e_send,
+    NULL, /* fore200e_sg_send,    */
+    NULL, /* fore200e_send_oam,   */
+    NULL, /* fore200e_phy_put,    */
+    NULL, /* fore200e_phy_get,    */
+    NULL, /* fore200e_feedback,   */
+    fore200e_change_qos,
+    NULL, /* fore200e_free_rx_skb */
+    fore200e_proc_read
+};
+
+
+#ifdef CONFIG_ATM_FORE200E_PCA
+extern const unsigned char _fore200e_pca_fw_data[];
+extern const unsigned int  _fore200e_pca_fw_size;
+#endif
+#ifdef CONFIG_ATM_FORE200E_SBA
+extern const unsigned char _fore200e_sba_fw_data[];
+extern const unsigned int  _fore200e_sba_fw_size;
+#endif
+
+static const struct fore200e_bus fore200e_bus[] = {
+#ifdef CONFIG_ATM_FORE200E_PCA
+    { "PCA-200E", "pca200e", 32, 4, 32, 
+      _fore200e_pca_fw_data, &_fore200e_pca_fw_size,
+      fore200e_pca_read,
+      fore200e_pca_write,
+      fore200e_pca_dma_map,
+      fore200e_pca_dma_unmap,
+      fore200e_pca_dma_sync,
+      fore200e_pca_dma_chunk_alloc,
+      fore200e_pca_dma_chunk_free,
+      fore200e_pca_detect,
+      fore200e_pca_configure,
+      fore200e_pca_map,
+      fore200e_pca_reset,
+      fore200e_pca_prom_read,
+      fore200e_pca_unmap,
+      NULL,
+      fore200e_pca_irq_check,
+      fore200e_pca_irq_ack,
+      fore200e_pca_proc_read,
+    },
+#endif
+#ifdef CONFIG_ATM_FORE200E_SBA
+    { "SBA-200E", "sba200e", 32, 64, 32,
+      _fore200e_sba_fw_data, &_fore200e_sba_fw_size,
+      fore200e_sba_read,
+      fore200e_sba_write,
+      fore200e_sba_dma_map,
+      fore200e_sba_dma_unmap,
+      fore200e_sba_dma_sync,
+      fore200e_sba_dma_chunk_alloc,
+      fore200e_sba_dma_chunk_free,
+      fore200e_sba_detect, 
+      fore200e_sba_configure,
+      fore200e_sba_map,
+      fore200e_sba_reset,
+      fore200e_sba_prom_read,
+      fore200e_sba_unmap,
+      fore200e_sba_irq_enable,
+      fore200e_sba_irq_check,
+      fore200e_sba_irq_ack,
+      fore200e_sba_proc_read,
+    },
+#endif
+    {}
+};
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/fore200e.h linux/drivers/atm/fore200e.h
--- v2.3.47/linux/drivers/atm/fore200e.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/atm/fore200e.h	Mon Feb 21 16:32:27 2000
@@ -0,0 +1,952 @@
+#ifndef _FORE200E_H
+#define _FORE200E_H
+
+#ifdef __KERNEL__
+
+/* rx buffer sizes */
+
+#define SMALL_BUFFER_SIZE    384     /* size of small buffers (multiple of 48 (PCA) and 64 (SBA) bytes) */
+#define LARGE_BUFFER_SIZE    4032    /* size of large buffers (multiple of 48 (PCA) and 64 (SBA) bytes) */
+
+
+#define RBD_BLK_SIZE	     32      /* nbr of supplied rx buffers per rbd */
+
+
+#define MAX_PDU_SIZE	     65535   /* maximum PDU size supported by AALs */
+
+
+#define BUFFER_S1_SIZE       SMALL_BUFFER_SIZE    /* size of small buffers, scheme 1 */
+#define BUFFER_L1_SIZE       LARGE_BUFFER_SIZE    /* size of large buffers, scheme 1 */
+
+#define BUFFER_S2_SIZE       SMALL_BUFFER_SIZE    /* size of small buffers, scheme 2 */
+#define BUFFER_L2_SIZE       LARGE_BUFFER_SIZE    /* size of large buffers, scheme 2 */
+
+#define BUFFER_S1_NBR        (RBD_BLK_SIZE * 2)
+#define BUFFER_L1_NBR        (RBD_BLK_SIZE * 2)
+
+#define BUFFER_S2_NBR        (RBD_BLK_SIZE * 2)
+#define BUFFER_L2_NBR        (RBD_BLK_SIZE * 2)
+
+
+#define QUEUE_SIZE_CMD       16	     /* command queue capacity       */
+#define QUEUE_SIZE_RX	     64	     /* receive queue capacity       */
+#define QUEUE_SIZE_TX	     256     /* transmit queue capacity      */
+#define QUEUE_SIZE_BS        16	     /* buffer supply queue capacity */
+
+#define NBR_CONNECT          1024    /* number of ATM connections     */
+
+
+#define TSD_FIXED            2
+#define TSD_EXTENSION        0
+#define TSD_NBR              (TSD_FIXED + TSD_EXTENSION)
+
+
+/* the cp starts putting a received PDU into one *small* buffer,
+   then it uses a number of *large* buffers for the trailing data. 
+   we compute here the total number of receive segment descriptors 
+   required to hold the largest possible PDU */
+
+#define RSD_REQUIRED  (((MAX_PDU_SIZE - SMALL_BUFFER_SIZE + LARGE_BUFFER_SIZE) / LARGE_BUFFER_SIZE) + 1)
+
+#define RSD_FIXED     3
+
+/* RSD_REQUIRED receive segment descriptors are enough to describe a max-sized PDU,
+   but we have to keep the size of the receive PDU descriptor multiple of 32 bytes,
+   so we add one extra RSD to RSD_EXTENSION 
+   (WARNING: THIS MAY CHANGE IF BUFFER SIZES ARE MODIFIED) */
+
+#define RSD_EXTENSION  ((RSD_REQUIRED - RSD_FIXED) + 1)
+#define RSD_NBR         (RSD_FIXED + RSD_EXTENSION)
+
+
+#define FORE200E_DEV(d)          ((struct fore200e*)((d)->dev_data))
+#define FORE200E_VCC(d)          ((struct fore200e_vcc*)((d)->dev_data))
+
+/* bitfields endian games */
+
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+#define BITFIELD2(b1, b2)                    b1; b2;
+#define BITFIELD3(b1, b2, b3)                b1; b2; b3;
+#define BITFIELD4(b1, b2, b3, b4)            b1; b2; b3; b4;
+#define BITFIELD5(b1, b2, b3, b4, b5)        b1; b2; b3; b4; b5;
+#define BITFIELD6(b1, b2, b3, b4, b5, b6)    b1; b2; b3; b4; b5; b6;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+#define BITFIELD2(b1, b2)                                    b2; b1;
+#define BITFIELD3(b1, b2, b3)                            b3; b2; b1;
+#define BITFIELD4(b1, b2, b3, b4)                    b4; b3; b2; b1;
+#define BITFIELD5(b1, b2, b3, b4, b5)            b5; b4; b3; b2; b1;
+#define BITFIELD6(b1, b2, b3, b4, b5, b6)    b6; b5; b4; b3; b2; b1;
+#else
+#error unknown bitfield endianess
+#endif
+
+ 
+/* ATM cell header (minus HEC byte) */
+
+typedef struct atm_header {
+    BITFIELD5( 
+        u32 clp :  1,    /* cell loss priority         */
+        u32 plt :  3,    /* payload type               */
+        u32 vci : 16,    /* virtual channel identifier */
+        u32 vpi :  8,    /* virtual path identifier    */
+        u32 gfc :  4     /* generic flow control       */
+   )
+} atm_header_t;
+
+
+/* ATM adaptation layer id */
+
+typedef enum fore200e_aal {
+    FORE200E_AAL0  = 0,
+    FORE200E_AAL34 = 4,
+    FORE200E_AAL5  = 5,
+} fore200e_aal_t;
+
+
+/* transmit PDU descriptor specification */
+
+typedef struct tpd_spec {
+    BITFIELD4(
+        u32               length : 16,    /* total PDU length            */
+        u32               nseg   :  8,    /* number of transmit segments */
+        enum fore200e_aal aal    :  4,    /* adaptation layer            */
+        u32               intr   :  4     /* interrupt requested         */
+    )
+} tpd_spec_t;
+
+
+/* transmit PDU rate control */
+
+typedef struct tpd_rate
+{
+    BITFIELD2( 
+        u32 idle_cells : 16,    /* number of idle cells to insert   */
+        u32 data_cells : 16     /* number of data cells to transmit */
+    )
+} tpd_rate_t;
+
+
+/* transmit segment descriptor */
+
+typedef struct tsd {
+    u32 buffer;    /* transmit buffer DMA address */
+    u32 length;    /* number of bytes in buffer   */
+} tsd_t;
+
+
+/* transmit PDU descriptor */
+
+typedef struct tpd {
+    struct atm_header atm_header;        /* ATM header minus HEC byte    */
+    struct tpd_spec   spec;              /* tpd specification            */
+    struct tpd_rate   rate;              /* tpd rate control             */
+    u32               pad;               /* reserved                     */
+    struct tsd        tsd[ TSD_NBR ];    /* transmit segment descriptors */
+} tpd_t;
+
+
+/* receive segment descriptor */
+
+typedef struct rsd {
+    u32 handle;    /* host supplied receive buffer handle */
+    u32 length;    /* number of bytes in buffer           */
+} rsd_t;
+
+
+/* receive PDU descriptor */
+
+typedef struct rpd {
+    struct atm_header atm_header;        /* ATM header minus HEC byte   */
+    u32               nseg;              /* number of receive segments  */
+    struct rsd        rsd[ RSD_NBR ];    /* receive segment descriptors */
+} rpd_t;
+
+
+/* buffer scheme */
+
+typedef enum buffer_scheme {
+    BUFFER_SCHEME_ONE,
+    BUFFER_SCHEME_TWO,
+    BUFFER_SCHEME_NBR    /* always last */
+} buffer_scheme_t;
+
+
+/* buffer magnitude */
+
+typedef enum buffer_magn {
+    BUFFER_MAGN_SMALL,
+    BUFFER_MAGN_LARGE,
+    BUFFER_MAGN_NBR    /* always last */
+} buffer_magn_t;
+
+
+/* receive buffer descriptor */
+
+typedef struct rbd {
+    u32 handle;          /* host supplied handle            */
+    u32 buffer_haddr;    /* host DMA address of host buffer */
+} rbd_t;
+
+
+/* receive buffer descriptor block */
+
+typedef struct rbd_block {
+    struct rbd rbd[ RBD_BLK_SIZE ];    /* receive buffer descriptor */
+} rbd_block_t;
+
+
+/* tpd DMA address */
+
+typedef struct tpd_haddr {
+    BITFIELD3( 
+        u32 size  :  4,    /* tpd size expressed in 32 byte blocks     */
+        u32 pad   :  1,    /* reserved                                 */
+        u32 haddr : 27     /* tpd DMA addr aligned on 32 byte boundary */
+    )
+} tpd_haddr_t;
+
+
+/* cp resident transmit queue entry */
+
+typedef struct cp_txq_entry {
+    struct tpd_haddr tpd_haddr;       /* host DMA address of tpd                */
+    u32              status_haddr;    /* host DMA address of completion status  */
+} cp_txq_entry_t;
+
+
+/* cp resident receive queue entry */
+
+typedef struct cp_rxq_entry {
+    u32 rpd_haddr;       /* host DMA address of rpd                */
+    u32 status_haddr;    /* host DMA address of completion status  */
+} cp_rxq_entry_t;
+
+
+/* cp resident buffer supply queue entry */
+
+typedef struct cp_bsq_entry {
+    u32 rbd_block_haddr;    /* host DMA address of rbd block          */
+    u32 status_haddr;       /* host DMA address of completion status  */
+} cp_bsq_entry_t;
+
+
+/* completion status */
+
+typedef volatile enum status {
+    STATUS_PENDING  = (1<<0),    /* initial status (written by host)  */
+    STATUS_COMPLETE = (1<<1),    /* completion status (written by cp) */
+    STATUS_FREE     = (1<<2),    /* initial status (written by host)  */
+    STATUS_ERROR    = (1<<3)     /* completion status (written by cp) */
+} status_t;
+
+
+/* cp operation code */
+
+typedef enum opcode {
+    OPCODE_INITIALIZE = 1,          /* initialize board                       */
+    OPCODE_ACTIVATE_VCIN,           /* activate incoming VCI                  */
+    OPCODE_ACTIVATE_VCOUT,          /* activate outgoing VCI                  */
+    OPCODE_DEACTIVATE_VCIN,         /* deactivate incoming VCI                */
+    OPCODE_DEACTIVATE_VCOUT,        /* deactivate incoing VCI                 */
+    OPCODE_GET_STATS,               /* get board statistics                   */
+    OPCODE_SET_OC3,                 /* set OC-3 registers                     */
+    OPCODE_GET_OC3,                 /* get OC-3 registers                     */
+    OPCODE_RESET_STATS,             /* reset board statistics                 */
+    OPCODE_GET_PROM,                /* get expansion PROM data (PCI specific) */
+    OPCODE_SET_VPI_BITS,            /* set x bits of those decoded by the
+				       firmware to be low order bits from
+				       the VPI field of the ATM cell header   */
+    OPCODE_REQUEST_INTR = (1<<7)    /* request interrupt                      */
+} opcode_t;
+
+
+/* virtual path / virtual channel identifers */
+
+typedef struct vpvc {
+    BITFIELD3(
+        u32 vci : 16,    /* virtual channel identifier */
+        u32 vpi :  8,    /* virtual path identifier    */
+        u32 pad :  8     /* reserved                   */
+    )
+} vpvc_t;
+
+
+/* activate VC command opcode */
+
+typedef struct activate_opcode {
+    BITFIELD4( 
+        enum opcode        opcode : 8,    /* cp opcode        */
+        enum fore200e_aal  aal    : 8,    /* adaptation layer */
+        enum buffer_scheme scheme : 8,    /* buffer scheme    */
+        u32  pad                  : 8     /* reserved         */
+   )
+} activate_opcode_t;
+
+
+/* activate VC command block */
+
+typedef struct activate_block {
+    struct activate_opcode  opcode;    /* activate VC command opcode */
+    struct vpvc             vpvc;      /* VPI/VCI                    */
+    u32                     mtu;       /* for AAL0 only              */
+
+} activate_block_t;
+
+
+/* deactivate VC command opcode */
+
+typedef struct deactivate_opcode {
+    BITFIELD2(
+        enum opcode opcode :  8,    /* cp opcode */
+        u32         pad    : 24     /* reserved  */
+    )
+} deactivate_opcode_t;
+
+
+/* deactivate VC command block */
+
+typedef struct deactivate_block {
+    struct deactivate_opcode opcode;    /* deactivate VC command opcode */
+    struct vpvc              vpvc;      /* VPI/VCI                      */
+} deactivate_block_t;
+
+
+/* OC-3 registers */
+
+typedef struct oc3_regs {
+    u32 reg[ 128 ];    /* see the PMC Sierra PC5346 S/UNI-155-Lite
+			  Saturn User Network Interface documentation
+			  for a description of the OC-3 chip registers */
+} oc3_regs_t;
+
+
+/* set/get OC-3 regs command opcode */
+
+typedef struct oc3_opcode {
+    BITFIELD4(
+        enum opcode opcode : 8,    /* cp opcode                           */
+	u32         reg    : 8,    /* register index                      */
+	u32         value  : 8,    /* register value                      */
+	u32         mask   : 8     /* register mask that specifies which
+				      bits of the register value field
+				      are significant                     */
+    )
+} oc3_opcode_t;
+
+
+/* set/get OC-3 regs command block */
+
+typedef struct oc3_block {
+    struct oc3_opcode opcode;        /* set/get OC-3 regs command opcode     */
+    u32               regs_haddr;    /* host DMA address of OC-3 regs buffer */
+} oc3_block_t;
+
+
+/* physical encoding statistics */
+
+typedef struct stats_phy {
+    u32 crc_header_errors;    /* cells received with bad header CRC */
+    u32 framing_errors;       /* cells received with bad framing    */
+    u32 pad[ 2 ];             /* i960 padding                       */
+} stats_phy_t;
+
+
+/* OC-3 statistics */
+
+typedef struct stats_oc3 {
+    u32 section_bip8_errors;    /* section 8 bit interleaved parity    */
+    u32 path_bip8_errors;       /* path 8 bit interleaved parity       */
+    u32 line_bip24_errors;      /* line 24 bit interleaved parity      */
+    u32 line_febe_errors;       /* line far end block errors           */
+    u32 path_febe_errors;       /* path far end block errors           */
+    u32 corr_hcs_errors;        /* correctable header check sequence   */
+    u32 ucorr_hcs_errors;       /* uncorrectable header check sequence */
+    u32 pad[ 1 ];               /* i960 padding                        */
+} stats_oc3_t;
+
+
+/* ATM statistics */
+
+typedef struct stats_atm {
+    u32	cells_transmitted;    /* cells transmitted                 */
+    u32	cells_received;       /* cells received                    */
+    u32	vpi_bad_range;        /* cell drops: VPI out of range      */
+    u32	vpi_no_conn;          /* cell drops: no connection for VPI */
+    u32	vci_bad_range;        /* cell drops: VCI out of range      */
+    u32	vci_no_conn;          /* cell drops: no connection for VCI */
+    u32	pad[ 2 ];             /* i960 padding                      */
+} stats_atm_t;
+
+/* AAL0 statistics */
+
+typedef struct stats_aal0 {
+    u32	cells_transmitted;    /* cells transmitted */
+    u32	cells_received;       /* cells received    */
+    u32	cells_dropped;        /* cells dropped     */
+    u32	pad[ 1 ];             /* i960 padding      */
+} stats_aal0_t;
+
+
+/* AAL3/4 statistics */
+
+typedef struct stats_aal34 {
+    u32	cells_transmitted;         /* cells transmitted from segmented PDUs */
+    u32	cells_received;            /* cells reassembled into PDUs           */
+    u32	cells_crc_errors;          /* payload CRC error count               */
+    u32	cells_protocol_errors;     /* SAR or CS layer protocol errors       */
+    u32	cells_dropped;             /* cells dropped: partial reassembly     */
+    u32	cspdus_transmitted;        /* CS PDUs transmitted                   */
+    u32	cspdus_received;           /* CS PDUs received                      */
+    u32	cspdus_protocol_errors;    /* CS layer protocol errors              */
+    u32	cspdus_dropped;            /* reassembled PDUs drop'd (in cells)    */
+    u32	pad[ 3 ];                  /* i960 padding                          */
+} stats_aal34_t;
+
+
+/* AAL5 statistics */
+
+typedef struct stats_aal5 {
+    u32	cells_transmitted;         /* cells transmitted from segmented SDUs */
+    u32	cells_received;		   /* cells reassembled into SDUs           */
+    u32	cells_dropped;		   /* reassembled PDUs dropped (in cells)   */
+    u32	congestion_experienced;    /* CRC error and length wrong            */
+    u32	cspdus_transmitted;        /* CS PDUs transmitted                   */
+    u32	cspdus_received;           /* CS PDUs received                      */
+    u32	cspdus_crc_errors;         /* CS PDUs CRC errors                    */
+    u32	cspdus_protocol_errors;    /* CS layer protocol errors              */
+    u32	cspdus_dropped;            /* reassembled PDUs dropped              */
+    u32	pad[ 3 ];                  /* i960 padding                          */
+} stats_aal5_t;
+
+
+/* auxiliary statistics */
+
+typedef struct stats_aux {
+    u32	small_b1_failed;     /* receive BD allocation failures  */
+    u32	large_b1_failed;     /* receive BD allocation failures  */
+    u32	small_b2_failed;     /* receive BD allocation failures  */
+    u32	large_b2_failed;     /* receive BD allocation failures  */
+    u32	rpd_alloc_failed;    /* receive PDU allocation failures */
+    u32	receive_carrier;     /* no carrier = 0, carrier = 1     */
+    u32	pad[ 2 ];            /* i960 padding                    */
+} stats_aux_t;
+
+
+/* whole statistics buffer */
+
+typedef struct stats {
+    struct stats_phy   phy;      /* physical encoding statistics */
+    struct stats_oc3   oc3;      /* OC-3 statistics              */
+    struct stats_atm   atm;      /* ATM statistics               */
+    struct stats_aal0  aal0;     /* AAL0 statistics              */
+    struct stats_aal34 aal34;    /* AAL3/4 statistics            */
+    struct stats_aal5  aal5;     /* AAL5 statistics              */
+    struct stats_aux   aux;      /* auxiliary statistics         */
+} stats_t;
+
+
+/* get statistics command opcode */
+
+typedef struct stats_opcode {
+    BITFIELD2(
+        enum opcode opcode :  8,    /* cp opcode */
+        u32         pad    : 24     /* reserved  */
+    )
+} stats_opcode_t;
+
+
+/* get statistics command block */
+
+typedef struct stats_block {
+    struct stats_opcode opcode;         /* get statistics command opcode    */
+    u32                 stats_haddr;    /* host DMA address of stats buffer */
+} stats_block_t;
+
+
+/* expansion PROM data (PCI specific) */
+
+typedef struct prom_data {
+    u32 hw_revision;      /* hardware revision   */
+    u32 serial_number;    /* board serial number */
+    u8  mac_addr[ 8 ];    /* board MAC address   */
+} prom_data_t;
+
+
+/* get expansion PROM data command opcode */
+
+typedef struct prom_opcode {
+    BITFIELD2(
+        enum opcode opcode :  8,    /* cp opcode */
+        u32         pad    : 24     /* reserved  */
+    )
+} prom_opcode_t;
+
+
+/* get expansion PROM data command block */
+
+typedef struct prom_block {
+    struct prom_opcode opcode;        /* get PROM data command opcode    */
+    u32                prom_haddr;    /* host DMA address of PROM buffer */
+} prom_block_t;
+
+
+/* cp command */
+
+typedef union cmd {
+    enum   opcode           opcode;           /* operation code          */
+    struct activate_block   activate_block;   /* activate VC             */
+    struct deactivate_block deactivate_block; /* deactivate VC           */
+    struct stats_block      stats_block;      /* get statistics          */
+    struct prom_block       prom_block;       /* get expansion PROM data */
+    struct oc3_block        oc3_block;        /* get/set OC-3 registers  */
+    u32                     pad[ 4 ];         /* i960 padding            */
+} cmd_t;
+
+
+/* cp resident command queue */
+
+typedef struct cp_cmdq_entry {
+    union cmd cmd;             /* command                               */
+    u32       status_haddr;    /* host DMA address of completion status */
+    u32       pad[ 3 ];        /* i960 padding                          */
+} cp_cmdq_entry_t;
+
+
+/* host resident transmit queue entry */
+
+typedef struct host_txq_entry {
+    struct cp_txq_entry*   cp_entry;    /* addr of cp resident tx queue entry */
+    enum   status*         status;      /* addr of host resident status       */
+    struct tpd*            tpd;         /* addr of transmit PDU descriptor    */
+    u32                    tpd_dma;     /* DMA address of tpd                 */
+    struct sk_buff*        skb;         /* related skb                        */
+    struct atm_vcc*        vcc;         /* related vcc                        */
+    void*                  data;        /* copy of misaligned data            */
+} host_txq_entry_t;
+
+
+/* host resident receive queue entry */
+
+typedef struct host_rxq_entry {
+    struct cp_rxq_entry* cp_entry;    /* addr of cp resident rx queue entry */
+    enum   status*       status;      /* addr of host resident status       */
+    struct rpd*          rpd;         /* addr of receive PDU descriptor     */
+    u32                  rpd_dma;     /* DMA address of rpd                 */
+} host_rxq_entry_t;
+
+
+/* host resident buffer supply queue entry */
+
+typedef struct host_bsq_entry {
+    struct cp_bsq_entry* cp_entry;         /* addr of cp resident buffer supply queue entry */
+    enum   status*       status;           /* addr of host resident status                  */
+    struct rbd_block*    rbd_block;        /* addr of receive buffer descriptor block       */
+    u32                  rbd_block_dma;    /* DMA address od rdb                            */
+} host_bsq_entry_t;
+
+
+/* host resident command queue entry */
+
+typedef struct host_cmdq_entry {
+    struct cp_cmdq_entry* cp_entry;    /* addr of cp resident cmd queue entry */
+    enum   status*        status;      /* addr of host resident status        */
+} host_cmdq_entry_t;
+
+
+/* chunk of memory */
+
+typedef struct chunk {
+    void* alloc_addr;    /* base address of allocated chunk */
+    void* align_addr;    /* base address of aligned chunk   */
+    u32   dma_addr;      /* DMA address of aligned chunk    */
+    u32   alloc_size;    /* length of allocated chunk       */
+    u32   align_size;    /* length of aligned chunk         */
+} chunk_t;
+
+#define dma_size align_size             /* DMA useable size */
+
+
+/* host resident receive buffer */
+
+typedef struct buffer {
+    struct buffer*       next;        /* next receive buffer     */
+    enum   buffer_scheme scheme;      /* buffer scheme           */
+    enum   buffer_magn   magn;        /* buffer magnitude        */
+    struct chunk         data;        /* data buffer             */
+} buffer_t;
+
+
+#if (BITS_PER_LONG == 32)
+#define FORE200E_BUF2HDL(buffer)    ((u32)(buffer))
+#define FORE200E_HDL2BUF(handle)    ((struct buffer*)(handle))
+#else   /* deal with 64 bit pointers */
+#define FORE200E_BUF2HDL(buffer)    ((u32)((u64)(buffer)))
+#define FORE200E_HDL2BUF(handle)    ((struct buffer*)(((u64)(handle)) | PAGE_OFFSET))
+#endif
+
+
+/* host resident command queue */
+
+typedef struct host_cmdq {
+    struct host_cmdq_entry host_entry[ QUEUE_SIZE_CMD ];    /* host resident cmd queue entries        */
+    int                    head;                            /* head of cmd queue                      */
+    struct chunk           status;                          /* array of completion status      */
+} host_cmdq_t;
+
+
+/* host resident transmit queue */
+
+typedef struct host_txq {
+    struct host_txq_entry host_entry[ QUEUE_SIZE_TX ];    /* host resident tx queue entries         */
+    int                   head;                           /* head of tx queue                       */
+    struct chunk          tpd;                            /* array of tpds                          */
+    struct chunk          status;                         /* arry of completion status              */
+    int                   txing;                          /* number of pending PDUs in tx queue     */
+} host_txq_t;
+
+
+/* host resident receive queue */
+
+typedef struct host_rxq {
+    struct host_rxq_entry  host_entry[ QUEUE_SIZE_RX ];    /* host resident rx queue entries         */
+    int                    head;                           /* head of rx queue                       */
+    struct chunk           rpd;                            /* array of rpds                          */
+    struct chunk           status;                         /* array of completion status             */
+} host_rxq_t;
+
+
+/* host resident buffer supply queues */
+
+typedef struct host_bsq {
+    struct host_bsq_entry host_entry[ QUEUE_SIZE_BS ];    /* host resident buffer supply queue entries */
+    int                   head;                           /* head of buffer supply queue               */
+    struct chunk          rbd_block;                      /* array of rbds                             */
+    struct chunk          status;                         /* array of completion status                */
+    struct buffer*        buffer;                         /* array of rx buffers                       */
+    int                   free;                           /* index of first free rx buffer             */
+    volatile int          count;                          /* count of supplied rx buffers              */
+} host_bsq_t;
+
+
+/* header of the firmware image */
+
+typedef struct fw_header {
+    u32 magic;           /* magic number                               */
+    u32 version;         /* firware version id                         */
+    u32 load_offset;     /* fw load offset in board memory             */
+    u32 start_offset;    /* fw execution start address in board memory */
+} fw_header_t;
+
+#define FW_HEADER_MAGIC  0x65726f66    /* 'fore' */
+
+
+/* receive buffer supply queues scheme specification */
+
+typedef struct bs_spec {
+    u32	queue_length;      /* queue capacity                     */
+    u32	buffer_size;	   /* host buffer size			 */
+    u32	pool_size;	   /* number of rbds			 */
+    u32	supply_blksize;    /* num of rbds in I/O block (multiple
+			      of 4 between 4 and 124 inclusive)	 */
+} bs_spec_t;
+
+
+/* initialization command block (one-time command, not in cmd queue) */
+
+typedef struct init_block {
+    enum opcode  opcode;               /* initialize command             */
+    enum status  status;	       /* related status word            */
+    u32          receive_threshold;    /* not used                       */
+    u32          num_connect;          /* ATM connections                */
+    u32          cmd_queue_len;        /* length of command queue        */
+    u32          tx_queue_len;         /* length of transmit queue       */
+    u32          rx_queue_len;         /* length of receive queue        */
+    u32          rsd_extension;        /* number of extra 32 byte blocks */
+    u32          tsd_extension;        /* number of extra 32 byte blocks */
+    u32          conless_vpvc;         /* not used                       */
+    u32          pad[ 2 ];             /* force quad alignment           */
+    struct bs_spec bs_spec[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ];      /* buffer supply queues spec */
+} init_block_t;
+
+
+typedef enum media_type {
+    MEDIA_TYPE_CAT5_UTP  = 0x06,    /* unshielded twisted pair */
+    MEDIA_TYPE_MM_OC3_ST = 0x16,    /* multimode fiber ST      */
+    MEDIA_TYPE_MM_OC3_SC = 0x26,    /* multimode fiber SC      */
+    MEDIA_TYPE_SM_OC3_ST = 0x36,    /* single-mode fiber ST    */
+    MEDIA_TYPE_SM_OC3_SC = 0x46     /* single-mode fiber SC    */
+} media_type_t;
+
+#define FORE200E_MEDIA_INDEX(media_type)   ((media_type)>>4)
+
+
+/* cp resident queues */
+
+typedef struct cp_queues {
+    u32	              cp_cmdq;         /* command queue                      */
+    u32	              cp_txq;          /* transmit queue                     */
+    u32	              cp_rxq;          /* receive queue                      */
+    u32               cp_bsq[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ];        /* buffer supply queues */
+    u32	              imask;             /* 1 enables cp to host interrupts  */
+    u32	              istat;             /* 1 for interrupt posted           */
+    u32	              heap_base;         /* offset form beginning of ram     */
+    u32	              heap_size;         /* space available for queues       */
+    u32	              hlogger;           /* non zero for host logging        */
+    u32               heartbeat;         /* cp heartbeat                     */
+    u32	              fw_release;        /* firmware version                 */
+    u32	              mon960_release;    /* i960 monitor version             */
+    u32	              tq_plen;           /* transmit throughput measurements */
+    /* make sure the init block remains on a quad word boundary              */
+    struct init_block init;              /* one time cmd, not in cmd queue   */
+    enum   media_type media_type;        /* media type id                    */
+    u32               oc3_revision;      /* OC-3 revision number             */
+} cp_queues_t;
+
+
+/* boot status */
+
+typedef enum boot_status {
+    BSTAT_COLD_START    = (u32) 0xc01dc01d,    /* cold start              */
+    BSTAT_SELFTEST_OK   = (u32) 0x02201958,    /* self-test ok            */
+    BSTAT_SELFTEST_FAIL = (u32) 0xadbadbad,    /* self-test failed        */
+    BSTAT_CP_RUNNING    = (u32) 0xce11feed,    /* cp is running           */
+    BSTAT_MON_TOO_BIG   = (u32) 0x10aded00     /* i960 monitor is too big */
+} boot_status_t;
+
+
+/* software UART */
+
+typedef struct soft_uart {
+    u32 send;    /* write register */
+    u32 recv;    /* read register  */
+} soft_uart_t;
+
+#define FORE200E_CP_MONITOR_UART_FREE     0x00000000
+#define FORE200E_CP_MONITOR_UART_AVAIL    0x01000000
+
+
+/* i960 monitor */
+
+typedef struct cp_monitor {
+    struct soft_uart    soft_uart;      /* software UART           */
+    enum boot_status	bstat;          /* boot status             */
+    u32			app_base;       /* application base offset */
+    u32			mon_version;    /* i960 monitor version    */
+} cp_monitor_t;
+
+
+/* device state */
+
+typedef enum fore200e_state {
+    FORE200E_STATE_BLANK,         /* initial state                     */
+    FORE200E_STATE_REGISTER,      /* device registered                 */
+    FORE200E_STATE_CONFIGURE,     /* bus interface configured          */
+    FORE200E_STATE_MAP,           /* board space mapped in host memory */
+    FORE200E_STATE_RESET,         /* board resetted                    */
+    FORE200E_STATE_LOAD_FW,       /* firmware loaded                   */
+    FORE200E_STATE_START_FW,      /* firmware started                  */
+    FORE200E_STATE_INITIALIZE,    /* initialize command successful     */
+    FORE200E_STATE_INIT_CMDQ,     /* command queue initialized         */
+    FORE200E_STATE_INIT_TXQ,      /* transmit queue initialized        */
+    FORE200E_STATE_INIT_RXQ,      /* receive queue initialized         */
+    FORE200E_STATE_INIT_BSQ,      /* buffer supply queue initialized   */
+    FORE200E_STATE_ALLOC_BUF,     /* receive buffers allocated         */
+    FORE200E_STATE_IRQ,           /* host interrupt requested          */
+    FORE200E_STATE_COMPLETE       /* initialization completed          */
+} fore200e_state;
+
+
+/* PCA-200E registers */
+
+typedef struct fore200e_pca_regs {
+    volatile u32* hcr;    /* address of host control register        */
+    volatile u32* imr;    /* address of host interrupt mask register */
+    volatile u32* psr;    /* address of PCI specific register        */
+} fore200e_pca_regs_t;
+
+
+/* SBA-200E registers */
+
+typedef struct fore200e_sba_regs {
+    volatile u32* hcr;    /* address of host control register              */
+    volatile u32* bsr;    /* address of burst transfer size register       */
+    volatile u32* isr;    /* address of interrupt level selection register */
+} fore200e_sba_regs_t;
+
+
+/* model-specific registers */
+
+typedef union fore200e_regs {
+    struct fore200e_pca_regs pca;    /* PCA-200E registers */
+    struct fore200e_sba_regs sba;    /* SBA-200E registers */
+} fore200e_regs;
+
+
+struct fore200e;
+
+/* bus-dependent data */
+
+typedef struct fore200e_bus {
+    char*                model_name;          /* board model name                       */
+    char*                proc_name;           /* board name under /proc/atm             */
+    int                  descr_alignment;     /* tpd/rpd/rbd DMA alignment requirement  */
+    int                  buffer_alignment;    /* rx buffers DMA alignment requirement   */
+    int                  status_alignment;    /* status words DMA alignment requirement */
+    const unsigned char* fw_data;             /* address of firmware data start         */
+    const unsigned int*  fw_size;             /* address of firmware data size          */
+    u32                  (*read)(volatile u32*);
+    void                 (*write)(u32, volatile u32*);
+    u32                  (*dma_map)(struct fore200e*, void*, int);
+    void                 (*dma_unmap)(struct fore200e*, u32, int);
+    void                 (*dma_sync)(struct fore200e*, u32, int);
+    int                  (*dma_chunk_alloc)(struct fore200e*, struct chunk*, int, int, int);
+    void                 (*dma_chunk_free)(struct fore200e*, struct chunk*);
+    struct fore200e*     (*detect)(const struct fore200e_bus*, int);
+    int                  (*configure)(struct fore200e*); 
+    int                  (*map)(struct fore200e*); 
+    void                 (*reset)(struct fore200e*);
+    int                  (*prom_read)(struct fore200e*, struct prom_data*);
+    void                 (*unmap)(struct fore200e*);
+    void                 (*irq_enable)(struct fore200e*);
+    int                  (*irq_check)(struct fore200e*);
+    void                 (*irq_ack)(struct fore200e*);
+    int                  (*proc_read)(struct fore200e*, char*);
+} fore200e_bus_t;
+
+
+/* per-device data */
+
+typedef struct fore200e {
+    struct       fore200e*     next;                   /* next device                        */
+    const struct fore200e_bus* bus;                    /* bus-dependent code and data        */
+    union        fore200e_regs regs;                   /* bus-dependent registers            */
+    struct       atm_dev*      atm_dev;                /* ATM device                         */
+
+    enum fore200e_state        state;                  /* device state                       */
+
+    char                       name[16];               /* device name                        */
+    void*                      bus_dev;                /* bus-specific kernel data           */
+    int                        irq;                    /* irq number                         */
+    unsigned long              phys_base;              /* physical base address              */
+    void*                      virt_base;              /* virtual base address               */
+    
+    unsigned char              esi[ ESI_LEN ];         /* end system identifier              */
+
+    struct cp_monitor*         cp_monitor;             /* i960 monitor address               */
+    struct cp_queues*          cp_queues;              /* cp resident queues                 */
+    struct host_cmdq           host_cmdq;              /* host resident cmd queue            */
+    struct host_txq            host_txq;               /* host resident tx queue             */
+    struct host_rxq            host_rxq;               /* host resident rx queue             */
+                                                       /* host resident buffer supply queues */
+    struct host_bsq            host_bsq[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ];       
+
+    u32                        available_cell_rate;    /* remaining pseudo-CBR bw on link    */
+
+    int                        loop_mode;              /* S/UNI loopback mode                */
+
+    struct stats*              stats;                  /* last snapshot of the stats         */
+    
+    struct semaphore           rate_sf;                /* protects rate reservation ops      */
+    spinlock_t                 tx_lock;                /* protects tx ops                    */
+
+} fore200e_t;
+
+
+/* per-vcc data */
+
+typedef struct fore200e_vcc {
+    enum buffer_scheme scheme;        /* rx buffer scheme                   */
+    struct tpd_rate    rate;          /* tx rate control data               */
+    int                rx_min_pdu;    /* size of smallest PDU received      */
+    int                rx_max_pdu;    /* size of largest PDU received       */
+    int                tx_min_pdu;    /* size of smallest PDU transmitted   */
+    int                tx_max_pdu;    /* size of largest PDU transmitted    */
+} fore200e_vcc_t;
+
+
+
+/* 200E-series common memory layout */
+
+#define FORE200E_CP_MONITOR_OFFSET	0x00000400    /* i960 monitor interface */
+#define FORE200E_CP_QUEUES_OFFSET	0x00004d40    /* cp resident queues     */
+
+
+/* PCA-200E memory layout */
+
+#define PCA200E_IOSPACE_LENGTH	        0x00200000
+
+#define PCA200E_HCR_OFFSET		0x00100000    /* board control register */
+#define PCA200E_IMR_OFFSET		0x00100004    /* host IRQ mask register */
+#define PCA200E_PSR_OFFSET		0x00100008    /* PCI specific register  */
+
+
+/* PCA-200E host control register */
+
+#define PCA200E_HCR_RESET     (1<<0)    /* read / write */
+#define PCA200E_HCR_HOLD_LOCK (1<<1)    /* read / write */
+#define PCA200E_HCR_I960FAIL  (1<<2)    /* read         */
+#define PCA200E_HCR_INTRB     (1<<2)    /* write        */
+#define PCA200E_HCR_HOLD_ACK  (1<<3)    /* read         */
+#define PCA200E_HCR_INTRA     (1<<3)    /* write        */
+#define PCA200E_HCR_OUTFULL   (1<<4)    /* read         */
+#define PCA200E_HCR_CLRINTR   (1<<4)    /* write        */
+#define PCA200E_HCR_ESPHOLD   (1<<5)    /* read         */
+#define PCA200E_HCR_INFULL    (1<<6)    /* read         */
+#define PCA200E_HCR_TESTMODE  (1<<7)    /* read         */
+
+
+/* PCA-200E PCI bus interface regs (offsets in PCI config space) */
+
+#define PCA200E_PCI_LATENCY      0x40    /* maximum slave latenty            */
+#define PCA200E_PCI_MASTER_CTRL  0x41    /* master control                   */
+#define PCA200E_PCI_THRESHOLD    0x42    /* burst / continous req threshold  */
+
+/* PBI master control register */
+
+#define PCA200E_CTRL_DIS_CACHE_RD      (1<<0)    /* disable cache-line reads                         */
+#define PCA200E_CTRL_DIS_WRT_INVAL     (1<<1)    /* disable writes and invalidates                   */
+#define PCA200E_CTRL_2_CACHE_WRT_INVAL (1<<2)    /* require 2 cache-lines for writes and invalidates */
+#define PCA200E_CTRL_IGN_LAT_TIMER     (1<<3)    /* ignore the latency timer                         */
+#define PCA200E_CTRL_ENA_CONT_REQ_MODE (1<<4)    /* enable continuous request mode                   */
+#define PCA200E_CTRL_LARGE_PCI_BURSTS  (1<<5)    /* force large PCI bus bursts                       */
+#define PCA200E_CTRL_CONVERT_ENDIAN    (1<<6)    /* convert endianess of slave RAM accesses          */
+
+
+
+#define SBA200E_PROM_NAME  "FORE,sba-200e"    /* device name in openprom tree */
+
+
+/* size of SBA-200E registers */
+
+#define SBA200E_HCR_LENGTH        4
+#define SBA200E_BSR_LENGTH        4
+#define SBA200E_ISR_LENGTH        4
+#define SBA200E_RAM_LENGTH  0x40000
+
+
+/* SBA-200E SBUS burst transfer size register */
+
+#define SBA200E_BSR_BURST4   0x04
+#define SBA200E_BSR_BURST8   0x08
+#define SBA200E_BSR_BURST16  0x10
+
+
+/* SBA-200E host control register */
+
+#define SBA200E_HCR_RESET        (1<<0)    /* read / write (sticky) */
+#define SBA200E_HCR_HOLD_LOCK    (1<<1)    /* read / write (sticky) */
+#define SBA200E_HCR_I960FAIL     (1<<2)    /* read                  */
+#define SBA200E_HCR_I960SETINTR  (1<<2)    /* write                 */
+#define SBA200E_HCR_OUTFULL      (1<<3)    /* read                  */
+#define SBA200E_HCR_INTR_CLR     (1<<3)    /* write                 */
+#define SBA200E_HCR_INTR_ENA     (1<<4)    /* read / write (sticky) */
+#define SBA200E_HCR_ESPHOLD      (1<<5)    /* read                  */
+#define SBA200E_HCR_INFULL       (1<<6)    /* read                  */
+#define SBA200E_HCR_TESTMODE     (1<<7)    /* read                  */
+#define SBA200E_HCR_INTR_REQ     (1<<8)    /* read                  */
+
+#define SBA200E_HCR_STICKY       (SBA200E_HCR_RESET | SBA200E_HCR_HOLD_LOCK | SBA200E_HCR_INTR_ENA)
+
+
+#endif /* __KERNEL__ */
+#endif /* _FORE200E_H */
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/fore200e_firmware_copyright linux/drivers/atm/fore200e_firmware_copyright
--- v2.3.47/linux/drivers/atm/fore200e_firmware_copyright	Wed Dec 31 16:00:00 1969
+++ linux/drivers/atm/fore200e_firmware_copyright	Mon Feb 21 16:32:27 2000
@@ -0,0 +1,31 @@
+
+These microcode data are placed under the terms of the GNU General Public License. 
+
+We would prefer you not to distribute modified versions of it and not to ask
+for assembly or other microcode source.
+
+Copyright (c) 1995-2000 FORE Systems, Inc., as an unpublished work.  This 
+notice does not imply unrestricted or public access to these materials which
+are a trade secret of FORE Systems, Inc. or its subsidiaries or affiliates 
+(together referred to as "FORE"), and which may not be reproduced, used, sold 
+or transferred to any third party without FORE's prior written consent.  All
+rights reserved.
+
+U.S. Government Restricted Rights.  If you are licensing the Software on 
+behalf of the U.S. Government ("Government"), the following provisions apply
+to you.  If the software is supplied to the Department of Defense ("DoD"), it 
+is classified as "Commercial Computer Software" under paragraph 252.227-7014
+of the DoD Supplement to the Federal Acquisition Regulations ("DFARS") (or any 
+successor regulations) and the Government is acquiring only the license
+rights granted herein (the license rights customarily provided to non-Government 
+users).  If the Software is supplied to any unit or agency of the Government
+other than the DoD, it is classified as "Restricted Computer Software" and
+the Government's rights in the Software are defined in paragraph 52.227-19 of
+the Federal Acquisition Regulations ("FAR") (or any successor regulations) or,
+in the cases of NASA, in paragraph 18.52.227-86 of the NASA Supplement to the FAR 
+(or any successor regulations).
+
+FORE Systems is a registered trademark, and ForeRunner, ForeRunnerLE, and 
+ForeThought are trademarks of FORE Systems, Inc.  All other brands or product 
+names are trademarks or registered trademarks of their respective holders.
+
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/fore200e_mkfirm.c linux/drivers/atm/fore200e_mkfirm.c
--- v2.3.47/linux/drivers/atm/fore200e_mkfirm.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/atm/fore200e_mkfirm.c	Mon Feb 21 16:32:27 2000
@@ -0,0 +1,155 @@
+/*
+  $Id: fore200e_mkfirm.c,v 1.1 2000/02/21 16:04:32 davem Exp $
+
+  mkfirm.c: generates a C readable file from a binary firmware image
+
+  Christophe Lizzi (lizzi@{csti.fr, cnam.fr}), June 1999.
+  
+  This software may be used and distributed according to the terms
+  of the GNU General Public License, incorporated herein by reference.
+*/
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+char* default_basename = "pca200e"; /* was initially written for the PCA-200E firmware */
+char* default_infname  = "<stdin>";
+char* default_outfname = "<stdout>";
+
+char* progname;
+int   verbose  = 0;
+int   inkernel = 0;
+
+
+void usage(void)
+{
+    fprintf(stderr,
+	    "%s: [-v] [-k] [-b basename ] [-i firmware.bin] [-o firmware.c]\n",
+	    progname);
+    exit(-1);
+}
+
+
+int main(int argc, char** argv)
+{
+    time_t   now;
+    char*    infname  = NULL;
+    char*    outfname = NULL;
+    char*    basename = NULL;
+    FILE*    infile;
+    FILE*    outfile;
+    unsigned firmsize;
+    int      c;
+
+    progname = *(argv++);
+    
+    while (argc > 1) {
+        if ((*argv)[0] == '-') {
+            switch ((*argv)[1]) {
+	    case 'i':
+		if (argc-- < 3)
+		    usage();
+		infname = *(++argv);
+		break;
+	    case 'o':
+		if (argc-- < 3)
+		    usage();
+		outfname = *(++argv);
+		break;
+	    case 'b':
+		if (argc-- < 3)
+		    usage();
+		basename = *(++argv);
+		break;
+	    case 'v':
+		verbose = 1;
+		break;
+	    case 'k':
+		inkernel = 1;
+		break;
+	    default:
+		usage();
+            }
+	}
+	else {
+	    usage();
+	}
+	argc--;
+        argv++;
+    }
+    
+    if (infname != NULL) {
+	infile = fopen(infname, "r");
+	if (infile == NULL) {
+	    fprintf(stderr, "%s: can't open %s for reading\n",
+		    progname, infname);
+	    exit(-2);
+	}
+    }
+    else {
+	infile = stdin;
+	infname = default_infname;
+    }
+
+    if (outfname) {
+	outfile = fopen(outfname, "w");
+	if (outfile == NULL) {
+	    fprintf(stderr, "%s: can't open %s for writing\n",
+		    progname, outfname);
+	    exit(-3);
+	}
+    }
+    else {
+	outfile = stdout;
+	outfname = default_outfname;
+    }
+
+    if (basename == NULL)
+	basename = default_basename;
+
+    if (verbose) {
+	fprintf(stderr, "%s: input file = %s\n", progname, infname );
+	fprintf(stderr, "%s: output file = %s\n", progname, outfname );
+	fprintf(stderr, "%s: firmware basename = %s\n", progname, basename );
+    }
+
+    time(&now);
+    fprintf(outfile, "/*\n  generated by %s from %s on %s"
+	    "  DO NOT EDIT!\n*/\n\n",
+	    progname, infname, ctime(&now));
+
+    if (inkernel)
+	fprintf(outfile, "#include <linux/init.h>\n\n" );
+    
+    /* XXX force 32 bit alignment? */
+    fprintf(outfile, "const unsigned char%s %s_data[] = {\n", 
+	    inkernel ? " __initdata" : "", basename );
+    
+    c = getc(infile);
+    fprintf(outfile,"\t0x%02x", c);
+    firmsize = 1;
+    
+    while ((c = getc(infile)) >= 0) {
+	
+	if (firmsize++ % 8)
+	    fprintf(outfile,", 0x%02x", c);
+	else
+	    fprintf(outfile,",\n\t0x%02x", c);
+    }
+
+    fprintf(outfile, "\n};\n\n");
+
+    fprintf(outfile, "const unsigned int%s %s_size = %u;\n",
+	    inkernel ? " __initdata" : "", basename, firmsize );
+
+    if (infile != stdin)
+	fclose(infile);
+    if (outfile != stdout)
+	fclose(outfile);
+
+    if(verbose)
+	fprintf(stderr, "%s: firmware size = %u\n", progname, firmsize);
+
+    exit(0);
+}
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/iphase.c linux/drivers/atm/iphase.c
--- v2.3.47/linux/drivers/atm/iphase.c	Thu Feb 10 17:11:06 2000
+++ linux/drivers/atm/iphase.c	Mon Feb 21 16:32:27 2000
@@ -2359,7 +2359,7 @@
 	{  
 		printk(DEV_LABEL "(itf %d): can't enable memory (0x%x)\n",  
 		    dev->number,error);  
-		return error;  
+		return -EIO;  
 	}  
 	/*  
 	 * Delay at least 1us before doing any mem accesses (how 'bout 10?)  
@@ -2499,7 +2499,7 @@
                 printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory+"  
                     "master (0x%x)\n",dev->number, error);  
                 free_irq(iadev->irq, dev); 
-                return error;  
+                return -EIO;  
         }  
 	udelay(10);  
   
@@ -3074,7 +3074,7 @@
         {
             if (!skb)
                 printk(KERN_CRIT "null skb in ia_send\n");
-            dev_kfree_skb(skb);
+            else dev_kfree_skb(skb);
             return -EINVAL;
         }                         
         spin_lock_irqsave(&iadev->tx_lock, flags); 
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/pca200e.data linux/drivers/atm/pca200e.data
--- v2.3.47/linux/drivers/atm/pca200e.data	Wed Dec 31 16:00:00 1969
+++ linux/drivers/atm/pca200e.data	Mon Feb 21 16:32:27 2000
@@ -0,0 +1,850 @@
+:150000001F8B0808AB5A10380203706361323030652E62696E4D
+:150015007D00E43A0D7014D7796FA5BDE84EC86211A7333020EE
+:15002A00AD89C00A23EA83AA589C7E7C38D8152EB887477677D3
+:15003F0095C39C3DB2AB388CA324C4A509352BFBB085BBD0C73F
+:150054007210B903C92991CCD1B1C242255BCCD81EA5C34C6826
+:1500690006271AC6D36A3A31B976D4A9A683DB4B07BB38265C56
+:15007E00BFEFBDB7777BA7030B2733994C35737AFBBEF7BDEFE7
+:15009300EF7DDFF7BEF7769FFEEAD79F221221E1ED844C3E4677
+:1500A8007EA3BFF036F827CF8597C3AF0C7E920B16595BCE5AA8
+:1500BD00296B6483D83E9F7DBE8FF50BE74A0B45FB1F274FAA79
+:1500D200D82E2867139DF637FD937EF1D55FB0769FE8678BDAFB
+:1500E7007D9BD8885451515172FE27E4138E9FC9949CBFF026BC
+:1500FC00741DF83ECE59823FF23BF89346493F6B4F17C1B3A7CE
+:15011100B3B79C97D3275B5ABFEC3CF9579457703B3CBFEFD600
+:15012600FC38236CA91B5E347EDBFA67F7ED4397956EA4D3C5F4
+:15013B007CE6A567799EFFF5CFC4FF7BDF938BF83E83EDE59F02
+:15015000FEAC24BF8A3C3F2FF9FDFF933CF51EF2FFEC2FEBFA11
+:150165002341C38CBC5F4EAA265F5EAF04BC51F0059FD1419ED8
+:15017A00063493D465A2384E66A0171C30231F40AB5CB5646FC8
+:15018F005CBFB633DECCC614D2DAF622F15D3189EFEA3EE28B83
+:1501A4007D99F8DABE4D7C2418A438AF3129015D7507F1032EBA
+:1501B900E174827F46C82229AE2BC63A9D50E9253960EC005FCA
+:1501CE00F2EDFE0AF12A9D5EBD6A35F1B5AC441A49BAD94F22C6
+:1501E300DECB544F180D1A51FACD8C4A7C034B93DAFD6455A8F9
+:1501F8009AAC5AB74C9542EF11E23DB0946A0F1B0DA10BF0CC0C
+:15020D00F9A4A8097BCA1D751474A02FEC02593C75C9E870D176
+:15022200B8CF352EC3783C379E1C2893C98017C6A57B3CDD0E4D
+:15023700CE32426A9CB99F03FC2E81BF46AD0D06544FD0190B08
+:15024C00C0580B8E897EFDF490DE08FD652E9CFAE911DD5F24FE
+:15026100CF832469DAB1116BE0F3C437B686F8D275C437AC9220
+:150276000542BFF6CC0320B22AB7237E1F5B97A4E927A397490C
+:15028B0064C43AFF0CD8ACCE8886D37F632A7F4C16005E289CAF
+:1502A0003E491DDAFB083513C6B0A6B8E4929626F531E0877479
+:1502B50082E58C9E2503DDD45DC4777E3BF1051F253E09684E42
+:1502CA00C3BAC26825AC39F5225F6598EE23B366227C52ABFC3A
+:1502DF00BC2754E61BD1FFEBAE6DCDFE8D49AAEA38EE89A35A1B
+:1502F4009DF0DCF4254234681BBB09E98536033F2F3C5F835F24
+:15030900107E147E1AE8AA0406A36989DB63C95ADE9F9272EBA7
+:15031E00C17C6131AC4519193457028723BE118D0433D6F063E5
+:150333005C6E1C77EC2981FD118663B2FA3A455F8D11A2D66BC0
+:15034800AFE9B096E6D4A38454D70D004ECA8235541117C7A5F2
+:15035D002D26F8E4B07D3848BA956402FC7BF8EC956CB6B6D35F
+:1503720091EB21B280C218CAB04122B5957583D126189B7D88FF
+:15038700FB2BDA46560F52056C867C6CE85FF1135F19E0C948D1
+:15039C0023873342916798F3A6E45FA58C9021887DB9A8DF9307
+:1503B1002EECF7421F693AB054DE6F73F4FDF414E83A6B66B2C0
+:1503C6000B11C3BA0E45D0D1074E3318C92C24FE074FF267E847
+:1503DB00E03AE67193D635C40D9FD66A65B471CABA5AC66D9C17
+:1503F00081B68DE4F5200AEA316B3E3EF5F8D4CAF0C902BFBC6E
+:1504050003FD12ED00BE39F8E7C4E765F2A6F8BCC8083DA6B648
+:15041A00335DAAA0AFC4DEA66A6CDC8418EA26910FAD6A0821BE
+:15042F0012B4A9C269D1DDAC9DB05A98BD06B91D807702D6021B
+:15044400F02CA479BF88CD3D82BE3F92D49137C262E0EB5969BB
+:15045900D6AC8DA4F4A3A0EB808FEB8570E6F34897F9F77CE4C2
+:15046E0071E4E07C73F2C0FC256AC3208B2D5C834D43BA3F060F
+:15048300F39566B386103FC611E321E23D02F1168A79426C3DFD
+:15049800E159DA32AAA34C083FBA62DC2474847A94BF031D86A2
+:1504AD00ACE5EAEB969CDC4FF3F3216F03DE5414FD8ED3DA3050
+:1504C2005F5AC953795A804F2146D05612811C0DB6A0BC0E67DE
+:1504D7007C6E471FC3A5CFA04B06639EFA201E11FA182E7D3E53
+:1504EC009556913E89227D129F511FDBA5CF05970CF63CF54199
+:15050100BCE097B83EB64B9F4FA555A4CF60913E839F511F752A
+:1505160026AF4FCB4C5E0684CF471FC48B75737DF079C37C69B3
+:15052B0015E973BC489FE32E7DC231AFD997FEF15925301975DC
+:150540007CBC5E33F5D918F2E53E82FD69D1B745FF82E8237F22
+:15055500EC4FB07ED2A4626FD8C3F7363321FA29D11F14FD6938
+:15056A00D13F2EFA9D40678FFA1ACBD131181B507F88FBA8451E
+:15057F00E179507D8362EC4FC2734A7D8786D5D526CF431356CC
+:1505940010E6D51152BB2CE6690F243DED35694FBB17D6017487
+:1505A900B251C766F514A3D3037337AB67189D043C77A9E728AB
+:1505BE00CE3FCFE5A0C8B347ED17F9CDB09A812EE4A09AFBC861
+:1505D30005F3ECCE1F76B0B8059C6AD51342D87777BEC16093F7
+:1505E8002ED82B3BDF613094C9813DB7F3A50E87FE6A95AF1F58
+:1505FD00D259C69E53B447F047991EAA1FDDE8D0747091968332
+:15061200EBC88AB2D5095CA4FB07AA87ED030961D37494DB348F
+:15062700C27225D77D497EBF32958271CE6F8DA0D12CF612E37F
+:15063C00718ED32568206F3FDF874C7B477EAC4DD8310AE35B40
+:15065100C17E683B139EA3EA6178A6D65B4CA65926E72EF555F4
+:150666007A82D977D06A9A610E58F3D80D4F6BFDF4DDFAC37506
+:15067B00E7D67D672AA93DD881720C301B55C6E4D0860EB97506
+:150690007D5DFF3A0A636BD898CDE4AD4C7A42CBDE915B037587
+:1506A50087D7593056DDC1E5477B55429CDCF8B5DCFAAB15AFBD
+:1506BA00AE3B0263FFD3EE69AF8C5584FEF3FD0FDA90E6BFADE7
+:1506CF0030DB70FEBF9C186B43DC4BEFBFDE4682BD8C27C86F5A
+:1506E400B3BC185CC264063DED086BF730DA2418B655D6F63110
+:1506F900394850B53126EEFCD1AC2EBD1B83F83B6D56056C5662
+:15070E0027F079B3565739DFC3A2AC8D591AB48B37FD4097B6BD
+:150723007D4527CA41F38E00D6C48665887A30CEDA5E6BA09CE8
+:15073800EF7568CF8A7EC03FF80DC05F6B56078280AFB25C86D9
+:15074D00F863ACEDB32658DBC26CBEE04780FFEEB7017F9BB98C
+:15076200301001FCB0C5E54E5A0DD0BEC8D6618FD53893DFDBC0
+:15077700489D0A781A5B9B27616DFAD4435409C08E179C365B01
+:15078C00B86D2C5EB34E5BCDD0CEC0B98106CBBA25A29A87AEC7
+:1507A100676BD0977601BC4A7DCDC2BA15ED575E1DD7B78610CF
+:1507B6008FC715EE954F0A5CB4B78837139F9F079E8AEFA21E32
+:1507CB00DF9814679714AB9163E99F59FEBDE3263A704FFA4DF8
+:1507E0000BFAD400D9FCE1115DF1C541C7772D591DB7BA1C7929
+:1507F500D4BBCC1B9F701EC761BE22E4A1429EB736E6E5C1BDA9
+:15080A00EE92C09D74C933790B79222E79BA401EE8535A429E39
+:15081F00F3ABF2F23C2B785CC43812F24C0A799A5CF2E05E759D
+:15083400BFC0457F73E4C1E79BC91376C9B319E4813E4D9690D5
+:15084900A7D925CFE55F711E6D33B8A771799007CA73BC252F86
+:15085E000FEE3567392EE35506B935DE3E625D87B3AC9363DDC5
+:15087300675D387B325FEEC53DCA370CF1D064D2707F1F9E1BAD
+:15088800BCCC7732962CFCB60AF76B17AFD80C1694A4D6EBDAB7
+:15089D0047E58DFC1CEB75E1E10563311E21B6794C95704FA00C
+:1508B20031EEBF8BC93DD0270326EC0F8A54674771FCCEF0B040
+:1508C7007E67F81CD864D8EA401CC819480FE1811DBC76E5FDFE
+:1508DC00733A83FDD508D6AA24406D9DCF3FA75FCC66FD65D592
+:1508F100FDFAEE7BF332F5F0FDC225936D769033AD01550A3A24
+:15090600BCF12CBF86F184F305E007567C68E59EDB3FCCF1498D
+:15091B00D79F692B73E8803CC25E4CAEDA152370463A4A2DE42F
+:15093000AB34998BC0DE1BD01C0AA7C5715314ED0FC74F4B510E
+:150945005ED2BDC9319893001F18B3A2AE734B17D4E2CFA89EB1
+:15095A00D6B7245E6394E2F350520E95A6DD6079943780F65B70
+:15096F00507B1C857AE36D0B6B12491D8133EA88E6D41A72B92A
+:15098400A835607E52D421448C255D7548EE0F723FD656E84744
+:15099900CA3D28974DE33C4751AF90CFEB9603D61BE545BA8197
+:1509AE00906D2A44D446CA190BE550DE5F85B273DF637264CCC1
+:1509C300C15E487501388B928C8974B4ED9C4E8FD80F395D9B32
+:1509D800D9A7F6FDFD5482B3B6141B358F92514D3A30CEEA2EE8
+:1509ED003EC7B6108744E478BE6ECB98555F46FA54D0E77A23D8
+:150A0200FDE876AE1FE7932AE0C3EC226CC2EC98E676BC7347DE
+:150A1700DC0A446C361675F3A48267306C72595A4C85D9A5D310
+:150A2C006467AB60D0E4761AA00C1E19A6CFDE057584F27DAC4C
+:150A4100810A64F09F5845DD6B073896ACC05936324E1D3FC1D0
+:150A56001C843796C7485C2391FD168998CC2EAC0E807119F419
+:150A6B00A52D86899716E555719D1E5CABF77860FDA686D87D2E
+:150A8000881FD74839ABCBEADB34C06AE6FC196F49F9DC3367A7
+:150A9500FF9653FCBCE83E774E9DC198FD9433E7203F734E0EF2
+:150AAA00E7CE9BECEC19F9BEE5F8961C30A2634DFCFEA0D0B70D
+:150ABF00B82FA14CBDC23E6C6D4249E6574419B2081DA247F1E2
+:150AD400AE02FC0A7D81D9CC00FA74C84ADCC82E72F9336B3524
+:150AE90075186487D8A757CCC5B06FE37D56B5BAAAF912D674D6
+:150AFE0012F13EA3AE0D5D83985C9FF6B7B3DAEE31CEB713DA06
+:150B130045E420F33B90DB12700BE117C47D4058E0468A700568
+:150B2800DC42F87111EF0EFD1E316777D11C01B710DE2BE8F75C
+:150B3D000A5CA30857C02D84B709FA2B05FD06818B78F8BCDCC9
+:150B5200956F1A5D63F88C67293C4379C18FCAAB46C037862CF0
+:150B6700B497ACBCA2E37A07D5613B00F6AA091FED901553AFF3
+:150B7C00EDBFA257A9A7AC65C6076D814DFFADCBB131EB44D2FC
+:150B9100D3ED8D9966269B5D0C355EAB1CBB62393E5B09B92DA1
+:150BA6007D3DEB73C7C0B7A0CE95599D4AE7C4A388AF5C5E4121
+:150BBB001ACAA1213D513EACA16C353B1A2C279ED9DA634E30EB
+:150BD0002027A4DFC63C22E273C22A8E67F405C61362C61D27AE
+:150BE5002FDE11D7C365DC0F1591D33E2D4E5E82FD3B17230768
+:150BFA008634CC078AD84F31565642CAC2B3E0D3AC9E17310500
+:150C0F00F1F318F89BA8DF73B0FBC5B9E2E6B1D4226269A8F448
+:150C2400FD8D2B9E7ABEF0DBCFD57473E2296C3D2DEC7EBCF2E1
+:150C3900AE00DF13950DDEA802CFB7FA713CC25A35E0ECA52AC3
+:150C4E00D412F544A96ED2E3655F78CA23E0B4C678CA19C73BC6
+:150C63007A25DCF084ECD008279EA8719E37E5E1B9FD8ADDB182
+:150C78000DC0764CD423AADC4D73B519BFDF7C84EDF7B3589BA5
+:150C8D002978178F2324729206D4F666ACDF181C6C7FFDBEF62F
+:150CA2003F04FFB4091D3E8BEDE2C8A08EF7A1481361354A427E
+:150CB700BF0075C79CFD52F0EFBA09FFF58CFF80C9F2281DB6EB
+:150CCC00918E943ECEE946809780E173BA047D6A637DC3E9E326
+:150CE100FD30D41426ABD5A0BF066353F5B7AD57AB426111E732
+:150CF6002175793BD0A435CA01DD9101E36E51513FF72CF85916
+:150D0B00533FD0D6AB0F846AD4079A03EAAAD056276FA94F71C2
+:150D2000DA82A6E43B3E87AEF48FB786AD4E2F6F75EEA36584E2
+:150D3500837D8F64208743DE10F7CD8B56A7E5565C0F7627CD82
+:150D4A0071E811C84132E2404C200ECA9A85BA8E1AFB35425244
+:150D5F00980BCDECDF9F97C1AF71CF55D02E2C2EA660BF823D2D
+:150D74006135190E61FC6476BEDEE1BEA7FD9C787F107F84E908
+:150D89005860EF2C9930495D2A9AA76D08DAB6C1624F81FD644F
+:150D9E0072445B638C94A45D2168373E42BCEE7D285F5F65CC2D
+:150DB300E4D7B03E3172F5C9FCF381CDF301E856321F28AE3A51
+:150DC80028771E688C4A5BD641CD07B107B58A72379C210E6DFD
+:150DDD00D477415EF648712D0AAD1C4846132A3F977C1772DDE5
+:150DF200B1E4C7CDE4EA10BDF6B5FC7B8D3D5FFFDDFEA623C476
+:150E070037F149D60767196DF37D72BB73D787F76764B77176CD
+:150E1C0012DFEDED4E9E9D62ED24C612B4E9B319F6CE0FCEC553
+:150E310060A795E28EC5592B49ACD55EA03DFBA77C1F408D2F19
+:150E4600C19925111ED61AB1FD22D431CC768DCC76686BC46913
+:150E5B00025948755C5BFE89B05F4C62F603E3079A805E15C03F
+:150E70007F7E9F7C2F5BCFEDA2BE82166B17AC59900EF6BB59E8
+:150E85003D95F781473ED50706C49DFE70491F5072FB7DC6422E
+:150E9A009DC136B6B08D2D6C630BDBD8689B72C8E56E9F99AF8B
+:150EAF003DF1DD13D451C14A757F10CEF8BE3C6C2DC00E06535C
+:150EC40005B03F02D8D1E09803AB42582DC056042711C6EE3D4A
+:150ED900B87DDFFB18EC09763DFFF15CBBBEF730F18D7D8C764C
+:150EEE006DB877BE7ACD579F7809FF2813FE1105BE17B615CA1F
+:150F0300D922135F23C8E20159979490B511E67899AC4DF7DEFF
+:150F1800CE1ACC57DEDE12F2960B795F0759976C9BEBCF06FAC8
+:150F2D004B095F8E5DCBFACA408FC8B5B97AC4804EF81AEAE194
+:150F4200BFF7767DE976F4E929A18F2CF4F9F956E2EB84DF675D
+:150F5700E1BFF97F4127B5812A6A1365EFE620074AB029B701EC
+:150F6C001CFB32E934357C0E6AA60AD659AEEA96A26EFA5B76F9
+:150F8100970E79676B6C88BD2B8E7D53DCF73CC76A5433FD0D60
+:150F9600A89D643847E33B55DC9401EF62EC9455F5C419EBC295
+:150FAB00479C3601BAD9858639057D89F7BD631F15CA33267057
+:150FC000DF83B68B244DBFCAF9118DF3433EC8CFDE5DC86F3932
+:150FD500E0553D71CADA0AFC3441837EC4F9C5043FE87BDDF609
+:150FEA0054843DCD3FE1EFB8AF3E440AC61789F15D62FCBDA29D
+:150FFF00F11A31BE558C8F158D2F16E34D623CC1C63366D79E29
+:15101400FC793F0B3A5202FB37ECD5DEE52452707687BF81A5FC
+:15102900B646E14C41EA923BF0AC5963EC5F87EFF53591D70ED8
+:15103E002C9DD53AC22F873A5DF7E92F4C3CF113B4D573BB2F35
+:1510530075045DF0CBAFFEF57584B7EEF84987FBFE7DFA8D6F83
+:151068009D40F893FFF0E30EC2BE871834E3FFFC179BFC0163E8
+:15107D0047B297F8269F24BE3972BAEE17827F59B87FCB380E23
+:15109200F9167388548D39197231C24AECC74EAE81B351FBEE40
+:1510A7002DE2DE07700F6C19D52A638F065F811671F66EE7672C
+:1510BC003C1C73CE320C5644AF8EDFF7F1EF332E0FE8F683F8F2
+:1510D1001D01FB1640C47E8ADD2918BE51B6571056CB2419BE69
+:1510E6005F39CDEE52768B7B1784A9EA283B4BED71C18202D67F
+:1510FB00E7823509D8DE99FCB707866B1CED4B26086954472D8C
+:15111000370CBF436C2882554932692E84518A67BFD838550E10
+:151125008DEA2D3826F4C6EF6508BD9BD99D8AF91FDC58F453B2
+:15113A002F9B9FF345D18A7E649C4A07F09C0338ECFD3DE713EE
+:15114F005647E93EA827B19EC2F3EE65F0B7441FE9C6F74ED3D0
+:15116400397FE1B66DACE2760DA74FE6E40CA74FD3FE2DE3DA2C
+:151179006675DC72D37C79E98086FB33D28C15ECEFA3ECEE6226
+:15118E00AB80ED1132EE113206605F6732E27B2576864DE1DED8
+:1511A300CF6A05B6F78BB51C106B298B6F2998CDA06605DE16C5
+:1511B8007EFF9280338317CFA17866127A7845AB14B5176F64D1
+:1511CD000BEA546EDF93EC5E0EF76903F4C3332E3E3B30F2F086
+:1511E2005C58991BC6EAE794D509272B493C6F56381C6C66A124
+:1511F700DD6A33CCCE0143C8C160013B1AD89812E727389FC223
+:15120C009C5A03D60DD688B591717321D2A3A356297C52029F42
+:15122100E4F0DFE4F605183C5B7B9DCFF944FCBD20F4E4B19C55
+:1512360062758BE4E804CF57A514F3F7A03F3FFEF296FCB8034D
+:15124B007BA9044C7E782ECCE386B9623AE7DF22A69C7875C78E
+:15126000727F512C633B25C66E36C72831C7196BC4F68BF9B97C
+:151275009590BB8DBBC902278FA04D5E747C0E9EEBA7E37AAC39
+:15128A00687CC1E594CE69A4CC1648B68998A71B7CAC06F7016D
+:15129F0073733E27A17F605C38637DEE31F6ED1BA7C35A178D76
+:1512B400CE221A8E0DB80F7298510C037A2F38307F1E66948027
+:1512C900555617C250A7FD2E9D1D58BC04ACBCDA0D334CBB4EC1
+:1512DE0026E1D5C23EB08F60CEC0B8F483CF634D85DFE4B17ECD
+:1512F3002015AD75BD4B225584BD3342FFF533FF1D311D3FAFDB
+:151308003C84DF1BD87400BFB50BF35C568A8672DB34600CF7B2
+:15131D00176514F12C2D1717498AF91CF3E12ECC25D0C77907C1
+:1513320097A634461F7DC54F6829B8E2829B6EFC25A5E10AC018
+:151347007B9DEFDEEA788E75DB6BAB74137BF94BEBBAE0B20DCC
+:15135C0067E4D1BE83504BB03C301FBBFD1669A19EB75A03F3CC
+:1513710076E4FACCB40AD7D51679DED9AB793E2EB475613E2E11
+:15138600210BCCE1B2A44CD602ED85480F6ABE927628814F729C
+:15139B00F885F2ED75F91DC6AF543D37BE49F5DCF82EAB9E1BB7
+:1513B000CBA404EC15DFDCF8F654CF8D65B90886F847DC73F32E
+:1513C500EF3C2B79FD8531CEF706B469BD6BEF83D6D825BEDF9F
+:1513DA0020AEBD50291A935D63FEA231AF6B6C49D158956B6C58
+:1513EF00B922F611E52D4A1493CAEA307BCFC4BF63A4F41A6BD3
+:1514040007E9F532BEE765581B34A1A82072F5889E30C635FCEE
+:151419005676B13CA21F2B1FD78E854735AC55BE639CD3BC1730
+:15142E003FD0192E201F360E68CA5653AF81BC5CE97AFF8BDFE1
+:151443008FCAE638833F17AB0ACDB8D613DFFBFFD37DFC7B9AE7
+:1514580058EEDB1B80CFF0335F65F2D7CDCB92DFC4EF4EC4B7BF
+:15146D003313ECBB277E5F3EC1BF8D080E50FEBD0C1538830C25
+:15148200A7D7F57E03DF9F3F2BF84CCEE17347011FFE7DCD0460
+:15149700FB7ECAE1630B3E5D820FC719345551A725A13D119479
+:1514AC00BA2B0E8DE8FEF02AFD353C9FC4EE6E0BC42A425745A7
+:1514C1007C5D8ADD139A85672FD8BF5E8BEBD433DA5719F3B4AB
+:1514D600E33A292ABE8B033BBE097935297577A9A72C388AD66C
+:1514EB00C8CA5A88EB03B42E7CB0ED30665CA5DFC46F5D37FF53
+:151500003B9CEB22BFB41AD45F5ACEFBE836F58015560F5BFEA9
+:15151500F408FDBFF6BE3E3A8AEBCAF355AB5A6A498DA816ADA6
+:15152A0046C2209588708447715A422648964C43182F78306934
+:15153F00639CAD12C26EDB644C1C26A3DD61E7704E58BB255AC4
+:1515540020E10729D548462638B4B064E30938322B123C47248E
+:1515690062E275F02C61B48CC390C4269D19C626332456BC4A65
+:15157E0086CD38F4DEDFABAAEE9210FE9839B367FF58D5D1A9A8
+:15159300EA57EFE3BE7BEFBBEFDEF7EEBB657887B6D5087BF17D
+:1515A800081FA63A83A941B22B5F3491CE945E0EDF6E779BEBA1
+:1515BD00BF3ED0EC2E5FA1FD996EDA75A02C9E5157FCDBF00DF9
+:1515D200AF6E8D4C2B5F4CE523EA336693FA8A5DBE77C6F2D17B
+:1515E700E31818D5AD80254CEF6AD47623AC7673ACFB9A2CD1D0
+:1515FC00A6A93F37BD12FC228E7293F5B5C9B184594CF2CC8307
+:151611007DE9E8A0E98BF59AFED8A869EDDBB8F9F8A4CDC7F152
+:15162600297C9CE1DFB1214D71F16F51CCDB98E151EC1B61AFE5
+:15163B008478348FE466095BA45B7DABB6FA16196876F3735093
+:15165000ED364231F94E6BBFC1E0F0E51DF97BAC8FC45BA1DF9D
+:15166500AF6E60F987CA929AA22E16B459053AC0F5491D31629D
+:15167A00EA5123A26EE04A68756B1FE9A75864EF1B7F41737C57
+:15168F00777BEDF1DB6FF95B14BBFD285AA9BF3945A7743575DF
+:1516A4008C67CB1C31B9ED0FE7E415FB9AE349AD9878DC5D3E9C
+:1516B900AAF61A1BA87D8DE0D0D483F47FD56853AB8CED6A8D70
+:1516CE001157EB8D2EB5C930D45544BB477493FD595B754AEC79
+:1516E3009FB6F553FEA43A6A1C51B9D1F7EC515EC28EE97336A4
+:1516F8003DCB17BC759527367D92772E58CC776DAAE5BB9F6D89
+:15170D00E05D6FADE04F2F38CEB166F2B91FC0892426ECBAFDF3
+:15172200CF9EE2FED387F59EB7F6F262B677A91B2E3205F38BA3
+:15173700D455CD99B46807AF92587EB13B4D74A083F39BA4BF13
+:15174C0071217D43BA16EB3032FB606FDDF89E191DFCFD821912
+:15176100EA235E1B79279D5F953C6C88B1053FE0CB37DAD7F014
+:151776008388129F788B3A85AE7290F2BC1FCCFA9DF8A6FB9DCA
+:15178B0010AF1E14B65E3B7C7A4CE13F4D63DF4B32A32F49FA86
+:1517A0006CD3104F596B5EA6DF3A5F31A744D87D9326DEAB6A39
+:1517B500027BA94167BC63FD5E8B55124FE0EC483B8FBBDA56CD
+:1517CA0066F0C3F1C5A85D3127C44DEC57F6A9528B323AC0AF33
+:1517DF00D96D627F734A9BF4DE37ADCDE9FB071B5CED3357FB1F
+:1517F400EA0CEDCBAEF6E7CFD07ED5C76C1FFE3589863077601A
+:15180900010C3BE65830CCA7B6A6B7AF8CBE28DA526303A46BCC
+:15181E000CB732A5D384EF8F4CB67188DA9D1F1B309E5EF06B13
+:15183300E1D331E9F6F371EDCFAC7D2AEB3F22E52774A9ECA464
+:15184800BE7EACB3D1B78E0B5D46B92FA995EC18E1511F8B60C6
+:15185D007C96EC18E4317A866F01F21B296F0B337E6D62EF18A4
+:15187200699E6969D4D712C77F24188AB5865929DFD939B88DCC
+:15188700190F70F08FFA790234A4B5FACEEDA1F64EF292D096AF
+:15189C00D6B93B8EF208B5118C5B3A33F2083F10E3707FF1B807
+:1518B10021F67738C13277473D27B9DDD6B177ADF0F3098696FE
+:1518C600B576DCFB29FD3CE1E9B598E74ECFA5FF20CE4084AD8B
+:1518DB00730562BF0D739DBD9F2CF6434331A9B94059AFA36E52
+:1518F00094654A3397A5C37AA7381BF0B258170EC2C732BA3C2A
+:15190500B35621C717E9589F484C785A426F35F0D08A7B74362A
+:15191A003E6286562CB6FD5AC4BA96B557611C3597624F3D3A72
+:15192F0018BF4DDDB4043693D88735068633FFCA603C4875F9B3
+:15194400F32BF52BE974E08DE57AD3E34F7A9A1C5A5DA0BEB02D
+:15195900F0761BEEB69BC2EDB954A1CBA79337C21E5E6686ED09
+:15196E00F593E9F04346032FE883D59719FA30FE0D731DFA6039
+:151983003C175F29FA10113028D1B80EF80D35A70577C08F3B83
+:15199800F15EC92CCC25E37BF8E0EFD285428F540EC7C7976FC2
+:1519AD00AA1FA5BEADA2BE39EF77FCCE75D410FE24048BAFE8E2
+:1519C200A8E085B93B4EF00999C598B16838A00CEA993335F4F6
+:1519D7005B8D25E8FD31FE3EDEC37710FB414A3B6C06E386DFF9
+:1519EC006E7FA97D597EF71525048FB3FA041F233316FB9D6202
+:151A0100BF69D883FD6A137BBB57D3E950D6FF89C6CBBFB17C5F
+:151A1600625F767D5894CF961DB6FF8DCCFFB4F5E2B6988F27FD
+:151A2B0053DF3715E2733535305C1CDA4EF56CE1C154A5312B41
+:151A400095D3B22AB5D80884DA88DE63A2CE10CDC92CFAFBFC5E
+:151A55003519FBF21A87AF8EFCFA2384C752BE16FABD021FF809
+:151A6A00A8F0B5EA8DD7697F1EA96DBE47F5349FF75EE1A1C844
+:151A7F002797826E1BD2E9C249C9B193BA8D3CD02D2AEF32DA11
+:151A9400E013B89683D6C85743F9CEDAF9C2A91554EF6A739572
+:151AA900C573C38286F6BD26760FEF16FB8295246F5682A68619
+:151ABE0045C3A9F70E09EB8657787A391C7107881F3FAD4DE607
+:151AD30058F517F101FD41755663B13AABF6A5CA924673E18293
+:151AE800C657F18EE018BC9E2E5CA84A8D024E85F4B072A3D58F
+:151AFD00C7FAF9E51FA7F333E7F1C60F5B7B8DE387CD4365D585
+:151B12001AF58C63BFABD7AE9FCA37A32E8DEA72F23AF9B6524A
+:151B27009E7D6B06B45D34C6D0875B49E64D6F6BFB8FAD3D8A0C
+:151B3C00522AFFAA64C185737B5D180BE37163BE7F500FFE6E98
+:151B5100BF8101BE3AF5A2619DD34A3333F282D647F5CEF3D710
+:151B6600E8A42B97C0D7BC865DE189C837DB70F62E89B1BB66B3
+:151B7B00B16E12AD72D990EE25FEC7DE506364A89129CF59B491
+:151B9000B1F5378C6159F0994A70455A05FCCA73E69B3F4AE70C
+:151BA5001FF558FD5C49B46E9A81A6B751DBD3FB34F8A3B4D82E
+:151BBA0013443D5BEDF2F36252A3779C6440740FF7F8137A2424
+:151BCF00B59F375D4AE73B6573699CE02CDDA88D779CE714B2F2
+:151BE40080F0E0E4E9A777E2D9788AC77F98B6CE3F529E37DF4D
+:151BF9009F8A7BF0E04CB012FE4B4A53ED46FD050BE783D3CA28
+:151C0E008D02FFE07371566D0F77708D3371AB530326C73E7BDE
+:151C2300785ABF5957A6DF472F5AFD06ED515F1BD55763D34CAD
+:151C3800F0E6A0C59BF04B97D6FCBE1EA5F7B73AFC67D3C2C2FA
+:151C4D0063B60EEDA2056B1BF1C4C8BF583C31CF5FAF8706A432
+:151C6200468737B662BC5BE73B6DDE209D3F32A42D64279AC1E8
+:151C770017C18661C10F667CA1E6EB7E519769AE5C68F381E5DB
+:151C8C00F73A95EEA493FA42CA61E2F9765E447C116CAFD595EC
+:151CA100376C7C3BE3C15506F6D44CF8BE1DE39DF203E737B4A5
+:151CB60043E3E928D5E9F8D3E4BA78631BF186FAA6C51B12E1DB
+:151CCB0057B67963EDDF5AF8157B568493CBBFCDD20FF5CD8A7C
+:151CE0006ED1B59F7CA99E649C599D5A6356A5569824E74C9214
+:151CF50083C60CFB4DE21C33F4143FD901C2276E063F6FD2937B
+:151D0A00785E51B7DE06BF4CD2DFA09749F9033AF6B5BAEC73CC
+:151D1F000BF02D7B50F8330D0B5B4AF877E34C34D94F87CA4E3B
+:151D34006ACC1812BEDE4AB2D384BDBB2A794AE877F1E410782A
+:151D4900728EA2769AABD453A641F712E388FEAA6ABD67954398
+:151D5E00FCF24DF43FD8438150B4750FE66FA58A17939CAF263F
+:151D73003BE676F8E23B7633D96915DA55BD27B2BF0DF8F35FD4
+:151D8800C8DACDADEA7DE6DB3F93EE94957BF52A7505AF225DD7
+:151D9D00FE92EA6D0ED2FD5BF04514E36C0F2F3D9FCE7FAD5214
+:151DB2006E249BDC207BD698C78EDD15211B50B6694D76AC01A8
+:151DC70059D9E44A433E25146EA53ACD2ED5DFECF8589692BDD0
+:151DDC009BC72C3D0DBF8F52DDBB95A7DAA08F55CF618580CB48
+:151DF1006D67BA6DCCE80FAD71D029F257F36BC5AC9029EF99AF
+:151E0600412A0399E186C9E2BF7A7E3BCD0B800F7004D5970D68
+:151E1B00F4218F781FEBE76C7C31749E6068C5A774F41D7A90B7
+:151E3000F774834E6085AAA82E21038C1E1E559FE1AFCE26DABE
+:151E45002BC46754DE6907766090F41F4A33DD6DDE934E8B36D0
+:151E5A00855EA51C364748472B8FD9B22C6AC939D4D9361BEBFD
+:151E6F00F6614A3B2CE0F2B2BD7A0FE08AEE3121A71CBA396BC1
+:151E84001ED13740BBF704ED707E5C55498F573A877DEA1DA687
+:151E99007705E940D1BDA26EE8F5D0E9FDEAB366CD75A929AB9C
+:151EAE00CF583470F0EDA6C360C0F2BFBCD97B1E60856E7A0042
+:151EC3009EB1BFA139D2A117E495526526D6701D7AD4E49355C5
+:151ED800774DE7D7A87D9E2F9E7AC72C095D6CCD49922D7DFE54
+:151EED000A8D8D2FF00AED4FF425B16FF37D9D27DAC43E90ED91
+:151F0200971EA6BBB087B08608C28CC1C77DD80C8BB3DCDF30DF
+:151F1700E684CE50BB3F249952DAEA8B3D493AED72CC2B66C792
+:151F2C00BD0F918E7BBFD171EFBD7A774A024E857E9B87392E76
+:151F41001CB5F5DB2ECB2F8FC66CCCF6B31F16F76ADB0638627B
+:151F56008CDC073B2B4265B6087D3A2D7C44525C444EC819E394
+:151F6B00E1582D9F9DCC69093CBB9E074EB7E852F2040F40BFA2
+:151F8000879E7C1F7CD25F163EB87DEC9B1ACABD4FCA53DF677C
+:151F9500BF69EDA7517DFBD97734B6ED1847F4903EF66D0DBA40
+:151FAA0018E4771F7B4D832F2DE089920E87FC80E55689059E76
+:151FBF00227915185BA9DF4DFDF12B8FE8B2FA9C81BE3A7E50F6
+:151FD4002C7A9FD931EB5EE1039C4F3031638DD9C70632FE501A
+:151FE90028CFA2CF99AF125FFACE8DE86CA4D384FD04FA0FDB39
+:151FFE007BCC68ABE8524AEFCD7941E8F56BB1AE3C72CC1C63DA
+:15201300225F1CFA3CFCE2B0B78867D80758AF213917C7BC7364
+:15202800ADE27073B9EA69F49D233DBCFE18A7726DED852B5BE4
+:15203D00A05F930D5A124DBD635468DFD3674BCF0B9DD8E33F85
+:15205200A1236F09FC1BEA87903F7270672FCD457DC236050FD3
+:15206700887764234E923CF49D3BA8CF3BF79CCE2607054C382D
+:15207C00EF437C2564FC1FC6D6365978F986E13BFD72960F9219
+:15209100DE0C1F84C007842787F6BEC82ABDABCD63D111F4336D
+:1520A600BA4D879E4FB31735879E2CFA0D73103ABACD2B53F1A0
+:1520BB0067E1EDABAFFF9186337253717644E0ACA44DF848DBB0
+:1520D000381B06CE026CFC581CBEDAD79EBC7789A80FB6CCA84C
+:1520E5008533165D346CFD77F65B733B1B9E3B7A42E047AC7FA6
+:1520FA0019C7CC02E8C5935FE16F104B127F9414A53CCDC0ED45
+:15210F00E39E2796FE69CA736728E66976F30978C373E91DDDF8
+:1521240027BDA077AB599C04A78C0DCBF6035D2D7EB6C60AF085
+:1521390094E1F5E9769FBDEF6EAAEBEFF49DBBAAC367D9EAA701
+:15214E00C1710644E83FE1301778D9F669AB7FCA401C6BEB2D2E
+:15216300EA034BB0FFE1659D7A70C75745FFD8E6E778EFD81756
+:15217800493E7CD174D93BFDC2D6C19E36E18245474CA78E203C
+:15218D00D951852E5C8C117F2797AF6FBA7EDDC2C76FCA9FA8EE
+:1521A200DD40FA96859FBFD7EBA4273F003FDF27FC3CFFEF82DF
+:1521B7009F97809F7577E98E6D9E6661CE267F6EE1836CE6DE14
+:1521CC0038EC050B1F0BD8223DF8FE62818F9C68A95E1E2F6F3A
+:1521E100BE45CC71FB782CF5AEB9ED97B0974B5BE9D9807CB1CE
+:1521F600EC1FC21BFBE32C0F2A583310FF84BB0117EE5E369D99
+:15220B00F6A6E3AE9770B78D70F77736EE2E12EED07EC8D5FE2D
+:15222000B55F586D4F6DF7056D5FFE505666DC5C56CC71C98A24
+:15223500A64C3EEBEC74667C2CC4BAEEBAE7333244D8E7E3545F
+:15224A002E3EA44D2EF70AD8204B204722A4E3418E604D0A67B3
+:15225F002050EEE9944B9EE4BCA461FF0FE736F05EBCB3E449EC
+:15227400896FDD4BFA016A5BC8946D4362CC627D0A7D2E76F53C
+:1522890059A63EBB65CD74FFA551F8E6285C2FBA64E801D20F34
+:15229E00FA9232F547354EDE27F4CA906B8F8C063EE99034B72D
+:1522B3000357276DFE4079DF42962F8FEFD495F33BB5A9FEFC1E
+:1522C80086B0357697F56B42B7945917703526D65C86E20BB10B
+:1522DD00A743632327752C2EA74EC47D7ED27308BF05F1A1C669
+:1522F200E2A841F301E73D29B94556137CAEF217382B182AC2CA
+:1523070019BA0C4C5161776CC799BBF2D5ADD0B1587958D821CF
+:15231C00D095271EB07C67AFE15EBE8CE6DDDF3F207CF7C2EA17
+:15233100F1D40333FB731B87B07ED12FD62F76931E5C34D629A3
+:15234600D609D8B89C301A8E58B04787E245F06FB4D33DB1A12D
+:15235B00B8D2302CFAD7C3F66A384FE85B47F3883104BD08739A
+:152370008C41735BA67FC591C146A7ACB58F9B79BE019E6B8741
+:15238500B2EB31BBCB86B5A2B80D8F711378285D215B1AB0B83F
+:15239A00DB94ACFD988ECC5A8DBD3F8FBD68567ED2DAF7B4FD65
+:1523AF00110977167EACB5F4A978543A0F4CF12FA27110BF1F74
+:1523C4007D305A31164897E928B77CA2E21D94DE1B4D6ABE22CE
+:1523D9004B2F4B114C5772E258F32AC4FBE87ACB96C1DAC1428D
+:1523EE00DB8F6AB5E09123F1FBE89D03BB809BF26BEBC51EA3A5
+:15240300D8075C6BE7D35DF956A45EE8A0FF38D28DF558CFF983
+:15241800761CF31EFA82FD4FC0D1BB73480B8ED9F050BAD3EE10
+:15242D0016BBBE9E19DAED77B5BBD5CEF78C2BDF4A6A17F99220
+:15244200AE7C6D76BE8119E05B99FA661C67108E0818BF1BC70A
+:152457001ED815824521F89E16BC734CF8CDF47E8F6065D6BA3B
+:15246C00E01517ACDBECBA5F9C01D661170CDBED7C2FCF00EB9F
+:152481004957BE1D76BE573E0056D0D881F5EA87C07AD5056B9E
+:15249600CAAEBBFDFE1B61EDBA3F0BC3653B5FF7FD37A1E7FD24
+:1524AB00597A5EBE093D2FBBDABDE2D0738676FB5DED5E75E845
+:1524C000799376B76CC0F81A050E8C0977BBE8AFBD7E8F74875A
+:1524D500E71FA7FCFBD95086E737782D9E7F5FB2783EB621DB46
+:1524EA0076D46BB5FDF0860F681BFBA576BB4E7B93AE7E6EB0F7
+:1524FF00EBF8E2CC751818B38E6FCEB5E9328FE4CBE5C1ACBCF8
+:1525140013E359ACCD22E69421FC099832624057F1F93BF5DD6E
+:152529006586A6D0FCA0AC3DA597F213FA3E9A12DC32E809EAA9
+:15253E00D74CB2C729179286B4FDA437825F2CFFC7BD644B24A5
+:152553003BE0EFBD52D4959D1BEAA82E0FCD0B19B94A7A896F04
+:15256800DD9090A9429E3AF3451CF27448C853650DC14F725439
+:15257D00723D4F9D8FB0DFDBAF4965869EC61A18F6DAADB37498
+:15259200F6DC346CB56FD8F234DA678A35D5F121C3EACBA0069B
+:1525A7007F17EC0B189897C85E99ABBCA2FB48E7C6DC34E37C24
+:1525BC0032945D0FC73A1CF6944270D7856FBEFD9BE6F339D379
+:1525D100D7C2AD75DCA3864CF348A0419C756301E917FA933497
+:1525E600B72D10BAC911331264D1D7688EF6150D0A9F0E2B1601
+:1525FB0058B5D807DA5DA66AAC7E2F6F13FB0B3D64EF579AE254
+:152610004CDCFFEDFFC3BD1C30B36DEFF238D159C0EE7ABF99F3
+:15262500F4B6E5F4FECBEC1F9722C609FAB0ABEC88735E5915B9
+:15263A007D237D48F44321BBE2E3FE0FF4F29215EFEAD9B4A1AD
+:15264F00E175B1F412A7AD0ACDB2D53F4A5BF1E48D7535C6BE43
+:152664002BEA8A7E40F918952B5D33B5DCEDB18796587433CC8C
+:15267900D5A09B5D2E4C79FDD3F2D6C52AECBC2A17FB43365DAB
+:15268E006591AFC75C3061C77B237CE26C5D5D2CAF51ECBDC060
+:1526A3007F53E44F7092F13109F989A7113746B6E2C319880F2E
+:1526B80027CE3F132F89B399E383A67B3FA9F5886B3F087BA603
+:1526CD00DB388F603F272A6C1B71BE5251E0FF613FAB3807990B
+:1526E200DD0FEA75955F18931B9D3D21D421AFE17A8F589B1E44
+:1526F7001C9E74EDA33AECEF63A3F96FC977E57CD9F39EF47519
+:15270C00E951E9335250BAC6FE8EFD35FB2E7B990DB1AF319314
+:1527210075B30EB683FD2929DA5F628FB147D9436C23D3D8036A
+:152736006C3DFB1CBB97FD015BCDEE66ABD84AB6822D67CDACF0
+:15274B008935B206B68C2D6577B07AB684D5B15A16669F66B73C
+:15276000B34FB11ABA7E8FDDC616D355CD3E49D7AD6C115D55E8
+:15277500747D82AE857455D2A5D25521AE72BA16886BBEB86E5A
+:15278A0011D73CFB2A1357A97DCDCD5C21FB2AC95C41D735C7EC
+:15279F0075154FB902D32EE5866BF60D57D18CD7AC9B5EFE0F7A
+:1527B400BC0A3FF42AF8C857FE875E3E26CE181FB7D6B754E111
+:1527C9008B4EBA3DE9F151A61E475A15A519F673353D8FDBCFB4
+:1527DE0035F4AC48F48C35BEF26ACA1FE1065BCDC7C95E5024A0
+:1527F3008D2BEAC2E34A8CFE93F49F5A785C8C2BB11E522DF667
+:15280800DB55D54ECBB7D3244A8BD96905769A87D292765AA167
+:15281D009D964369A88FDA14B02B2C1AB6EB825F60D8AE037E98
+:152832008061BB2CFCFEC254262AC16651F9F04B5828BD8D33C0
+:1528470075E1016F6899A8272AE2EED41AC549A9CE776631CD9E
+:15285C006B95077C671A843C887FC0BBE10F78073F38BC2BA2B2
+:1528710077946E225D7EBD41176D8F2F361DDC3938473FC66D43
+:15288600189561411343153E7661037E200CFD1465C2ADC02FED
+:15289B0070A878ACFCA96FDBEF99CA9BD485A661D7C35EB1D235
+:1528B000A3942F8A754A65A129FBC8A6BFC93D2A65F38CBB9EA0
+:1528C500154FF6D9B0D345FD63E9D988ED64F947AA7C42ACE7CD
+:1528DA00A8563C48B12EAA8A5891B9F6B3F043F310AF617D2323
+:1528EF00BC8C477FE16109CF32332FA4B6CA91067DA2B241C487
+:15290400A998F8AEF70EE004BFE12B3046E5FC6C19CEE49A35C6
+:15291900840B529EB84FAD33F3D86D04FB6DA63714691D9F2168
+:15292E004D91AC34A6BE67C2BEAACE99AE9FA98648037FD3FD64
+:152943004155AA9389664ABCBD4E86FF8C5209F9ED634A2D354B
+:15295800B9CCA81171196A4DA6002E55C012F594521B8B0DB4AE
+:15296D002F9F29D595F8E27ADC7DF1C575B847D1D7F1B090F94B
+:15298200C82BF818F29DF489B81813CB7844F8D946901E4BCFE8
+:152997005E4D79A2464CAC776BF659FC188F88B5932DD699FCEB
+:1529AC00709B75469E6DB7E3F076D9677810F764360195205DD9
+:1529C1002461182CA141FFC1EFF796CB77B0F10EC3AFCA752C4C
+:1529D600BAD39844BFC655C35A07B2CE2DD7A472EA449D549F2D
+:1529EB00386783E768AFD15516D72431FFF59A9973E3D1FFDE24
+:152A00008FFECD579F3664F575D21913464495EF78E9A197A820
+:152A1500FED7FA918EB41A4A3B302DAD94D2764D4BDBB69CE0E0
+:152A2A0052DEEEFFF243EFD49262C6FDEA25633B3BC3E7AF7812
+:152A3F00476FA9F869EDD7965DB17DA5E362BD6D41FC027C739B
+:152A5400845EB160C5395D4E0E1A9EF223ADAAFAAD7E664C9A2E
+:152A6900BEAE5EA193637EF68DF52D0D618EA47698F10DF3161F
+:152A7E00E91D1D7828603FAD1D7EE8974B0906A2E92582EB9C07
+:152A930021F17DFAD736BDCD6F89D05CACEC330967F1EBCB57B1
+:152AA800D5FABAA9BDE8CE617624176BE5C33E1F7483DD077C9B
+:152ABD00ABDFA1F4FD07ACDF2FD8BFBF7DE00CCDB7C9EBD3C29B
+:152AD20060477FD89FF09C3180B7ED6C8CC7BF935BF7C413B97E
+:152AE70075581F3830FE356DDEF9FD5ACEB937F4BBD985DA799A
+:152AFC0063A774C41685FE62AD2F8E8BBE96287FAE4F3E7CC918
+:152B11009C27BD46EF2F98BEF8B1A5D88342DD130F9F337CC974
+:152B2600DCBA912773EF10671887451C98E3090FD90CCA090325
+:152B3B007DF9EDA1CEFAD069AA5BF9078EFE28803BFABD611FD5
+:152B5000620529BB8F2B02FEEF1F7F9BC66081BAB70B6BB57987
+:152B65006A67BC27CE3589F49389CA1F1AD05192A4777CD58762
+:152B7A00F83ABC6BA2F2D726E5DDF34BB5E68E28E5DF115B5586
+:152B8F0007BB4A8C2DE59821279F2519E9AD8B8D1DAD63C60920
+:152BA4006302BC47EF317ED653BA9C3C46FCD3297C13ABEDD81E
+:152BB9006D62AC197BC53E47B5186706F725F7D2388B73996858
+:152BCE00AB305E8FBB8FF13ADC113FCA97ECA33AC68C36EC2BC0
+:152BE300261386E4231C85C74CFC061F627C9CF92EDE0D923EE6
+:152BF800493A7F3261DE16E7227D8CD2F11BFBC81395DCF0C751
+:152C0D00E4BA00E96B1827139583E63CB22746AF7BEF205C9AE6
+:152C220067DE4FFB1482A789DAB8807115EEE71324839BA85E80
+:152C3700963C68BE91F1E7EE32FC8481300177A193D733E374C9
+:152C4C00BFF0632179D61D39A7FDE51772EBFA59A7D61FEFD3ED
+:152C61007E5925DFD14FF6DADC44AFDEB3936B3D0D17C55EB4FD
+:152C7600927ABAFFB645E59F11BA5B383E8C9824810509C4C806
+:152C8B0032E627459FAC182F3EE8A37111C3A55AC6DEFBDB8611
+:152CA000B41AF18A5F357BC6B806FF415FF22095DB0D3C8B58F6
+:152CB50057A5A9A7CDF9A9AF9BD5849BF9D4D7642EF634778BAF
+:152CCA00F159ADEE16BEF1A20E85236E9FAF54FDAA217CF63673
+:152CDF00714EE50CC806393662D4A7BE437977D358E9A579EE05
+:152CF400A08E3A3D6787442CE5B6BF60AC0CF62FD980885722D7
+:152D0900AFDBA5539F0E78D6EDD3B7E4B1A9E3631CB16EBAF850
+:152D1E0057DE92BFFFB424E82262000553F033EA177E46C029AE
+:152D3300E2FE045942AC5F8A78669FB77CBF906E8EF56AA5A9CF
+:152D48005DFDE1D4F3496505D77DA403E7ACE5BAAC72D3EF4371
+:152D5D008CB783BC3AD2B714EBBE25EDC43FEA102F8DE3F709B1
+:152D72003364FF464C0D4BEE937D9AF2D7210DEBC2BE8CFF7CCB
+:152D8700BF8881E3016EC67B8D2A4107EB8CA2447637CEE55AC6
+:152D9C006713AD3DBD37A92E896000ED413FA9EB981E5AD069C0
+:152DB100EE8F58E7DA104346FA032EF47445D0D1107E6A8AE003
+:152DC600EBE78E5F1636449788B723A748868D4F0A3C07C84604
+:152DDB00F60B1F837E116FC72362565BBE6BCC78CA443C46C088
+:152DF00029A5BEC2AB539FA875CB76C874D04FC8F58C4C27F975
+:152E0500BE25B72598FA8D29E22C1E07FFED32F7FC2E5D520F81
+:152E1A003F3B9B06C07130B5CFF0F05E3DD068C5BCF3906C4040
+:152E2F00DC763FEB5DE2271E99C77A6B41BFAD2EDEDC6AD1C9B0
+:152E4400D88E7BF99556C15B4437FC96C5B982B888E3047A8367
+:152E5900BE22361FC632D1733A2D6551D6A2C387E1F623D3083F
+:152E6E003470E3DEA1C7C7A04181A041BF1DE7284B8B0FA58182
+:152E83006B6E75F03FF62DC4A72C0ABB69511CFB64ADB04BA3BE
+:152E9800EDC3D79EFCE452259647F368BB01DB13B28A7F25B730
+:152EAD00EEE2BF38F2C79217A544ABE205DC94A84FA01DFA68E6
+:152EC200C53AB2DA407BA83B130F23A31F59F42873D1628780A9
+:152ED700A7CB3AB740EF11574B49ED33253521F808BF35D77979
+:152EEC00E0A0AB7CF0F399F8E022AE783F1B12FB163ED0BC7DCA
+:152F010048F3AB5E218B15F007C99EB288257B32E38EFA2C6D48
+:152F1600C1FC4BF735E7040E689C06FB7F6BF53735EDB313D89E
+:152F2B00A3290D75B596D1DCAFB2E4F1301B3B1E61A9E3D72E7F
+:152F4000A4F3E93E4CBF87297D58B3CBDF2CFF9137A7E6AFB6EC
+:152F5500F3631E1FFD8DDBFF14F32C8BBACB8AB8C362CF8D1B4F
+:152F6A00D79F94EF6882BF8B3A1AFFEA99535A2E9917B2DADB5D
+:152F7F0085B84805EAAB5D38FF68F9838F8933508A3A42764A45
+:152F9400C2F0A716D5C97F93CE071ECE5E4AE74FAFD30D9B3808
+:152FA9003B48659BD4678CC99F71D2890C1173C9E2C33F330520
+:152FBE00EF5AB19D267A483FAC233DE8E3F0E6C4CF7A8D84A7CE
+:152FD300CB6047E496899F7133E1E9379BD41EF337D7313EE251
+:152FE800B62DD26E5E86EE13361CBDD48AEB6E1C34A0034B3494
+:152FFD006E003BFD3677FC17D2FBC25113FAAE83B39387B2F8C4
+:153012006EFD7516BFF3110B22544A7A79BB7196E0DECE629CE6
+:15302700A5C2FDD88FF2A7AA8DDCD3B5FAB7E28B6B3B972D9B72
+:15303C00A22BE631F8892E13FA539EF428C98F35869A8AF63372
+:15305100E557A6CF57A9C3D7D4D213172E2D205BC453AE8936F5
+:15306600105F167AB6B7BD562F8AD4D617509B472BEE5C3A3F3C
+:15307B00A5D25C576D94A6C286E46FD43B9FADE5DE31B2FBC612
+:153090009799CE1E37621B0A5D5D6927FDB1AA56C65E6AF49146
+:1530A50061663C7CC0D785F301FF49DC53CB3D7764D7834AED9C
+:1530BA00B882D5B69C0A939C5AA6414F9FA74A61118F54C869C1
+:1530CF00B241A83FB22B2695357F3E3F5C3676502FB3D7338382
+:1530E400340F63BE65E3AF9801E9B25E5759F419567EA695B16D
+:1530F9002B5C61FFB03428BDABEF53BD75D005C32413E74B43AF
+:15310E007A49E864AB2FF20F4BE6D3DD73AE4FF8AD601D6FEEF2
+:153123000AC4C23B69FBC7C4F9159AD78BE327F4C07CD24B94E8
+:153138008EE18FFA3F97746FDCFB97E7D517C7F2C82679C5604B
+:15314D00A9E78FBF41E3687EEA6903B24AC411A0FE07683EBE55
+:153162005AD6BB2442BA0CE69B07BC86D05F7EFC0CAF75749694
+:15317700ABBF4BDF546719FEDFE99BEA2CCB6EA6B344DFE129A5
+:15318C00E7FC27640CE1CA57F985A505620F0F783BB53478FAFC
+:1531A1001754FF29BE9E70B77F99E19CA917780AC54732780A6C
+:1531B600A516D5FAAE604FB963587EFD14E473685E6A562DFD13
+:1531CB00368A5325E25E905A20EE06C9F199FA4FF369BD67F568
+:1531E000BBFAE56B691FF080BED6D87D9F78DFEAFBFC19FA8E7C
+:1531F50032C3D73E7EFF1710DD4B2147A33DFD6DBF9966BF5070
+:15320A001FC55AAA8B9E6BDD79A27DC63DAC9F6F201D3DF78709
+:15321F00BD4B54F5345920295E2C91DEA55C3083365FCA381F10
+:15323400A4FCC4DCCE2EF280745587DCBB65C5BB7A78EC3BF5FD
+:15324900B73458F8BC85BD63F975517BB7C05E095F143805CF3D
+:15325E00C1BF133EA2E5296F9D9367EEE94B19BCCFA5B28ADA53
+:15327300DE1F2F4CB420EF56ECE54447FA117B31E7CC29BC3BCF
+:15328800E0397B4A37D26427D1FB6AF50B4B71073C93CBF3EE4B
+:15329D00D8F6D04F491FFC89E1535F3E50A3FEC85C3669F73195
+:1532B200BA6BD88FF8AAC9F5DC7A86ADB46BF8CA72ABFC49C28D
+:1532C7005BD0AEEBDAF2C796DECE5EA813B68E2B2FCAA20E77B1
+:1532DC00B9B394A7E3A90B5A58FD8F4B908EF99154E5CFE1F98C
+:1532F10019CC91D15D49E89F285B803D65C225BE1F33BFE7B062
+:15330600C0EB3C957402BBFEA229CF736B3DD6737F813ABB967E
+:15331B00EE86A7C8D2CB51BFE7EB7B74A1037C876405E9576696
+:15333000E4794D8924F4529A3B443C16C53A83F361FF34A7745C
+:15334500495DEB75F8193265A7987794129A3FEC7947CC41785F
+:15335A00F731E61F67EEB1E7A119E71FCC3D9883EAC599FBCC51
+:15336F005CC3D5316BAEB1DA5159A9FA2B730E74099A977C6AF3
+:15338400B7B9E5BDB4AF20C9BB0A08EEFA48A2CEB1FF4A691EE8
+:15339900439ED5EF39F4EE349AEA2CBB716254BC37F03E4CF834
+:1533AE00417996BC6C486557881F39D98D5D3C37998817533BB2
+:1533C3004A72A41F632E27758AA34EF01A78AE5AFDD901F0D4A9
+:1533D800C5F71DFDCC8699607DA3E7591AC3EDC6D65F58F3BB94
+:1533ED005897A5B6467F951D5F8190E5EFE1B3CF1924432C9F18
+:1534020074CFFC2B01EB77DCCBF23748AC707B0ECBC77986F8A2
+:15341700D8D46F3B4DFC2D4D4C1711129DBA46FF6DF46FD0FFC6
+:15342C0030FD8FD3FF04FD2B3FA2F73FB2F28ABD83A0EAC46896
+:15344100E467C7F0E1884A1DB1F06F555B97B0FA5F755EA47C51
+:1534560015FDCF100EAE926CBE6AB2FA761EFB4B7B9DAD7E8045
+:15346B0027E9B947F5B62834AEC7DE465F470DC4BC14E73EEA46
+:15348000BB39DAA977F43BCA1FA7FCB7B2BDCDE299DA539A5FFA
+:15349500340CF4433961C0BF36B4E298CE627B39DEA3EC7EF867
+:1534AA0063217634D5592CEA7C45B429621B7D601DC77851E412
+:1534BF005433F2A3CDB9A11BFDA9597082F7B2ECFEADF0DF0892
+:1534D40066CFECBF799A1AA43993D59FE216AEE1DB316CF5B34B
+:1534E9007E888B36C73B0DAC81948C1DD3156AB7247E54878F79
+:1534FE009EAC4E4DC31A888FD202E35D7ACF84A7C5FDCE47EF92
+:1535130042CA7FD3FD64878E601FD4D97725F8FCCC155F697AF0
+:153528000CA57FE37B9C131A0922364775EB55BA7B953A1D3188
+:15353D0072FDB14A3397CA5C0BB142F9BFB61B56BC617917D2C3
+:153552000629CD1F1BA03967917E71B9749757E9D0C7290DF1AC
+:153567004BBB903F5669E07C8D8A73A29426C706CC61A4D3B355
+:15357C00417C7B9164217CFC6BE63271C68307B23609CE1C5FF6
+:15359100F558F1B2B6219DE007C079471077F45DAE9C7F464330
+:1535A6003F4AE11BA48C709FFF98BE8E6CB339AADC92973A2800
+:1535BB00E2B610FCC5A114F2EFED90BA7B853F27CE18DE966C99
+:1535D0005AA2F82D5F0BC466982DEA1C3AE0A33C3E2B4FB034D1
+:1535E500292F918EDC589645F304DE0C9AF7AAE658DF8082FF11
+:1535FA00BDC3E7E373E0979EC8F887C9EAA4D95A427822B92460
+:15360F00137EA2F4CC66F0E72F25BC5BDF3CF96B737BEA6F0F36
+:15362400C897DAF5CBC553EBC7F744DAECFABDA1B156CA6B50E9
+:15363900DE7ED4B58764E75A196B3AED343E2254FF6AEE53F13D
+:15364E001C6D853FB7447A2EE9C2A65FD5CDB504838C33722494
+:15366300A7F17D95F96A3B87DCDC537646C37AECAAD43F13CFF4
+:15367800FEC05C4DF724F1C25ABAAF4E7DA61FB410FEE76AEDB5
+:15368D00011FD5514FF59706587E581DE0169C5FE8079C388F73
+:1536A200BD92F475D8309EF258EB9EB2360DF23E42EDC4A82EF4
+:1536B700CA773C4AF7CDF41FA1FA733167184D7C436AB919A3B7
+:1536CC0076A2A9FDFD38F3B09ADA89AA3D070E521E8DDA3AAA9F
+:1536E100D8676C4987403B84C0923D6549AD551D306304D7662A
+:1536F600AA7F82F07335C00A7D54E632DD714E9EF8CFBC46CFF7
+:15370B00ABA88E8900CE1924F8167A7E35007E575BDFA4FB6AE1
+:153720004A93296D989EFD418B46D371ECA697F7525CDF4C7926
+:153735008B55B939C745CFB03A48B8867F31F68427699C0F9A63
+:15374A008A4A73DA349A875F9B2AAFE12FA284734806776564EA
+:15375F00301C123057DF4DD38107E71CB78D7051CE386594ECF6
+:1537740018B4E4DCB663960C8AEE35E0D33217320A6B58888D3C
+:1537890019957765DADD3669CBEF1E9249581B3C684A65713D24
+:15379E00E37F4678A0692F9FE62E23389BE5E3AC06D9408DFDF8
+:1537B30012CB273E32A89F8D7E1AC705EA82CFACCA63F9F3E96C
+:1537C80019DF929195DDFA28F169BFC20ABFCCAA1A494008FC7C
+:1537DD003E42CF09C5C26B39AB6A8EDA721FB240C04675602E4B
+:1537F20088501E12E685CBE8AE282FEA997874341F5FA8686FF7
+:1538070084CFA788BD46F7ABCBBDCD0AE5DB5A7CE31872C60954
+:15381C00F6CC300E2798F50D3C278F9FF860A7FD9DBA72D5DBD0
+:153831005C4DF5E4975F213A1D9A820B85FA73167CA3DC26CE74
+:15384600D0EC8AE13B033DC613915ED1FFFC4FD3FC46F800FFDC
+:15385B002D25B4416F7FB508E30EFD7AD1C01CD1C83A455EA932
+:153870002CAC77E663AD63C0AC72FAA5741B32E916D5E0BD40AC
+:1538850017740503FE7E0AD581323EF5457AFF2B33BFC82AC7C6
+:15389A0094174DE0783BE5CF75CD5B6AD1D4F59B6B45AC3048CA
+:1538AF0079268AC0F35546428C936A314EE0DF0499FBE6F5749D
+:1538C4003EFC750AE289466FB45A57D54AE3CA72A97994CAD023
+:1538D900382EF4BAEA2FB6CFD665ED55D598781B01B576EAA8ED
+:1538EE005B39FF7B22D6307CB5B09624931C95A9BE2292F7E8B6
+:15390300C7C44303F50FD2337CAD64711EC8D603E0E3F536F634
+:15391800F82CF8E5D810C9A4170D712EDDD255D3C53407E3FBCC
+:15392D0055B2FA8C69CB9300BE0D09F926C33FC2FEFEC424D5C1
+:15394200F3E318F1606CC85E334EA7FF6A6CB0D14FBF713687E5
+:1539570045DBF9F642969F5B4934B4EBFE2DF5DDE90BD67050D7
+:15396C008785AB230257F0FB0DB1458D4E7F0AA80F93158B9A3D
+:1539810071CE7372162BACB8981D3F326414D96517C986FC2802
+:15399600FDC4FE9B809FF409C0E21D233B3B3A4A750D4057248D
+:1539AB003C7467FC45BC946FB480E5DFA30276AB6F778D250892
+:1539C000B735A60337F611FFC7B19F1CC5FA83A82F84B58C55BA
+:1539D50007A03FE3BD903D36BEEAA7ED4F59E36515B7F15B828E
+:1539EA00FD0F3FE5298EC9CD9B73B26347C9AFC1B7BB047ED1E3
+:1539FF00D6BCB141D2A306B1A79816E71AE9AF3CF242E3453F3E
+:153A140070F373DD194F23F6F95EE80781F1A7F4C0F9255AB02E
+:153A2900BD419F97929A049F19DD7C07CDEFBE50360E0960AEE7
+:153A3E00639F6A862E3096EFD0CDEAFB6FD177AA0BF97136C947
+:153A53001FB3E28A20CDDBB448C46C9745DC120BA6BF2298E058
+:153A6800DF081AECC7593A9A0333F44D791BA103CAA9534601AC
+:153A7D007BA57132ED6D9E97F23607A7F58164880F78925343FB
+:153A920037A72BE1183038FCE84F9D30FA52DE9650D3908009B9
+:153AA7007066F4D570B5A08B22F42AC0FD29EC41091CCD8B0F3C
+:153ABC00D43B78D94C32D76BD3CD473A5451A5D468F5CDC2C5E5
+:153AD10075C1E30306C64D89DDCE3F52F98FD3DF85D4DFAA4288
+:153AE600F437ABCF839FB723662FF1815F75F529F6B2D117930E
+:153AFB00B27D52AD3E59F850459F9CF3D2363D44BF0CD798284B
+:153B100076E10E7A01F0E6F4674EE84A2BC9419A7F7F6EE6B539
+:153B2500D3F852F6F0373C969E087C6C60D9710F19B839730EAD
+:153B3A00D7D28BC4B96ABBDC412A071E49A28C4B9E857F379504
+:153B4F00FFFDEA51923983FC4F2343B5CA8E11D12F5FB2D374B5
+:153B6400FA0C79017E2F16B1E59F35DDB20973899C7CD6EC230E
+:153B79005D5321FB3E4032DF9F841CE3A6D5CFE12C9D934346AA
+:153B8E00A8E984C04788FA60AF6F171440BE8AF1C5752BEEFC13
+:153BA30015D1DEC2152FB8C697859FA2D38322FE2F70F7C8C3D1
+:153BB80096BF2BEAFF0EDB4B7C3068049A3A6DFE1FCCF0FF61C9
+:153BCD00E27FC0073B05EB7C820F62E003C3E683D10CDFCFCFB8
+:153BE2009FCAF747057F0E66E9AF8E18A82BCBD3832EFA774D11
+:153BF700A33FE0D96BF537293763ECB8C70C7ECB49C4324A1863
+:153C0C004F936CB360B6FAB98BF8DAE1E110C1574C7CEBC07AA5
+:153C21008D602D2758DB7C37F2ECABBF01BFBAE08D11BC311723
+:153C3600BCAA1B5E4B36BAF502A5A953C0EBC8216B6EE8123030
+:153C4B00CB31CB87CF8824DA8A5C7362EADA541EC4B91256DF0C
+:153C60006BE0FB53B01DB5FF952ECCF01FD92E6F2256C061F98F
+:153C75004E2566D92FC591A33AA972C52595724BE07CBFE6913D
+:153C8A0058600EDE8D8F18CAF9A426930D739CE055C8E6958910
+:153C9F00C7B0AEE5F321561CE721A2A74AB64FFCA9DE960EA415
+:153CB40077FD33E6910EDFD953629FF44AC5DE3BD8F8A8618648
+:153CC900A516D4539ED88B98C1C1B988EF41E9896EEC77ED3513
+:153CDE0065AA0F7B61E237B52B8BB5FABDA62887B68CBD387FDC
+:153CF3003CA73C2937B65B653AE26413E16C936F2DD785BF237A
+:153D08007C526C9B08B0A2FE9DABB996B36E528FD370E9FD2C8B
+:153D1D00D7D06799CA94278E6D02FC98CF010B60036F2E2318BE
+:153D32004ACE9FD4E662CE7FFD59BD98719A2F92DAB7302FD91C
+:153D470075E2FB086DD4579473FABE8BEAEFDA7742F851827F75
+:153D5C0044DEE84887AFFB9FF51460A33EA12F6CF220CE5EA6C6
+:153D71008107D29D39F0B9142C4BEF1D5C5CCCE0C16A2B830789
+:153D8600ACDF8D5B78087D576EEC5A873DC921DE4EE9BD185FB6
+:153D9B008413A4C13644AC330BDE538483631AEACF59F76B7D0D
+:153DB00087C0C3312D40FD030E149C3BC6DA3BF4326A0B310BAB
+:153DC500C3D47E39C941271EA1751E24CED93B8CED29EBD2DED5
+:153DDA0023DD754198FD61952ADFE5C45B1FFEBC88472874DE64
+:153DEF00D5C2AE5A7420286268EE16DF804059E2EB7CFA3D8C92
+:153E04007DC0F17F72C5B3251B113184845E087F7AF8A685976F
+:153E190071863C4ADD01D249C6E2D5DE16C957A3CB91C5FA20AF
+:153E2E00C18AF80B48AFD0FA750573907A6FA34FFDA346457D70
+:153E4300A0598EAA3ADEA54847C77DB3388FF4E722966149836F
+:153E58006A5AF51E860E34B68CDE5568861E8E0F36D6501DD54A
+:153E6D00544795FA40A35347A9783FB58DCBCB1F10F5FA45BD41
+:153E8200BFEA70F25ABF0F1B89E57D778A33DA0D13565B510BB7
+:153E97007EE0EAACF0EFAF36A3948E39F62A6385D2EAC5BA120B
+:153EAC00818E68F793F20D8A7C61BE01E58DC526F28ECD90178A
+:153EC1006D6F07ED92569E8337C9B30163D3CEB3FD2679C294B6
+:153ED600C76FE7D9302D4FAE522FBE37847CE095ADCB7F762708
+:153EEB006425FA21533F719F43F2DCA79AE64CEB596166FBCB27
+:153F0000638C2A8363D86F147A0B3DE34CAD88371B8D0BDE2D37
+:153F1500B1CECE67D68424C9E2B74CBD549FEAAC1F093F34B224
+:153F2A004F7F90C3B07E029FEF94A06FB6BC150BEB8881746A9C
+:153F3F00D3AA9FDE958C3FA707CF3FA7C1462DA1B1126C1A1181
+:153F54006397F836A0B013F598673FF7560E53E3234B133497BD
+:153F6900FBC9362A461F146E5A3E6FC233A400318BFDF1634B40
+:153F7E00A04B237F10F53B700839DE65C11749D48BEFFDD9F533
+:153F9300CE8F0F2EAD99566FC60EA6B941949F617DE61FEDF10C
+:153FA800877EC15626788B2F63DC2855D9F2EE785B347E71160F
+:153FBD00EB9F662877745A391A9F379C27B4CA1FE23F9FA1FCAC
+:153FD200D68F50FEDD19CAD57F28BC87F89519CABDCF3EBCBDF5
+:153FE700D434FD0AFC1274F31FD6D5FFC9F54DBA19DEC7AF7EC8
+:153FFC00F0FB890F7BFFEF5DFFB4F77EF778F8A0F5D6FFFFFE71
+:154011005FF55E71E1BF789A7CFA7F077E9B3FA69D399A78FFE4
+:15402600C6F1F061F5B9F94D2A3BA2F779129B3F2ABF61BCCE52
+:15403B009155FE79711EAABAB553896D5E49C3DA1FF8828EF8BF
+:1540500077F80EB8FFEE6E1D631E3A823FB0459FB5AA5B57D5B8
+:154065002FF15977B7EBC1755CF34B957AB0A8524F90CE66CB4D
+:15407A00874DD7482F5102D53AEAFBD7D675680DD786E173B5CB
+:15408F00AE4A877F33BC776435A7E57192F925FE4ABD605D8D23
+:1540A400FEF5358BB58A758BB5907FB3DE99F37B1AF6A316C828
+:1540B90031C4C70922AF2C7D4217EB40ABDA850C822CAA284A4F
+:1540CE0068F08372DE178BF78B756F202EF4DA8A07E3BAF0CFA1
+:1540E3002438CFCED0FE4ABBFD426AFF10B55FE26A1BED9653F3
+:1540F800FBC827EAA5FADD6D5FB3EB9D70D59B4EFF34ED474C7B
+:15410D00C55AD6B29E4C18D41DCF8971E022CDACBA6EA7297B4C
+:154122002EE1C54F6DE6AF5D4CF8A9D416F86BF4F99F965BBC93
+:15413700AC7D63C51FCB2D87662704FEB12E457378106BA2B712
+:15414C0009DD240BBB881D01FD90C59F147D2398CEDA308DA2A4
+:15416100EFFE0D7AC5BEF5BA54E4C096BEEEC0D648B095FA2B21
+:15417600457A9C14638756F94535BA5FC0D4AD2D284AE83D3BB9
+:15418B00F764F80078FE6D3A6DC3C0443F71F6CEDA779D78128F
+:1541A000ED8EDB7048655DF8269C6F36B76008ECABD203D41E5E
+:1541B500FAD662FBB8C3394CE0252F8B970AE29BC2B54D7AC9E4
+:1541CA00BA7A01CFEE9C6EAD80F052E84FE8B92CB1718FCD975C
+:1541DF000B45DFB3ED5EA1B60C7A17207C11DD8B1D1840FB8A9B
+:1541F400D51B34D8DC15EB3668D3E94F83275020CE13B2828A7C
+:154209003307C57BE95C8D5EF2604C97D997F45994E780C44203
+:15421E005EFB791F3D17AE23F8884F0A8BEA75FEBD06EDD0EB49
+:154233000D5AE1B9B57A09A7B47DAB74FED97B88DFEFD140FB92
+:1542480012C265C55A0B07724C6A51D9165E4F38F34A0FEBFE75
+:15425D00580E62F807F3B15753BEBA7596F4A8EE9757EAFE153F
+:15427200D4D6DD8FEBFE55F7E87B73566A5823975764F3E7852A
+:15428700AC3324227FA2D6CAFFDA1775FFAB0DFADE9DB59A97C5
+:15429C00E6ECC0F7366B159FCE69C177627CF1DA8DF9630D1B06
+:1542B1009FC6B78679AD5E71EE615D3ADBA073CA2BF9B2F8DF16
+:1542C60086311D12674E362176B4AF9DCA9D6ED828ECDA65ACCF
+:1542DB00253710DE981758B6B1A26BBDB69B6401E982C5BBE8C3
+:1542F000FE879031FFF331DDBFAB41870DA1AA8F72B16F98F838
+:15430500A22EADFD922EDEBDD640EF6BF5BD842FD01C7C0DFB89
+:15431A00ABE09B524BC539C21F6FD74BCE7D512F3CDB2DE8DE86
+:15432F0043749F45F42E88F08D6E39045A835EC25FD7A623F818
+:15434400F06E82A505F0138E11377A1D3D2772B66AB3A81DC03C
+:15435900DFB9D37ABEFB7ABA0472C8F98DBC34AF6C3A4869289B
+:15436E000B7E36C98C04FE20E7C8BE9CE3F0D276CA237CAB09C3
+:1543830086ADF41CF8DE7CADE26C29E1B3549F896F7EC9B27C78
+:15439800F377CCE21BE0BD80F826E4DF2A70F1759B77C03725B1
+:1543AD009CD2A6F14E77FCBEC70A425B8826B1D66EF6E863B372
+:1543C20042D156C9FFB8EEFC2E8C3CFA186833AB7DFD46F67A95
+:1543D700CB46E75EF1AE477C1FA220BE7E63E158CB46299FE89F
+:1543EC00FC894AEE25DC5F277A0367B70BFC7B5A0A7907E1FE98
+:1544010071C2FD1E21B7DDF8CFB1F19FB0BE4B11947C9FA0B6CC
+:15441600A39BCE085A8057A29B46A7D102DF6D7BD0A605C9D76D
+:15442B00E2F52E5ADCEAA2C57BC287303B8677D2F8ED75D106C1
+:15444000EB55A03BD277D8F4394FB471E8B1659AFFE787D1E3D1
+:15445500828B1E7F65D30363B8C4A6C50D7420DAB86991177966
+:15446A00E4B1DCC8FAC7D876D6E21F7B64E32C65CBC63CF69F69
+:15447F001F2B88FFC946FFD8A3E277C51F8B315AEC67F43BF207
+:15449400258177794725F7908CBD9E17E5050EDE696C16FA775A
+:1544A900929CBB5F2F5CFBD414BC17CC84F7AE85A0B90BEF3177
+:1544BE008177A7BF6EFC936C2FBEDBC63FD67C30361CFC17BBB3
+:1544D300F0EF116B37167E7B6DFC164136D13BEC33BBF9DE2957
+:1544E800FF4B21FF2D9AA19C887B69D3C1C279FD14589E408C43
+:1544FD00AAA4D48273D5099237B954C72304C3A17B37EB15EBF0
+:154512009A34256789969773A7061EF693BC61AF376C3CF4031B
+:154527007A776EAD569CF3592D3FE70FAC77D2CA8D6CCD3D1BF6
+:15453C0077C73C2D806B2170522ED6B603B9AA47CC8548473C72
+:1545510037C7A641FBD89BCA71E6687B9E403EF80E03AEB7C9AB
+:15456600ECA43C99F1FE1A8D77CC5117D26905EB41D003684EA5
+:15457B000BBE6AE7FF163D57BC2BE35E7CD2EA77C1FF01EF9849
+:06459000C0E6B892000035
+:00000001FF
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/pca200e_ecd.data linux/drivers/atm/pca200e_ecd.data
--- v2.3.47/linux/drivers/atm/pca200e_ecd.data	Wed Dec 31 16:00:00 1969
+++ linux/drivers/atm/pca200e_ecd.data	Mon Feb 21 16:32:27 2000
@@ -0,0 +1,906 @@
+:150000001F8B0808AC5A10380203706361323030655F65636428
+:150015002E62696E327D00DC3A0D7054459AFD261333136278A4
+:15002A00192663E02479728060A10E9063213F64F0700F3DE05E
+:15003F009E6CDC7B2F3514B35EF0A28B9A5A731E554B91474C5C
+:1500540034E11AB6692618B7609D8404A2121CA8648D7551435D
+:150069009DA578A56C8AF276A9AB829DF3AC92DD52CC5EB177A0
+:15007E00D4CA32F77DDD6F665E263FA25B775B7753D5E9F7BEA8
+:15009300FEFAFBEBEFFBFAEB7E79F4A91F6C270A21A1870849C1
+:1500A8007C974CFA8536C11F37B9A99FFEAD9C49302569258321
+:1500BD00D8EF4EEE6E14EF59E3B3EDFED3E3C735EC67E50822CC
+:1500D200A9FE0FFD29BF7CEA97A26F4EC993D537AF13234A5E2D
+:1500E7005EDE94F3BF245F4AFCF1F129E7CF9E866E0ADE2C3919
+:1500FC002BF0237F849F3240F688FEB5EC75792D39E3BCB43E9B
+:15011100C9A9F54BDE24FFBC9C3C6987DDCD33F3938CB0674E4E
+:1501260078D6F8D7D63FD9DC8CEEABDC4824B2F9DC949E391965
+:15013B00FED7BF11FF975E7267F17D1CFB4BE77E3625BFBC0C26
+:150150003F0FF9BFFF5372CB72671A1F3D3EF99DF51312ECCF0D
+:15016500C070095C0E5FF8FFFE4B3A7E246851FDD31C5230FA46
+:15017A00FC0A35E009832F79ADB5E45140A3A4743C8CE3E39F62
+:15018F00C35BB09DEAFF05BD7A95BB3DADE6B56DADE538465425
+:1501A40052C90E11EF08B4773A8857FB013CB7112F090619CEAC
+:1501B9005B125380AEB695F80197D874FE9A9022A5D554ADE572
+:1501CE002661CA73EE80B5F5F26AE22D7F9A78FC814838484AB5
+:1501E300E8B36DBD4D843D4C4930CE42B06FCC091861CFB9BDAD
+:1501F8002621C3B438D010BE6DD7091AF29090DFEA334930C6AA
+:15020D001187E86D9CB09E2EDF18033C8DD220A9BB6D57390DB4
+:1502220011D2D8B26F23C02CEA0FAC0EB76CBADB3C4F48F1BBF2
+:150237001157A5EBD25FC0FCCB804A3412ECA211D133EA167DD2
+:15024C003B8518510311A53A5FDD62226D9C4BD46AEA567ACCA9
+:15026100362DB78EE8A7683E21017F201E4E927EEAB6169944DB
+:15027600AFE1ADE3AEBAC0C53534B0EE4194CF8AC2FE47C6065E
+:15028B007960DD5253D1FA6834346000BC45C0D909BE0A681025
+:1502A000BDD7BA4BDBBA12ED8A7C09EB8EA79BDA6BF9816681AC
+:1502B500F70EF3723259F4518D59F578B3AB0A66E7A3597F0E69
+:1502CA00BA90E04E5BEEC669E5765D2A33DD6762936427C1D5C0
+:1502DF005CDA40CA8A7AA03EA807AC0147BBA02E52A72974180E
+:1502F4007B956F461DD851EB3EA14348C8A0EA9689F2332DA72B
+:150309000E7B941FFB00D8FFD6801526637B69AB8FCC22A5F03C
+:15031E00ACF65863355BCB4740B7F5A05B6A3CEC239954156CC1
+:15033300E7B09E9AA7F084F085DB760DD171378910B6285EA406
+:15034800F64A5F403DE05D8BB4C2F800BD8EE3418BAF06B8AA3D
+:15035D00EE81F5E96393DE6D3B92E0385D564748698085091946
+:15037200A79EC256E0D34F49792B1D759310AC032BD6FBCDCEAF
+:1503870038D845EFE5456A87F95932097ABB5B050D98BFE30F8A
+:15039C009CDF2BE6B767E667E6C6EDC6D24DB7E7A56AA4888777
+:1503B1003626DE3B6D253EE5C5810BE19CD8095A7CFEB241D8BF
+:1503C600765A663C6DAE8CBC4EF7B70D35420264F51833C16105
+:1503DB00A6438F32018C232C303A64E29A23DCADBDCAE604CE52
+:1503F000C2DAFC0BE48392B027D20C3E546386122FF0964DDB3D
+:15040500C0A7BEC35A366D323B120AE8B357F8531ECA1ED46DF0
+:15041A007F6AE732A6800FFA49302E6321B8C48EB97E560BEFE0
+:15042F00458110CC6910FE9B84D825C10415992A67940623CBF7
+:15044400E9EC584E5DD1912DB4E84C9DA9C486689188ABB8F0F0
+:15045900BD43E494A124DEA49DE43503E75D87B4D6F9E7F81CCD
+:15046E00E748EF05F296419A062866F84EF23AC04791363CBF24
+:150483000BCFC31CE5D213EF71C44759162BA4E81F2077148DF9
+:15049800DE677E1BF429501F117ABAB5A3E037FD527EFD21DE68
+:1504AD0072EB2653890C502FC844D803BC937403BD7E2113CE66
+:1504C20027FA51FE0EC4AAE7DCA04906DB38E62BF04FDB0E52E9
+:1504D700EFC24B09339A731CE3886F2C203A191CE0A344E0591A
+:1504EC00183F514DC49F88258C471F213EC2FAAC68A8CFB85650
+:15050100D6535DAAB92A3CE7C0EFCB0728CC6BDC33EBBE3AF4E9
+:15051600E76BC964B19EF8949519FF64CE568E091F74150C995D
+:15052B00885B1C83D82FEF43FCD0E167A306513B39C4E31CF4C7
+:150540000131A6FE965F4D26FD9E7387CD79E78E9AE46AAF90F1
+:1505550009FC2A0E7E2562E5D1C8C62AB40BFA87E7CCA98C1F9A
+:15056A00E07CDB0F02E0079ED07A136DD5DEE892EB27D74DDAA8
+:15057F009075F0D47A1E222F1BA9F524FAABBC1763C2F6998923
+:15059400F69376FBD1FB4F007E4396CDFA85CD8A1BD166C3B678
+:1505A900CDE268B322323660755A03C6B5E64D2B053DCC1D2390
+:1505BE00D266445F1497ADAD0B68E03E15BF6D6448D8278AEB56
+:1505D300C80678BEF73EB0C30FE947E092E01FC585095735DAFE
+:1505E800F671D7EE55CF245C958188AB5ADA037C046D01BEE121
+:1505FD00BAF4A9E9518E9B1D5AC626FE09B121732DAEABB48BBB
+:150612008C15B459DAD7B3F32CC428FA34D7B6547ACE7D067369
+:15062700345B4F0631B39A266B102748855D9AEE95FAA9DD5677
+:15063C00D4EA35EAB4875792D2583897B499FE5D3F12FA91FA31
+:15065100A3343AFA18E487C7B823BF7489DC027E87B620FA20D5
+:150666004FD1F043DE9AE5B0C528F877AC664BD58D1BD21EFFFA
+:15067B0059BA7B79AD423CD23EFF6EAE509A67B0CF7B609F6360
+:15069000FF23F63989F6D9BCD64CED8550E85072F557D21EB076
+:1506A5004745AD6EE339DB1EF3C922D37F7DA9B0478E5E629653
+:1506BA005AA5D57F827B8FBE9F46125FF04F66E1FE5412866761
+:1506CF0086F945D818ED469ECAF8A08A7BB46860BB6E87ED4EC3
+:1506E400F114BF6CDB45C1764D60BB8F6DDB5D00DB21FF8083E0
+:1506F9007F83CD7B22DFE3C67E6F5F26674C9F2BE638724555DF
+:15070E001A0F7DDA111F0B20A778361F4BE710B11F8EC13CAB3F
+:15072300CFB85A932B64C35C82792494788F611E51E60E9B4A3C
+:1507380007E413987728E1C8273927219F0C603EF1E1B81893A8
+:15074D00F9A4D8B3F9A4F963E02D724A539F88D97980873AFBA5
+:150762001C3A37E59359CE5C33A1781D3BC1DC9B7BCDA235ED12
+:15077700A29E2C523E379B4988CE17BAF7F3909FE8EF821F7925
+:15078C000AB11608D25AE1474B445DF7FC5CCD20E5FB68A3A870
+:1507A100170E70A2DF010DFCFD7FBBF54429CA4C9ABEA016F86E
+:1507B6008190DD315E0F7E5103E34F925FAF825A94A30ECFCD41
+:1507CB00EDC7BD45FA3FEA06F6167AA890B7BE6EEB8ED2E275F7
+:1507E0005F9819585F7C7324B932C5ABCC90B5C0CDF0B262939A
+:1507F500695544DE16B4F419E647605EC90313E7DD13D9B652B6
+:15080A00AE1BE31B70DDEC7941C02DC8C25D1129B371352AEAA4
+:15081F003D7B5DDD02EF009F3F4EEA549887F684FAAA68452469
+:15083400AF42D45290DF570BFC56BA0BF015C4D73BF911F04B90
+:1508490037E243DE03FC62DCA7D1977CA206EDE5CEFA7063BDC6
+:15085E00A3BEDB4CC197290D617DA68BDC791A7B55055EA967AE
+:150873000D7A477DD7EA98BF20E2AE48D57848C3FD00350F601C
+:150888007C421EC69849CFB37FEA060FC6604F20B001CE496318
+:15089D00F45BB141FAE3B6A126DC2B99A8E7346641AFCCBD0C5D
+:1508B200FC9F80B3D24E383761AD1C83FDE1320F41BEF0EFBA70
+:1508C7005F9C89FC501BE39EAAC2D98AE8F5D48775DE582DD4FD
+:1508DC0079C130D653FB649EE04837404E899AD0B2CF592B7220
+:1508F10048F13F47DC707EFA7B13EB3699AF0DFBFCA4DB755C24
+:150906003B75477AA046AD605EF541B3E5D6BBCD36A0A978FFF8
+:15091B00C6DC8B750C9CBB3007DDB2E7553337827B40B7D80387
+:150930008A033190A792DF42FECCF4C379E3167106B1EBAEB1A5
+:150945001EEEC7F307D45D9DA1DE74BD05671CBE429CA18E43BC
+:15095A00BE5B682CD0CC95E2ACA1F6C4DD381FFA828EE5E21D9F
+:15096F00CF4F17DE36CBDB9B95EA476A72D279D11F53A6CF9FA5
+:150984002F7597077ACCF25BD6C49886A7633517D785EC80E7CC
+:15099900C4DF12320AAD0BDA4E683AB425D008B40B301E87C6CB
+:1509AE00A0E9625E4FDC6EB04FF43059BBFD16CF2CA13DDE56FB
+:1509C30043BEDBB50EF83FC2317F3629F20C3409C7410F71268F
+:1509D8008F2F88CBF60A4BF1D9381D5E9ADF82B8362D3FA475C3
+:1509ED00BA4BD293F8E3643ABE8067E39C2533D1CBD03A3C13A1
+:150A02009E8DD33425BF89326D9C964E46A68553D2C9D040BBF7
+:150A17007F55C31A995C3D2CF1C7A25CE40D8CB1E29881790360
+:150A2C00623586F12B629A58F412FA289C3F647C34424C9608E5
+:150A41007F9B2E4E5E8138715DFA8579CB9E939363247D66979D
+:150A5600B181F1823501C620C60CC64E3A56ACA39958518FC96B
+:150A6B00B3FA18D457D69F1A6B2156F09CCE223913E224153FF3
+:150A80001F431E9A8D7990EDA5175CF2ACFE817D7D38027114D6
+:150A950081380A7D8D38DA6CC751C3639938FA009E23DF07232E
+:150AAA004223D0128F43850E8D416B8016825602ED1AE0753D49
+:150ABF0036318EC41D03C412CAEFD9DF938E27E09B965B03B992
+:150AD400F7BCFF8A21C70726C557AA05537E9F8DEBE047317E33
+:150AE900DEEF81F157441D23C75BE2B2C13A3649FEF5022F9BEF
+:150AFE004E8B23CE5AE21F91E9F8B54C8AB35E320D3D874FEF6F
+:150B13009A915E86969EC69B420F382B230E9D92DF4499668A69
+:150B28008D7A32959D60BE4D7FE194E3683F394E74A0F3154D74
+:150B3D00CE4DE17F988EBFD4BA8B38D4FBB846C8AC542C4EA83B
+:150B520027713FDF91D98F156FABA86DB78CB65588BD1DFC5798
+:150B67007D286614EF1AA4BA479E078B77F5D28847D6AE88CF94
+:150B7C00B0C665526784B9B260E38E7DBC445B88674CB6E10A5C
+:150B910021EE75DDA61F635A2DC718F12B780796AE33FA999E1D
+:150BA60043484524B702756A8067E58101519721BC73FE108595
+:150BBB009862B92AE8AF77F3DBB513DC1D6B73DC635914F1AC84
+:150BD00087F12E56D25A75B3B4622F6768017E1CF67CBF1E338F
+:150BE50015C85F985FE2F23B9EE0F375F4B11CFA743964B06EE9
+:150BFA00521FC48BD74A7D2C873E5F492B4B9FC12C7D06BFA10A
+:150C0F003E71873E671D32C46F521FC44B7C47EA1377E8F3954C
+:150C2400B4B2F419CED267F81BEAA35EC9E8B3E44A460684DF02
+:150C39008C3E88A7DAFAE0F3AA9BA595A5CF48963E230E7D4207
+:150C4E00F6FDA61A180DA77CBCCCA066BB897CA58FE0FB4EFBF0
+:150C63003D6EBF37D8EFC81FDF0DF11EA3C29781C7CE1CD1D360
+:150C780041FBBDDF7E1FB6DF2FD8EF23F6FB6AA0B3533BC6C47E
+:150C8D007E0B63EDDA49BC1BE40C9EBBB49FE2F99F8FC273BFE6
+:150CA200F6160B698BA97DE6E61ACC2B857D695E24B73A10CB76
+:150CB700ADF62572AB3DB00E78DE451DCBB597059D7A98BB5EAC
+:150CCC003B25E844E1B9567B83E1FC77A41C0C79D66B7B98A408
+:150CE1006BF18540B710724F0D394B4F6F3BB916715096422D36
+:150CF600B702613FD9F653011B75C0F66E7B4BC050A614EC99A4
+:150D0B006DCFAD4DD15FACC9F5433AF3C4733FABB7F9A34C0FC4
+:150D2000960DAC49D14CE122AD146E4A5694ADD4C645BAF768FE
+:150D3500B9D5381EB56DAA3D216D1ABA22EF6F904789BD3FE19D
+:150D4A00B8BEC3392EF9DD65D358286174F44989B3DEA681BC57
+:150D5F00FD4803C6C69FC88C55D9760CC3F846B01FDA8EC2739B
+:150D7400583BC0F0DC392264BA2CE4DCA1BDC88E08FB76F1DBED
+:150D8900AF0807F47DF7466E65D9853BCDCDA56F2C7F612C6631
+:150D9E007C7B2DCAD12E6C940F67B9556BDD952B4AF72C6730C3
+:150DB3007697188B0B79F363B915F3DE7257064A0F2CE7305641
+:150DC800B856CA8FF6CA8738B9F17B77E5EFE6BFB8FC208CFDBE
+:150DDD0047756E753E9C577F7DF1F32AA4F9F17C5A85F3FFF557
+:150DF200C86015E29EBF78026AAD06C113E48F5BA22F113283A0
+:150E07009E715DF43B056D120CC555D1370A39E07C18C798B8BB
+:150E1C00EDCC6553F93002F1F71A2D10DF7F625CCEBBCC6B45C5
+:150E31002F6D4482116E403F67DD5153D9F47DA8B3F6D15B712C
+:150E4600AF04BB49BE31DE2AFA06DE2EFA2E61CFBC3D80BFEF5E
+:150E5B0069C0BF9B16068280AF895C26F2ADE81BF9B0E8570B92
+:150E70009BCF3A03F81FFE10F037D1D9011DF0435CCA1DE37EDB
+:150E8500E89F15EBB093975CC9EC6DA454033C43ACCD23B0367D
+:150E9A008DDA7EA606C6007681AE96B6E141D15FE0E5D037AD30
+:150EAF00245E1674D52944A3FBAF277DE84B3B005EA01D83BA29
+:150EC400C112F6CB81B3F8ED77209E8C2BDC2B1FB171D1DE7613
+:150ED900BC517CDE0D3C55EF0766EB9A98FD6DB39F22BF48E2BF
+:150EEE0067DCBF6B08EB5F529F789DC33BB340367FA8CF54BDFC
+:150F0300782FF021776B43FC9315B63CDA1DF4C69792C76198CC
+:150F1800AFDAF2305B1EAA65E4C1BDEEBC8D3BEA9067740679E9
+:150F2D0074873CB5200FBC3336853CB50E799EB4797C807164D6
+:150F4200CB336ACB73BD2C230FEE55F7D9B8E86F2979F0793A72
+:150F570079420E79D6833CF0CE6253C8F3CEF28C3C977E277943
+:150F6C002CBB827B9A940779A03C3B1CF2E05E735AE20A5E2E36
+:150F8100C8ADADD57DFC7A32994CE55867F917D10659443B01F6
+:150F960039BA96AA810DE1CE35FD14FF4FA873ECB821758973F1
+:150FAB00DDCE291BAFE0A505F1791CFB6658EB6539856F9A5A59
+:150FC00002CE58E939FD7C839D8F53B806E04521B67D901B9DD8
+:150FD500F3752DCA6A81BF017218DA61689FB1466D21DBA92DFB
+:150FEA00039F2967ED5A15ACD57A56663C627272B07149A28F90
+:150FFF0046ADBEC62EC08F6923AC5FA3ACF3C8095A4C06CC398E
+:151014005B8FD0F9173FA3AD5BEFA46DF397D2E7B62EA7CF1F57
+:151029005943DB2FAEA387E69FA6783FF357BFC8C198A6F8BFCB
+:15103E00542F1C7993169CE9310F5CDC07F5C0BE554EB9CEDE5D
+:1510530043BC85DAFAEA344C6FA1E5F712AFCF09130AB4D0C3DD
+:15106800D3C06BAF2527C18D480BC37C89F6F12F9E621E6BA1D1
+:15107D00CBD64C01875AE093F9C4BB30D6C3704D312FD45EC9C3
+:15109200D405E99F3AC2884A995B13DF2FD855FCC78E2063D72D
+:1510A70044DFC5AEBB64AD33EE92DF494812EAA2C23E336A0D67
+:1510BC0019F87D638EBBCF3C9433641C0A0D189DB0962F586F8B
+:1510D100189E0F3E1777C9F825E280D561A81BA9897E90EF9079
+:1510E6000FCFF76E3A24E0CF440A2A3E49FD7B8D9D377E5E23CE
+:1510FB00F7C7487A2F8D31947F01EC63F9B1DF97CF8BFD1DEE8E
+:1511100023F65E382CEA18B97F0DCB5C073693FB1FB371BA04B5
+:151125004E43669F14F1F0A4CD6774129F5B27F091FBE5B0A8F2
+:15113A0087527CE2369FF5361F89D345651EEE67B171428E04DB
+:15114F0095BABCFD7DA63FB4C83C06BAFA2277560560AFBA7A78
+:1511640043EA7B3E726FC56578F680FDCB0C3807E50E34C29EFD
+:1511790055AD94F687550DBF8B04E9D8DB9027624A5DADF6326D
+:15118E00DED9F9DCEADDB00F75B0D2D0BEAA0324DA48D43DD4DD
+:1511A30055DA15762F851A4DFF0D5FA8FD86BB6C5B57691D3C31
+:1511B800A41DE0FE441F63B97D4DCBB46E8E79C51A053D12BD56
+:1511CD004C059A08276A94C281CBE3E4B9E527DDD5CEF965C6B7
+:1511E2004193DB34702E3E232D1D68B94B97844359F37D303FCA
+:1511F700A4BDC8A186B0E747A79CAFFE23EE4D4BC2284B10C611
+:15120C0096419D11D43AC45D3427AD8D86F62B9EAB609E3B411A
+:1512210039E96C74475AB90FF66017D6BB7A2FF744A2BC2032BB
+:1512360022EE9C27FAF1B0EDC7D6043F4EFBEF689FA13AFCB79B
+:15124B00106A85B48F821FE0FAA18FE6ED1F308BC92253EAB616
+:1512600044EA16EAAE76FAB35FEB608188BBD28DE768C2A807ED
+:15127500D6A3E94EE2C5F7E7E7B61B259B89F7A5B93143D596FA
+:15128A008AB5598FEB0073D9FAE876EC73578BFF21CABF23206C
+:15129F0069AAAB3C61159E676A128F885E0BA4E4D620EECA880B
+:1512B4005AB8CC6C752DDD9E6BC399CFDA9E1AC7FF6352430BCD
+:1512C900BFE74ED10845BFE74B3DAFCBC0459C801EF81D11EF02
+:1512DE00CD0E6AEE3A96DE9BE4BDD916BCABB2EFA5314E08DEDD
+:1512F300AFE9C75940AB2EC7B51570BD8F5DAFA95E29EEFB990A
+:15130800BCE39FA37799F8BD016922CCA746CDB3C9A47F527EA9
+:15131D00B2F9D74EE2DF6EDF9D4B39EE127766BD71A4A3240E38
+:151332004BBA3A7E4790307C4E4C419FC571FF91F4D500F0620B
+:1513470094E2BE68D3F4F9347FD50AADA02264E78D0AEDF66A05
+:15135C00A0C97C6A47FAEE1068B3A2ACF7F4B3CD8F8F1D355654
+:1513710068F757F8B4FBCB03DAA28AD47DEB0A6DBBA46DD35490
+:15138600BC8727D155DE9F19B638717B25D610F8EC4638D8F716
+:15139B00207ECF8950FC3E731ABFE72C4EB82B713D104791385F
+:1513B000EC20E660C4D1FB38E2A0ACA501AC11A1B67B88903162
+:1513C5000236FE4BE255C5DD690CCF9BEA79D24FF15ED2F20E35
+:1513DA0088EF6B44AC7B4CE0FBD5D7E47730FBDC81304D1BA0C3
+:1513EF00E28CE280056D58A303B6CC8635E0D9B754F0E33B1C7E
+:15140400E3E2FF0C865D648936C09D30DC971766C188CB4DCA55
+:1514190027C2583DF46A6488A910CBABB3C712CAF87016AC0146
+:15142E0060235930F7BF29E3A3593002B0771066AFF37F13F3E9
+:1514430084C1511569F6242F3203617CC0644C280C0F0C1AF656
+:15145800229960D0640871E2A297502C37025AEFB141264ADC60
+:15146D00E0A1CC4156D92DEE7CC144126CB07926122DDD9DB8D3
+:1514820099327844070F14B7425DEE8E73BD2D6A2B6559B7D497
+:151497009D52B355DE15578538BAE8B2559C73DFD7DD6FE6CDD5
+:1514AC006450F1F6EA7E4CBD37DDFDBEEFEBAFBFFEBEAFFBFBA7
+:1514C100BA31DE44D82DB80EE738919E4FBE9AF31B37FF6E8C0B
+:1514D600D97D8E4A1BC19FE113CC3500EB7D15DAA8986B25E05C
+:1514EB0087B471F62449D02133CEFDA473208FA0ED37A19F74B0
+:151500003663C7C458757D99E6E3144ABE9AA12F947C9BF50CD4
+:151515008CEBAB1D34234CD447180B4298111E57823AA4431D81
+:15152A006768C3D7CAB2AD92C6AD92463FE63CA91C16DF3FF7EC
+:15153F00E1FF709CDAB90469291BFD5236446E9DE415D833C0CF
+:151554000DBEEBAB6C10E61C105FC6F58DEC875B3ED5BCE799CF
+:15156900AF3269B70EFEBE8AB2C2569792B0D97682E72DADE6FD
+:15157E00717D5146D64D2F2B7296012DDCE704CDE492EFAB5527
+:15159300511E4ABE0134BEC1CA529CCF7E53D2C1CBC0E6F81BA9
+:1515A800C7A4FE495015BE293361DC608CF8337C825E8FF0D8F6
+:1515BD00B855A83D29D09E64DABF2DF80B65F06EEDC9F843208F
+:1515D200770BC03B94FDC477DE271FD06EF709DE2FB9C6F8FCD9
+:1515E70009F8B2F5FBDAB2F576D9D305CA9475D3CB4A9C65796F
+:1515FC00F1542EDF728EDAF3DFA91B7AF274033EA764DDD5BE7C
+:15161100310B7C63D755E3F3FBD96FD1EE4ECD27B36CBD843CC7
+:1516260079CA9639785F78B6D748E4D5CF3A3766081863B4A142
+:15163B001CFCA948C92615F7A301D6853FCFEA38940F9C17769B
+:15165000DD94B30E78E19670F8D301632C0F86CD032183A2CC22
+:15166500CC2F03787BED325FB6CC2C5036D39B5B867DEA73F4B0
+:15167A00D92EEB2D5056EC7596993451A9105621F9436214752A
+:15168F0006CE4B1FC83CC6CA306EC2FFFBC7DACB1C6B51524A3A
+:1516A400F89A13E5D7C7E5374E6D399F7910F72B13AC1DE6BA33
+:1516B9003F2474592118EA35C380BA700CDFB19DA53BD60968C7
+:1516CE001F501F6E475D02FFF1BB0315633A878FB2E223AC503C
+:1516E300B9EA28A7CEF6E585CB5528EF92712E94FB7C7E617C84
+:1516F800B820BF7C85FB3AEB5CC21832C7A3072A123AD703DF1D
+:15170D00866F7F4258D8CFAF1B037A2D747D6758B9E39A907AAE
+:15172200DEB6FD421FE7F23A571F17A005BE11B48C51FE04D841
+:15173700D7233CF06F0AF2A1407B92699F4BDF1E87DCE1FC7519
+:15174C0079A7CF6FE29D3EBF8BBCD3E7322950B6DF337D7E97A8
+:1517610078A7CF6525AF0CDB3FE7FC36BB26E13ABB92CF716123
+:151776001B90A70B1DB60FE3E0DD72AF86386CA19A57A738EAD9
+:15178B007C79756E475D795E5DA9A36E812AED48204577F72309
+:1517A0005D268F1F667D8F380BDA7BE6DCDF88338C69E058640C
+:1517B500FD8D98217C8BDCDC45A266737E547F75BBABAD8E9F57
+:1517CA0067C09C7AF516428A0E361AC9CFD31E5843EA53F054F3
+:1517DF00802798FB87FB643F03997A3EF6C77A726984BDD79F79
+:1517F4008DAFB70EFCFFFECEB7104F0DD0CA423DFAEA3B9555D3
+:1518090076EC09E339A4DB7C7312CFA274C7DE9CE2CF495CDB6C
+:15181E00C033F9668A9F5101FFF25EB157E2F039A98B8C9F43E4
+:151833007E52807D39C4E339D2CEF6839D1D053B0BCFEF8FEA65
+:151848008277D59C77B6CD8D7D96F6106FAFCE3E93FC8BB8384D
+:15185D00FF50FF35013C13CA3FBC53B903F1EDB957CC93DDF0B5
+:15187200447F12734E79CC08FEAFCFF137E36CCD771C7335E3A0
+:15188700FFA62CEC2BF024217992903C49489E249027C5B09E3B
+:15189C00BE16FEE15CF26A4B0233B5BEC04BC58257A2EC562824
+:1518B1003B1018CB295B01654381E3765929969541D98D8149CF
+:1518C6002CE3FBEE829F7A0AF8077C6C4D4DE7E3A53B89A721F4
+:1518DB00857CACBAE34FDD9FFE02F25024E5610FE03DDF9C4B45
+:1518F0006783423C473F853903B4BEF4E9745A5BE11BFA29D2CB
+:151905005AF3AD69B5E391DF86DEED05E82D96F49E015A1B9ABF
+:15191A00A7CBAF8939BE0564F7E38B694F11F4E3838BD3FB616C
+:15192F00029CD317B11FBE6BEA47E63CEEB7EC4F5781FE28B23F
+:151944003F5756114F17FCBE0BFEF73E813E69554CD56A18D73C
+:15195900FDA0F35CCB09998472FCAF9056FA21BE0774AA017723
+:15196E00166886A56A2D2F22FE08E899B511DC0F8C51DC35426B
+:151983009B98A262AD12DB0FB65831C11EF6F3FD2C0AEDCE4436
+:151998008E58A51DC7ACB512762F3CD3D79B74233C5DE2BFBBA6
+:1519AD00218F9E06D95687E746F0357D9AC04774810FF120BED8
+:1519C200E833B9F81640BBD28E23D65AC0F7E10501C327F17D8A
+:1519D7007C41E083FF6E273F55C9CFA34D44D437919CFA39B6C6
+:1519EC00FE93F59756E6D6CF95F5DB65FD0779F5F364FD5A59A5
+:151A01007F9CD7A7A8EFD9ECF9A334F491913E1DF790DC68A32C
+:151A1600F3CE1BF5833FC4F0CC47656C7333EE2F997D75959A13
+:151A2B0012D4A53E1BA838AF3787F6055B1DF1DCBD273B7E8D0B
+:151A4000BC7ABCFBFDE680A3FCDC0BCF5CC1F2959B7FDDEC8CD9
+:151A5500FF9E7DEBA72F63F983FFF8AB665289B1C761DAFBDB56
+:151A6A00275A7C7E7373EC87C433761FF14CA3D391AF9B7A36C9
+:151A7F00D73E0B5F2365A10E7179C53A8C97A9B97DB3FD236C72
+:151A94003713647D3028721BB0ED40DBB83E33725F607F1BD7AA
+:151AA900E5CCB47539D4719D0F3079591E3C5C6F52B02D5D5C15
+:151ABE0086ED35183306CD2A1DF7BDC16FF4F457C4F4BBC89216
+:151AD300A0972CA99BAFB98298233650C1F4756655F0BD0C5F2F
+:151AE800C6F83EC46CCE0FB6177D9412F0F546F3EA3D8E7A059E
+:151AFD00EA7BB37CED2F5248BF1BEA5DB5307EB2CD7C6ECFC40A
+:151B1200B7D741FB8DB2FDF740FFFBB592805DE787BA0622E42F
+:151B270009FF2F3C3B6254C3FFF98E360BCFC60D5F1E3DF7C0A8
+:151B3C0038252271CB0DBAB6FECBB4277625EDD9FA557A96EC0C
+:151B5100DFAA49D0D3203F397AC527E574B491F079134A3E4B1F
+:151B660093256416CA19FAC136EC27619E610C4775D0E5AA8842
+:151B7B0019C723DCFED2808C3FEF01B8D5C0FFDE45C493AA12E9
+:151B9000B27FB20160CB7D72226DF99364980E4E8EEA336F4273
+:151BA5009B1EA0C297D5E43E6D35C576459EB8F1AF8B7E50EF22
+:151BBA006B8CB1062BEB6F45E0BD669090283C1B9E23C484E70C
+:151BCF0065F895C3FB65F885E0C79E13FB5D08A7F53FD29ED399
+:151BE400B82693FFDDE7D39EE3F89F8DB079303E181BA8E47B6F
+:151BF9000929EBF4FD843C87B6818D58367FED75C669919FC22E
+:151C0E0061281AC6285EC77C7A9ABA8F102FEA228C9B711FF33D
+:151C230088E56AA306EE2763EC8AE7CAAB23B8B75AD6E4A0E3B9
+:151C3800AC9BCCC2D82AE2C7734FB857B100EAC73CD25E713CCB
+:151C4D000798CA7535A326FC5FF05F609F501F89FC8B0C2D99AC
+:151C6200B39958F63B570AF0F17D3CC5F18E7B97F63BEE59F2DD
+:151C7700B80FFC1F73C4B96C783E76C4405D904A5FCFE71EC6BA
+:151C8C004486FEF9282F23A9EB89EFDD51F10E7F701CB36D6341
+:151CA10016C65186268FEA650ADF43B1447C2566613CA5C94103
+:151CB600B7D8BF1CA60F4C3D30B5787234472E67A35C227D20D4
+:151CCB009BBB6F271E1EAF0C1F61E8F7EDD7560510861B73A2DD
+:151CE00022A798163941FDFC9CD3179697E700279862EF075FF5
+:151CF50014F916FC5C82DAC3F74C791C397CCC7A5CCEC76BF51C
+:151D0A00279B1CFCFA661A246E3CAB84F80BCC81F25560EBE5AC
+:151D1F00FC60B8F7AC522E5764B288801D328662CA263C7B40E5
+:151D3400EFE5716FBFBD6E9B43460CD46BC85B2AE9C3EFCFDEF8
+:151D4900463CCAD45386FAFE53BA5347E2792466821EE76BBC5A
+:151D5E007E9AFEBBD30AC626152EFBA6581F4D017FCCB87E3379
+:151D7300190DE299C5D496A3CDCE71B94EEA8BEE159C0779F150
+:151D8800175CBFD9704D0E374D4ED2CC99447594611CED7B66CF
+:151D9D00BC20EC191276F90A92B38F9B858F79A4FD745FC5B0E0
+:151DB200CECFC7838E45FA63FCEC42DC5C8CEB03C0519C1C3729
+:151DC70095E409D35D1A37704F7026E09B1B66862B42E9A1A492
+:151DDC00B249D17AE90DEA2F8D33E9B4DF1B5382D9757098A279
+:151DF1005FBBDB85BAB015CAAAF9790D9EAE8B3EC3FD620D515C
+:151E06008ECFCA06983B77BFC8D75A01ED4D727F017AC13E46AC
+:151E1B000EA37D1CE6F6715FC549DD3BD9773BC737A5F4B2C6FC
+:151E300031417B386E7AD1DF93E54591B8A9362678FF0E9103BC
+:151E4500BA05F2EA5E07F38DC5AD9BC51955E68A8C67FA3737FD
+:151E5A00341AB4BF15FA2AF33E8D9EF70E67F371F7817FE13540
+:151E6F00253DEC2AF440B90AFA176971E2748978EADE9C3334E2
+:151E8400A82741C648E549B18F20FD33E09DE08FC82DC8E5A33C
+:151E9900DAF762CE7E3DCCBDC806EC036BC7791A4A1EDE5B29A3
+:151EAE00D681E683503E188EE96EAFD86B4B024DE78B4D3CA3AA
+:151EC3003E0BEB03EB458E0CDAB0C572EDD8CA6564CCAC833ABB
+:151ED8009B764E37B46F58CFFD6C1EC75F2BDB353ADAB5245FE1
+:151EED00DD0B3F13CBA3EB798CC4C43831F605D7AA48C7E05399
+:151F020071DD3729F704A1DCC6DB25E1FD5501BCBB1D78B7CB1C
+:151F1700763F71B4BB0BF0623BD3D12E2ADBF514A0EFAEE41B6C
+:151F2C0026CEB17E4EE3DF9B685FDC408B0AF43DCF65679CEF03
+:151F4100430FFE13D04AC4397EB783D66E097BA000ADCC41C374
+:151F56006ED9EE50015A871DEDF6C8762F7C0DAD38C636ADA5E6
+:151F6B00DF406BA983D6A484DDB1613AAD5D1BB2347C2CDB6D89
+:151F8000DB7095F1DC901D4FE52AE3A938F09EB7C7B300DEDD56
+:151F95000EBC17ECF1BC0ADED68D38BF2690074C75E2C5FECA8E
+:151FAA00FB36B0DC96F935D0FE308967647E638990F92B2E21E2
+:151FBF00F3A18D59DCE11281BB65E3D7E006BC3E89D7C6E77309
+:151FD400F473A384D1561806C3396BEF7597E7EB3CD02FC75F90
+:151FE900CAEA3B3E9FF95D0A4719B767784F8E7A9CA11FE92EF7
+:151FFE00ED33F6815FAA826D53D79E32CAE909E32021739C3A1C
+:15201300E86FA05F85748FFD9DDF15D70F9BE33ACA8B88271E8C
+:15202800D0613DBC17D7BF77715859DBB01C6015815DC8E8D5B4
+:15203D00D0B8EE5E17E73A95EB53DB5E98A84FE35C9FAA6D40B2
+:152052003FE85197E33DA7BF9598AF31ACBB2A9881E7F178AE2F
+:152067008CB0F9D23625047E26F5697848F8946063455F46F90A
+:15207C00F9097E3E08ED52641CECD23B863B7682A26D2A684F28
+:152091005ECEAE1F193FC7D46BF8319C8E7B15F2FFA5747A5E1E
+:1520A600FE5A52EC77F278BD359C02FDEA81B915AEA12CD41386
+:1520BB00455DEC2E163A59917E7C293CA37F486772FF588AE7B0
+:1520D000E79539F3C6944671EF4CABA31D5EF893DF0E6DC2F3A4
+:1520E5001A9E5B3AC910CE83987F510BFF8167E877BB2A13EDD1
+:1520FA00587F4368D4B821F40ECA8CD5CC7345C618C2C372FF1D
+:15210F00E6B895FDFF8EC1CBFE3A8E3E0BF1B38421BE7F076D69
+:15212400BAAFC8DB631CFF324BD3608AFB4D0E9A12B4991C5B1C
+:15213900E9D75C011B37DEBDC3F34230FF1ADAFB6FFCC2CABCBE
+:15214E00AFFA228327B9F058535126EF07D6AB320F1BE92ABB9B
+:15216300310E7EFE10B3F819D31A3A07F87D3BB24315B044DB21
+:152178003186FC07B368A9EAD330D6C7E19B414BD18E5BED0E8D
+:15218D00BF12D6DDE411AD64E5844BAE8B0BE05983BE4B41D8DD
+:1521A200555689FA16C09EA0840D594AEC94856704C4797E691E
+:1521B700BB51BF15CBF98B396DF25C0091759305FD19915B88C8
+:1521CC0072746106D29560ED226798B9257D6E271D682B8B05AC
+:1521E1005C7F30415522CF2AA8C72CA443FD6889C56D51868E26
+:1521F60014ED8A65E51BE11CBD4FC0194C09F8026E82F3A7EC3D
+:15220B00A33EE68235223F8347C6753C138F3EB0F82661619B93
+:152220009C7900F03F8C65FD1FBBDF083F719FE89FC0339683D4
+:15223500C7DE73C0B69C8F49C1C71B36F75AFE7082D7259C38A8
+:15224A0033E7914354D0D24055CE975679875080BA653E202FCF
+:15225F000F8FB28717A1EFFA0ACF4773D2E07B7909738E1DB4DE
+:15227400B114F508C6FE992D27E80BE30D65CF935E9DDFD31477
+:15228900A69C2FFCAC05D42BD05FD660525C841797F61AECC022
+:15229E00ADC607FF96F690A911BEBEF7E118A96F1A8A768AF9BB
+:1522B30023E24E017B0D535E3C7D1DD5D37624735E3EB39E9A77
+:1522C8003A66DD7EADEBA9F06B962D539847365C22D6BDB93243
+:1522DD002564086919967CE163128C7179E2EB5958C7A33D4393
+:1522F200794219E0BC32C51AFEA5AF44AE52A1F504CF1B0EC06E
+:15230700DC6717E83C7FA01DF767BCDA92FAF7D19EC23AFC1118
+:15231C00EDD6E0659893CB93BE55DC36DE2FF37DEEC74B4F0E1C
+:1523310070B9E3F960A2DCC2F2F7E4FA3622DB46F3DACA720B9E
+:15234600CBEDF3B836FC5EF9CD60DE37B2DCC2F22E09BF5FB607
+:15235B008DE5B595E51696DBEBD4C512FE6AD916DBE1FB028718
+:15237000BE6975D4E13B9E6DC2334D6E90A362B0558A36622134
+:15238500BF1475BF81E31DD046F19EA9B9734343CD0AAC57CB16
+:15239A007A2E18A5DA116BBEF94993BFE55343891CB75E8E95C9
+:1523AF006C72C39A0BECF1BC9991192B95C805CB96D999A0DB1C
+:1523C4009257709F2E3B077E0A3652E1E746D8B4F928E757464D
+:1523D900AF200CF5E08831583CAA236D73375759F67CE632C014
+:1523EE00CFE58EF3BB8BF8592FA147ACFCF92CF2400127CC19EB
+:15240300E73C796A76AF91F8ADD84754A54EFBA679F27480DF1E
+:152418008D23E6C8C008CF89518BB3F98F8B31F7007C8D07F85F
+:15242D00DE7E36AEB50EE4CD67CBCDFF36BEE9984FAD45FF072C
+:152442003A3ACF9F086B23ACC4DBC7F9F912C06BFAD4E10B5CB6
+:15245700CCB3BB400BB611FB20A6C5F7472AC7DA4B0EC68D21C8
+:15246C009015B5294E93220662B9C57E29BF37096D33D66BB0B8
+:152481006E4FA17D97F0307EAB4716B1622FDE75D743272F66C3
+:1524960071AB05FC107704F0F23D0AD3C2F11A02BBAF4E8CD0AA
+:1524AB00CB12278E6F0E4EA877E7E1CCED7F75FB4607FE900352
+:1524C000BF5600BFE2C0BFA000FEAA6BC48FFE456F6380DAB4A9
+:1524D500200D139F081A1600AE7CFCEAC4118E4B8B8CC0DA3C30
+:1524EA00D10E6B6F0B7D1F45E377CACC5B101961CF83DF833679
+:1524FF00ED92D3CFC1589F5A65F5B65103EF74BBF46455338FA4
+:152514002756DFB4B4AA6D6B50FB6143E366ED9EBF587FB7B6A6
+:15252900E127BBBA3B1FDDA5ADEFDCDED9B1AB33A8B56CB9679D
+:15253E00C7CECE8D5D3B7EFCA3AEEE2DF5CB6E5B16D0AA1FD909
+:15255300D5B56DE7CE1D8F6DE978BC235457D75877DBD23F5BD6
+:15256800AE3DBC6D7BE72E2DD0585BD750DB7807BC04EB03C11A
+:15257D00FADBB4AA4CFCCCC6575BBBB533BAA3BBF6A11D8F4646
+:152592006B3BB67644773D51FB68C7B6C76A77ED7CA8B6735700
+:1525A700B4F6E1276A3B3AB6F3B2ED3B764497EDBAA96E857601
+:1525BC00ABD6B9755BB7B6B5F3E18E1F6FEFD61EEAEA78EC478C
+:1525D1009D5AF5EEEECEDDDD4B11CBB783BF75E7B6C73B77D624
+:1525E6003E0CDDDAD2D1FDE896AD3B1F5FF6D04D2B1AAE063F10
+:1525FB00039E9F6799E30FB7EFC77D42B58ACEF537B4576BF5C9
+:152610006C199EE5B1F3F423CACA85FA05E350E870B4880CD334
+:15262500F63FA63379FAEDDABDD67FFECEB552517F6054692D59
+:15263A00B40AE6DE39D0253E78BE85BA539ECBEEFA22ED797785
+:15264F009112DCA81D613550379F8C3787B401C6EBC3CAD30165
+:1526640028437DD3E428C3762AD8408069F56BA5AB6C9B500E21
+:15267900BA710611BE04FEBF02B0F7A9CF44D14F1CFE657A16F7
+:15268E00D2E5CC6B77E6B4C72E8B585C1F6F5F4DBBA03D513FA2
+:1526A300B77CF0CD04E68D39F0B328E1676797B9C85CA40FE9F8
+:1526B800F069C718F66106AC53317F8E4C2DC538ACCFDF72AB4E
+:1526CD00817DC77B164BFEA1D1C02B54AA0096D8AF3A44C3DAC6
+:1526E2000BB4FE6DC00DFE940FBEB7F1E0391EBCB301CA2C2721
+:1526F700CE35E934C7C9EF6D04FFEA783A3DA732E2127B6AE153
+:15270C00017A1DD80584997C0BF3660350F60AA7AB04ECE521AB
+:152721007E6FC47EDC972BB3C7CD3E6311FB038EDDE77CEC30F5
+:152736007EA36930EFD4BE845B5B6195B41C85F13EC061E33C5F
+:15274B00C43958AABD6CD57CE56ACAFAAB620C6C7E3BC7C1F730
+:152760004EDAFD75F5574EA66739C703E951811E9F63BCA211D6
+:15277500378D257F65A920875A722431D7BF1BDA76515F7211DD
+:15278A009B9D2CDEB43AB914E435DA8E776AE01D89782F0E0997
+:15279F00DF4DDF55709DA453F465947F79D0C07B36D662FC4621
+:1527B400C533BB61EE8B0E9ACBF5D74275ABD66845ABDE2F396E
+:1527C9004FFDA15BF83E63EFEBE959975C765ED6009B9133FE04
+:1527DE006B29DE5D89EDDAA1DD19D92E906C01B8ADD66A11DF97
+:1527F30048F03B29E5B326B2860EF0BC9145D485F77F014FC4CC
+:152808009D94B9CFBD2E71278EB8E76B047CE95AFD52B180EFB5
+:15281D00A523C603DAECE05C6D76DDEB8BCA82D6E21B83A7B1E3
+:152832000EE3BAE3E9598B355790D3A90E50DC8376C3BC3C0DA3
+:15284700F320137F9B7A45D8E7A957AC9F5754EB7CBF1874E630
+:15285C00A0840FDFF3BDD47E8065B7B5DB6D873607DBF0BEB4B9
+:1528710012DE07DCDFCDC7A57F21E6512B7CCFE358324E77F2F6
+:1528860028C233D982D251C3F7DF87190A4E6B12CF389FE7E720
+:15289B00A9ACD0ABFA10C09D5F5A632C07BEE2D9D81A729EF631
+:1528B00086DE88624C2D896B83B6A5860563751DC84EC99E710C
+:1528C5008AB90441DCFF507F21C646CE65F4A915BE2ED380AECD
+:1528DA00503BA75FFD85357129ED395A24FA79178C75538131D3
+:1528EF00857575597E9F7A2FA5790E09C2D92EBF9F0F73AE6456
+:15290400CA34F0BEBA2258A784928729FD4DDA637F8B730575F3
+:15291900E284E43BC66F911701E083DD6618EAF83B7B864652D2
+:15292E006911EF8436A54773798F325888569CC7E5C91EE6FB92
+:152943004CF0FC83BFCDFD6E02F98F72CE75C37E6AF37A1078EE
+:15295800DD9A1CB1265E933E80B3DFB83724FB4D7F2FFA8D63CC
+:15296D008FF0A200AF468E1997CD51219B788ED6D576B71186B2
+:15298200FA9B6DF9936321F89885D1F07B416B1464E2E3D78499
+:152997004CCC2FAD37FC23AEA02D1B78CC3B2AE2B952364EE849
+:1529AC00E8DF2D262756A15CF81A135C1E2C73B1EE1E386228C5
+:1529C100A073174B3910FB02B9E37E12F8EC575F0199EFA15EF8
+:1529D600900B5F4F9D91BA28F96DCF07C737181B2FC4EF6538A7
+:1529EB00DFA13DE7793E1E984F9837649F7FB9CE211BDD201B4B
+:152A0000D13342365C781796940DCC8343DEF01C07CCEB782D44
+:152A15003B7E086F76B8CBD0FFFD2FEB41C759D5C936AB2AD9BA
+:152A2A0062819EB3400FB202F909FC5E665CEF946A553CC61AE4
+:152A3F002BB00F06FA9BCEF00E1891728C1B8DB5A3DFE6F28C47
+:152A540018B89FA6CB73D6E8833FC0F79712FCAC18DFFF8275A5
+:152A69003B9E0FFB79C54958ABC6F95E981AEBB3300F7275EC6C
+:152A7E0014F7FFCC581C65729EAAF559ABB553168367191B3372
+:152A93004E6BA29E2C8AD38FAFE21FBAC984E723A5B9F8B1A2B3
+:152AA800CF5D3F73FD4F7B4F1B1DC575DD9BD5AC342B0D627676
+:152ABD00D95D495848232C12C9519C5DB1C8922CC242A88FEC13
+:152AD20010654B9D744612F63AB603B19D84B634C7E784C42B00
+:152AE7005889058FF03015F65A266695480E6E209539909014D9
+:152AFC0092A5761C9152B2E1381C9AA4F638716C9AB8B6EC6293
+:152B110087A436DB7BEFCCAC56027F25ED39FDD13367CECCFB72
+:152B2600BEEFDEF7EEBBEFBDFBEEBB95BB86F37317D82FD98F5D
+:152B3B00D9F7D9636C823DC40CB69D6D619BD917D84676275BBC
+:152B5000CF6E6537B33EA6B04FB0B5ECE3EC63ECA3AC9B5DC784
+:152B650056B3556C255BC196C38CB29375B076D6C696B1085B45
+:152B7A00CA5A599885D887D8D5EC83AC059E0FB0AB58333C4D64
+:152B8F00ECFDF0BC8F2D81A7119E2BE1590C4F033C323CF5F4B3
+:152BA400D4C1B3889E5A7AAEA067A1FDD4D0536D3F558527687B
+:152BB9003F81C2E32F7A16143DBE598F77CE235DF2CCBFE4A91D
+:152BCE00BCEC33EF2D1FF16D9F8A777CCADFF5E379C747C0C3D7
+:152BE300535AF6BB963D6099CEB280EC52D7DE1F63F241F46BAC
+:152BF800043FDDFE6F82FF9CFDDF02FF1207FFC863EA9A207EDC
+:152C0D0054D359B7968349B2C4299A242F3E28C5E1CDC06B2E5B
+:152C22003E487602C97E6C13D9BE9365DBCF63FB71E017B7FD26
+:152C3700CA6D3F17F8656CBF0ADBAF04FC303F2893CE264A2C4B
+:152C4C0016B2F342BDE2909D07EA1187ECB4A8371C8234310E91
+:152C6100F768656DE3B751D0BA4A83D9F6A81BE41AF48BD1B952
+:152C7600FFB0EECB70ADC25433F081865161AA83EC1B26DE2674
+:152C8B006CF26DC2C81E0B84554218F81BE8CF9FE850A9EC5CF1
+:152CA000B3E1E0CEC139D62367C3983B4234D1659A8787749C89
+:152CB500F731AC27A509F5237E118792CB8A3F99B5C3813776CE
+:152CCA00C98B0DDDC9E7B8E51F837831E49BD262831740067A12
+:152CDF008B6F8C9B89932BFA975C33FFBAED4FF8CFE6E7A36DBF
+:152CF40009EB3CB7AC4D93FD5BD9D2E720DD4999743D4AED7F28
+:152D09003A37EB82B686F66043EDC03B5D2CE96A37CA609ECA75
+:152D1E00473BD4E9860E5A9F9BFEBE7B19E204DDB8469A857495
+:152D3300226B471D6CA30570018C5613E456A38C5D05B05F65E1
+:152D4800B883D1FEDC65FC24CEF263F2AB06F2DAA6B96B14217A
+:152D5D0059273F6CDFF0BD49E65A79A099941868E571BE2C35E6
+:152D7200A03D4A18CFC35064BBDE42EB5061834908974CB0C425
+:152D87005CD55046B38EE5F353D5AA94688EE0574834B7E23778
+:152D9C008675CD8548A6C6B8D48ED15E6528A425A84FB46B511B
+:152DB100D26D8AA27F3C3FBF1BE2C4C88E24CAD0D659D8B8163F
+:152DC600A573001BAC33B1A18D961E14BBDBBE272065EB48E02C
+:152DDB003AEF7C002A09F397A4AEB3A482FB3DE87E7505BF8CF3
+:152DF000E5B6E8A2CCB7B2D856FD3CD62B27EB96DD5C4B6FAAC7
+:152E0500C52C69A53C213F5A57C2FFD8889EAA49281CD9F31C8E
+:152E1A00310A7A20B11FA4B17EB5F2FD3A2F9F30989E84791408
+:152E2F00BFEC9B377F13F27F328DFEE8D7027EA373FCAAC16F26
+:152E4400688EDFA6150097F47CFA7337BF1006815913E5A7F5FB
+:152E5900BBD99456BBF205B5B7FE99F043EDE7ECB316093A3FF3
+:152E6E00BC287106EF0EA075B3452B4FA97C665C77C1B828CBA6
+:152E8300DF4A33FDBC21A44668AE836B6D4276775B10E7515087
+:152E98000ED3BF615CC1BDA0221ECAD933E1C99B5F6A031880EB
+:152EAD00A64F035CA7744EDBA93EB4EE79ED8AA806ED68A70154
+:152EC200384B5C5CB13A2C6C87F2625B27D9BE52B42D3E2908A7
+:152ED70068EB74DBA8D0FD02F83F306AB9BF6EBBBF3D3A95CFC1
+:152EEC00073217E75CF311FB693AE99AD2116F77B3AC96F85E05
+:152F010069EB97BF5CDA8AFA10A3B9879485A71F504A4E3DA5BB
+:152F16005EC7CE8417668FA964672DA4DB76067354D780F4F77E
+:152F2B00EAF95B9E3616724F42F81943481C68C3392CE63D7D7E
+:152F4000CB295DC894B61EBAA77419CA26C447A4B18349570694
+:152F5500E87C58C7BAFC61EF6024781CF2967EAD617D24843B52
+:152F6A00F6F8A4807B23D2B68312C1FFC383CF431F2C978753B1
+:152F7F0068DBBA4C1E4CEC4A680AD7A3411FFDA98E3657E38FD5
+:152F940031769F80FB095A6ABAE13503E2EE78496E591683F8DE
+:152FA9009BE3AB5B518EA1BE251DD0F9CC578047BA5BE3D9FD8E
+:152FBE00AD4C3FAC4F63DB8370EC3F6BC19FCF1C80F63348B612
+:152FD300299A6CDB31D4D7F461B20BDF44FD0C64DBCC30F4B3E3
+:152FE80084C6036D25A645F02B30AD15BFB85F266476431E596D
+:152FFD00B2C55A9D49EA9C00380A65C9862AB643EC1FFBA6308D
+:153012006CDC88A1CC9D491A572534F2CF803FBA512E9C6ED029
+:153027007431CEB77A4176C47E32DD306E2C0C66FA8F5E742F22
+:15303C00035C1A536FE40509E0E98232CE60BF0AA5B52CF0E088
+:153051002EC89765F6184F15CEF7A47411301002E09E1FD42243
+:153066004C3F9EA67929F0B3EDD153CAE9DB4B5BD36C504927FD
+:15307B00762B171BF965E9E8B052951C51776DD5945D1D6749C3
+:15309000B694CCFBD39D4BEAAEA13DA3506212D762BD8B92B8B7
+:1530A50027A8D766A84ED69AB680F67513B466DDCEA32CFDBCA3
+:1530BA00CE75A38EE113C6AEACA6E07AA190D903E9B6219E69A5
+:1530CF006FAFDABCDFA8351F369A0037B550D75C298805108ECA
+:1530E400FDB349DE46B63C280F49439B4E42B57C9F4E36F7D6B9
+:1530F900691AA4D39137F0F1437AC4FC1EC4DD66A00D4E616AB7
+:15310E008F8A79BA4E4E908E5AEC71C66A70BF3F74846C05F0F8
+:153123003D432AD469D4D5B3534D95B1D9FD23876BFB29ED8BE7
+:15313800FFC6FFF0618EE8427B1E7EF311D203A45B7670CD1FF4
+:15314D00FD5892F4B5B0CED6FE478AF63F8CEC88526D0EA543D0
+:15316200E6231969A5A60AD76B6AC91A4DE565CD1005DCD3DEE3
+:15317700A3354577B7E1B9B1C000B41F98B75627D07DD808DA47
+:15318C006E3CD36EF1FDDD86DF145BD18FEC8D16F643D2B4E610
+:1531A100EF42DCE446F446A28375C69963FB34D4CBB6CE365B69
+:1531B6007720FC02F2E2D6A0CE5E86E8C7A50EA8C14583C60317
+:1531CB0051EB5C2CAE9DBB7A2CDBCB3716D921E03EAA912D62AA
+:1531E0000969AB7FED20D93284FAE33A346F022FCB9D277C7B31
+:1531F5004DBE57A4B9439AF6195CA46B6ADDB101F35C03ED4235
+:15320A0021BC9CF945ADC95C102EE6F1C8DB918EC4DF0BBC1DC8
+:15321F00F8FC86D25EBFF9BA4176DBFE11DBE190B1E5CD7CA012
+:15323400E54DECBB162D10D77E73A7EED246546FA7B5D7EF02FD
+:153249001E81F7CB886C64A9086D65211B09231DB5A236AA591F
+:15325E00F4D2D3A4F375AE9FDA18D00FDD3CB3F45F5336DD9182
+:15327300CE9806DD48D7B934251AD8F478271CBF5B5AFD4FD299
+:15328800A29C6891B6F7796668F28EB4281A6B1D3AE8DF477B45
+:15329D005995A1629AF8E2EF0F93DDEDD8C0E4857BDEDF26C538
+:1532B200CB605C1DD0D1B636F2AECD5F2C6D9DFA2F871F59FCB0
+:1532C700A31A68E65BA4191CF04DA421D6D5DAF3B1CAC0F230DC
+:1532DC00EFC2B9A882BC64D1A5A688269B099E94657705C27175
+:1532F1005F5132771A9C9CA4F6846EA5C8BE40A4287DE4930561
+:153306007D5FD2134EB309D2DB6C42DA0F4C28A2EC26DE1C225F
+:15331B003D404DAF895ABCA8D00FA1CEDC061C8FE17BFD29C2BE
+:1533300001F45B7FEA0F567DCD39D76CA18DFBEA60AABF06645E
+:153345000199650E8658F660949907AB7F9BF7C07712DC93E0AA
+:15335A003FD96DA77FABF8CAB9D9F1ABEDF838AEEF7FBDA84C2E
+:15336F00D4C780F947715AB2CF45771668FAC57BF8655DB87E3E
+:153384002E1F4DDC37754C2985E9062F8FA4D04E49B9FC448ADD
+:15339900EC86D37E5096CE544AF22198B72475D15CD27AE3FDB6
+:1533AE00790FE2417B30EF999B67316CA4770869BBE407F5F373
+:1533C300CF6A2023E96403C56A877F6750DBB56CAD4CEF0279DE
+:1533D800B115E4A2F7D236A79F1DD193AE94CEF6F1BDD3CF6A0E
+:1533ED0046D29536BAE45DC6EB17B17F24ECB9C980F11CCA42CA
+:15340200407FDC5F95A18C629C5C787A363E717FD796672D5DEB
+:15341700687D8F8EB23307FD0BEB086E63F5DF82BC188A914D54
+:15342C0074279FEC8F67F2697C2D2FD4E2D9A16035C8F103FAC1
+:153441004928F36E16D798194AE3BA986836E9A5C7C3EAB7121E
+:15345600CDE1C1F6F659B26519C375E276EAF765DCADC067AE49
+:15346B00D765339666D22B862034A8B8D66CC9958BDBCA61EE8B
+:15348000E2AA53A80CB4878769DC0361B5321A8E944399FBEB54
+:15349500AF6DAB3565181B9BF46A33A47362A73AF895B0E6CE17
+:1534AA00C23C31D76E387788A0EE07B374D041DE6C0CF3B8563E
+:1534BF001DFBD424D36F191552B87FF857F43557B896CDACFF5A
+:1534D40057DB7A174D363F0B013F6B5750AEF7C95C88E62A504F
+:1534E9000FDEB11D937B64B226BB47ADB1EF6FF0C3388DE3317F
+:1534FE00CB7DC7F072CFA9AD0D95D7B0BAA97EC6CE6912FB759A
+:153513009B9F7B59DD29BB5B51560C01AFACE526D440F048BF54
+:1535280010FDF5D25AF8BA4EED26BBF4C827AB56A26EC011FBD2
+:15353D00BEA1843605E3BE2F7158F5D682DC52B0CFFCCE6F157A
+:15355200C8E6F84DAF288BF8E2653067F98ECECC470E8E83CCE6
+:15356700556BDEAF23EFC276817BD85E18AF9FAA19591A05598C
+:15357C0007C7A14FB875926FFEE9412DECC8346FBC997F4B99EA
+:1535910026FDFBFC5BCA34ED6F25D3C45ED04CE77C39F21CC0B6
+:1535A60095D0707B5B39E93423DE8EB5F98FFF07E47F4C5B0B28
+:1535BB00B87BA05D776C76109E828943053C05CD2561E11CEEF2
+:1535D000296D99E44F1C437E1D5C68CE0B835BF79901FA969B53
+:1535E5008BE8AB035FBF5CFD619C8DB8BA5F564F5EC80B880779
+:1535FA00AC6B8B5D7766D7BDF63275C734E90BEFBDFE8B80EE1D
+:15360F00D5C85763BBD2B1D7E7CC6FA08E747744113D5B8AE3A5
+:15362400C476EB37B0B47623C8F0CF3F35B254968F4F0297D654
+:153639007C1C8CB7D219C36FB74B1EF505A49F1B77B3B39A97FE
+:15364E007B91EE4FB862E5CB6A28FBBDC8151D163EAF602F502E
+:15366300DBC3FE7A05CE67426709A7D8E6703D17D784EB4C771E
+:15367800AB13A7EAF8D305BC57415A491E48272A92BD18F72EE4
+:15368D005CB28D1D4AA32E4AC9D4310C1B759D3CA6EA799847E0
+:1536A2004178937C7B1B7E119EF32BCA966DBAF91990177FAEFD
+:1536B7000BF263A32DF2BF1AD5E7ED3AC6862645D437CBACD512
+:1536CC00AC7F9C4B0D4D9E5B61A53F0278F3DB795D58B1BEED6D
+:1536E1006AF6F5569A0B15C5C5B49847713AB4F7BEE5DE334AFE
+:1536F60048FECBA5E88FE32588D21FC7FF0771CC8C0D65503E7B
+:15370B00C5B4E5A8630FB8C4F361B5BBBE4A785D28838C60E796
+:153720005F39EBBF2AECB2FED3E5F2FC307C7557A525B763FE8C
+:15373500AE8777A83437FA21F00A90BB8CE8238A144DAAD5302F
+:15374A0096D079BD7761A31F5F1863525C6AAD8AFB984CDA4A08
+:15375F00E3901480F1C41E87684CC2B0F7301E3963913D2E5D94
+:15377400763CC2B108C7A408D9F4288C291A3B618D29563932C9
+:15378900AB965F3116A06C01E394206F37BA5FCD0BE5192D5589
+:15379E000E7047A2C956677E580DE31AC6697AD5A1F7A05EDB5A
+:1537B3006ACD2B733FA0701DC343801F4CCF32CFE97417484EF5
+:1537C8008379654A2BCD24133E2847CA1C4A639F2B318F699847
+:1537DD0027B6356C734DF2B3A3D8A6CEBEE1C86B36CC00EBA1A5
+:1537F2005D5F813E3CA0D37959B439FA5D6B5CDDF3CA4CFFF2E4
+:1538070006ADF32F82BD5F3659C53C208B7AF62DB0DC719E794D
+:15381C0036BB98670A5E4BCE6EB27993A523E2C6BB03FCCE58AA
+:1538310098D136039EFCC73BD45520CFBA07C6D491DC98522753
+:15384600BB3B17CA1FFC30AE9D511AA9592D9C178D3540BBE016
+:15385B0086F87883EE96701D8E1B7A716F73849D1FD0CC1378F1
+:15387000B9D15C797276F9AB12CD4BFFA4722ED1BF09F53756D0
+:15388500B10A495AACA2BE2DEE75476A58855BFA06E9475E9528
+:15389A0079B30B75A7825F0AA3AC4B3A51645F00CFE5423CA71A
+:1538AF003CF4EF02F78CCD6E9AEB94E3BEF81341B47DD3D4FF48
+:1538C4004610F36D253D9F5C35AB10E363C05797A8EF93B98E87
+:1538D90052482FC61B8C0BE0CF7F6940B7F412F921679DC02DFA
+:1538EE006D517F0161685F6F04E340BD704F4F46DD29F0E3E3FC
+:1539030063C651F487FF17618E7ED64E877B5BCF813F7EC78161
+:15391800C6783EF0A8CB3A53398234F74FA31D4656B60FEDE209
+:15392D00BDAC49A71F5450AFB51AE737D2214D100FA83D40DB6E
+:153942000532DF5B66EE21BB48B5C00B8326C61FDEC26D1FA1AC
+:15395700FBE170AE7355A66BA9245A672FD0F6C97CCA736254CD
+:15396C0080388215C75F9DE19772FB2E4DCB6265A4EFAA03DE24
+:153981002201EB4C23EAB7A0DD41DCCF37C18F49C9C2FE1A2F08
+:153996009F37EE02BAF1801711FA66BCCABEA3720E7D437141CA
+:1539AB008B9B3F3CC83F3DA0BEE177F2AD2DE49BB2F38DDBB65E
+:1539C000677700AF385A86B695E47E964B18B4FE2E4534AEAEF2
+:1539D500BD9F379B0CC1443FA095D94EE5579BD306CA4392991B
+:1539EA00813CE3FDB82EB9A3668342BCAA6E637FAD8967CCCFD0
+:1539FF00F6F3F2678DA341AB7D34429A263337DA02E923905F61
+:153A1400D702E609417A0BB63F4B236C68A77415CAA076FB725B
+:153A2900D545FBA3E6EF8C1D3531254A792AFD317043FC83ABCF
+:153A3E00E11B87BC4B614E70A3B9D7889A0FA4BB4D7D34065FA4
+:153A5300DCD38BC17F16C215282BE7B36DF1B20CE1009015D890
+:153A6800519351FACD8C711BE41B07D8FCD85E01572DF015E0BB
+:153A7D008B362E6508AF85FFD590871FBE8D3077DB00FFE716D1
+:153A920060DB065C815F37F8F1C06F9E02BF50D0A2477C8E4D94
+:153AA7005FF7D30915DA5D854FE6979714D18B4378E47103D74A
+:153ABC00A042F2B826E0FFE5F4E5E83C48448BB958C5D5995BCC
+:153AD10022D86F4A3B642D4B3A81CD7A359E6991068C52DA2366
+:153AE600E6869C3C3250667D7A8CCE0570350975C67E4B14E2A1
+:153AFB00453406F90D215EFC4D05DEA69CC231AD5945BBE28BDE
+:153B1000E5DEA56CD32B8353CF32E6E4C3360D68999FD8FB05AF
+:153B25009BC63413FE51074328C0D3A12FC47105C39EB5F48CEF
+:153B3A005B1CFE047ED99FA0AEDEB2E502C00A3207C1EDD09B26
+:153B4F00492097DBE9826CF972B6A983F277F46D310DE45551D0
+:153B6400C9BA280CF32A0B5E8A2FECDF7E6E461F5EC2BB96FCCD
+:153B7900FB0A75ECFA31D6F1807A030C0DD29726F4F88F11604E
+:153B8E00B44D64ADF7EBE0CEC03B096F16DE1CBC26BCD3787B99
+:153BA300758E0CAD3119DE50CE8ACB360D5A75B574E6C9CD7E81
+:153BB80039DB2DCF7147E7B8E373DC8939EECC1C77768EDB9CD5
+:153BCD00E366BF9A53FEAF8A74FA013FDDDC6CFB0393483BFFD1
+:153BE20064C16E531CEA161838AC56D2D9503B1F9873E3DCFA61
+:153BF70086F8BA48E0D8849ECE219D66F03605EEB3F09E83F799
+:153C0C0002BC02D0A71ADE2678DBE1ED86578177C34FACB8ECF6
+:153C2100D004E12DE3D01FDC8837BDC88D784B14B9116F1B8B77
+:153C3600DC88B778911BF1162B7223DEA2456EC45BA8C88D78AC
+:153C4B00938BCBFFD58C5D442A1FDC818E8C816D1BF54BF97BFD
+:153C6000D65DEB9C6B279C5DCE3E03E0576445F89D1BE74F0C29
+:153C750047DE7314E417908DF427E6310FEA1AC29CBA33CD31E8
+:153C8A008F00FFC0673A451823CBE545D73C05E3622DFC231DFB
+:153C9F0079699B7A971778D67C5671076BEC8CCEB778DA4DF0DC
+:153CB4001F996FF1B23AD6B8DCD11B91D1CE2F8CF93AE48138E6
+:153CC9009BAE84F11BD29FAB44D9E1D1193B0A20EF9DA91F80D0
+:153CDE0071793FCA08FAF40AF7F227208EECBDFCF8E48C73B8E8
+:153CF3009789E311A0D1531C4F8472B7DA67BC41DE597E16F2D1
+:153D0800F290FC3E9B8FD502BC9B251C0F51BED8AEEF88E3B99A
+:153D1D009E47F52DD1FD547FCF87DCBD92DCAC23CF6F03B4794F
+:153D320057EEC6B5306DE33C5CCF1FD399FEA81E80B97B271B90
+:153D4700A4F8839E0985AB6987B175CCC07B8078905BC9B66F83
+:153D5C006C587B6A3E8E637ABFE44D511E47459021218D203F57
+:153D7100AAF330167B2A715D6ECC401B0688E746C9923F10D617
+:153D86009C385BBEDB378F553C01F965E6E138D3A827696C6ACA
+:153D9B00A2B109CF137235213A9F7EF662DE539E18E874C79ABA
+:153DB00054596ED05F5CC12DBF0BD24CCDB76422070F3E5B5772
+:153DC5006B66FD43D6A7A7914F6D25BB6B98BF74FA030A9ED3D9
+:153DDA0040987DD1B1A53CC82A3CE4390D79F6824C85E7407863
+:153DEF00D265A57138407607A62D9BA17C7CC21065EBFED03C4A
+:153E0400E9413FAA0580E7F3F26306C6AF043E4AF7A59780FC2C
+:153E19008C770C16DDDF721EF2F8511CDA5E1C6D16587691BFD7
+:153E2E00CBC63A4570E33883B88C9633CFEBD0665F65039D0EF2
+:153E4300EC164EF6116FC23CE8CC045BD2E9C07D1EE046FD401A
+:153E5800A04305DAF9C0B6C1A3DED985BCC7B1FB5D5CA7605144
+:153E6D009D9CF106EB45FBBCC0EF102E777618E039AA511DA462
+:153E8200319C7340BDB7CFD89D8D0F68231EE6B9016075D27CEB
+:153E9700383AD8897BD4FF7CE0E7FB45B9C50890AEA70A7D760A
+:153EAC00B5E1C0CECBFB691E86FF38C64B368ED6D8703A7A6FBD
+:153EC100362E03B8BFD60261BE38BFDC5F32D337244FA36ADD4C
+:153ED600E39AA6F28CE3E3CB5924827BD6796BEF219FFFF2F1E0
+:153EEB0008F82575BC5BC09BBB57F59EBE56918EAF54EB645735
+:153F000017E9B4E6B6A30E89C7533C6EDA70B6B225342E4F0ACC
+:153F1500CCF334D4F167D0F6D8A6AF525E185F405E1F19A77B66
+:153F2A000BE8FC47570B9D7B00395CFF6662AC13CF44207E1FE7
+:153F3F00887374AF9C8D779FCF747756A1BC6E1ED3CFDFFC9DFD
+:153F5400E53F0337D69937272EDFDE0047567BB3DA8F681ED6B2
+:153F6900779BEEDE60D7049587FDCCA2A74C3875F835DFB5043E
+:153F7E00F729315CAFCB8E459CFAC6B8D9ED12F5122EC6B94E46
+:153F930084DBC1DB4BD971E201621C78825DCECF208F775BA70C
+:153FA8003AD3BD3C543EBB2D76BF9EF7AC063A8AF1A2BAC88FA0
+:153FBD00E9A87F56A80BCC61ACFA3715EA8270F05D1FA4BA1001
+:153FD2009EE2636F8927B7D4A8DAEB1E79ACAF707C17E9FAE127
+:153FE700DC688FCBE6138003E0E99E82CDF1DC8076F2BF1C7DE8
+:153FFC00CB16AA13EACF3A696F837448EF34A429E63377BF6960
+:15401100B55751DEAFCBF171ED73D18930968D6D51DA7CD43A54
+:1540260057969B80F9C2A041F6E1A72D5EEEF415DE3C60489E81
+:15403B0009D50B3CF77E985B8926F215CDAEFF9199FA43BBA8E9
+:15405000EA3A46F5AF02BAD9F42D8C21E5C8EFA83F68AA6507E9
+:15406500DCEA0F17D1164AE4D0ACFEF09BEC21B28F82386BBD10
+:15407A00C53AEF8DE53CCC863BA12D5BFDA46BD06AC700EB5097
+:15408F0002CF30EBFDBBC9B6F9B139F4D62D7AD71F5D6E805B09
+:1540A4008C8F17D1F5908E6966E83A6ED72B45F5429EE3ED1A8C
+:1540B900A63A2DCCF0CBB1ED3BB42CB45FF0E333686B3FA90FC2
+:1540CE0041FFB3ECEC5BF5F802B44FA72DFAD8D1CE4A281F618E
+:1540E300B900B02C84B677A86C76DB3BF99FD0EEE422F8E200AC
+:1540F8005FBC083ED981CFE24B84CFAE4182AF982F4C4F5B7B51
+:15410D00C8F8E5E3D69DB37A34B9B1B268CC49FCDE694B85B9DC
+:15412200AB8F454608B768CB223D9DAF28B43D906D7E81BADD7A
+:154137005FE5AF95E2D6FCDB17DDAF3E0969020D7CAFF7745A0A
+:15414C007171CCBB00C3728774E97446E1610E7E10609570CC13
+:1541610081F683EB92828072A7A6058347FA65909112F78EF437
+:154176006E41FFD4EF90876F114E1EA37DF073F5C3CB58EEA8CC
+:15418B006E84B85ECCA72E398C36C1FC5578BF10F827613ECE96
+:1541A000A4618387FC708F93DC502E4F7B2AC306A5C3B2F461E7
+:1541B500D4175D5097E13B07AC345B1230A7C77511618DA6D2CC
+:1541CA00FDBCA87364CFE91156CC7F6BB7A694F49C5713F9BC33
+:1541DF006FE4239A8275E6214D5DF2C03A841FC74E840561C3C2
+:1541F4003D8476802170FA88521587BA9EF88AEA631AF0F08C51
+:15420900F22D1C17EC3CD1FE3CC8C03E4CE7D47D08F24FED3C5F
+:15421E004CF7FE627BA1B8B1435B84EDBF534D840DEA8475C1C0
+:154233007B41912E8807A61FD3109F6DA83600E10E2ECE16F0E9
+:15424800609555C003AEBFE62C3C04BFCF77A67A70AF79421B7B
+:15425D0000FF11EC2F8013F4C3B50D1C832D788F010E0E289865
+:154272007F49CF6BEA66C2C301C50BF5431C48782E05F74EF013
+:15428700CE0D280B6DDA86A0FCBAE0B97EC75EAD65DF04E6FFDB
+:15429C00AF30B6A326A5BCCACE698B42ECD38D32FF61C79E62DB
+:1542B100EE9364AF96ECCE74D31AC19251EB6C608AD245CD6D7D
+:1542C6001AB46D0F7C711FCDC8BD36D3CEF13C18AE55611B6D33
+:1542DB00C1B934EA1E86DA35F61AE9B58DC2989B4D34B97B3965
+:1542F00021A2F289B0BA0760AD5726F19E385D977777D1FC14F6
+:15430500E248C03B44F9639D82FCD94E49FEC4723E26E3789DC3
+:15431A007D0EE461FCF6E35C2AF628D9BC0D74C886953FCA8CB7
+:15432F0063D91084B540FA2648DF08E9D1AF56FE44A79307B46F
+:15434400A74E11C205087F6EC567293F91E666AF6C71E26CC493
+:154359007200267FC7B495B76EC18D388A60DF00385BE467BB1B
+:15436E00F88E901183705C2FE882F934970AAB5202F7D2ACF8F1
+:15438300981FB481000FF9603CD2E77E0DCF015AF769601F6EDA
+:1543980067F6FC1ADBBC346E97B3AF1F6D3254D3D97DCB0FE76F
+:1543AD004CE8876D2260E9B05F325FE2388B9E057FC8BFD6990B
+:1543C200FF901E1F944F7704650CF3B54BE75CD6D9C17D3A8668
+:1543D70021FF015E6B95057102B9AFA9FED35F53505EF5771D0F
+:1543EC00B2EEE580303FCEFDD9611CDFB58FBF50C26AB387DBB4
+:1544010036C2B827DAF30C4B67D09273D066BC9038B0B40A64E3
+:154416004F3FE61BDA67C151E0932982CF1F4D46C83E04B8311D
+:15442B00CFEAE8785B6D519E85B90BF05C4A6FF3CFDFD8ED19DF
+:15444000EB81733B80CDF71CADE934CEA4293E8F48F76DDFA789
+:15445500FDF632E9F6CF4907ED5DBFDC7A52D4DCABFDFB65D2F4
+:15446A00DFF52ED2BF7C997491778477AF76EE32E9DE60EF5C67
+:15447F00DEF49B73F6D3707DA7B8FD01ADA65F9BBDBE31373CC9
+:15449400F1FADB874FBF53F8FF76FE73C2C5E2F6FF76EB03FFC6
+:1544A9001FFE47854B45F8F7CDE54BFF67E0B7DB47ECBDA5C765
+:1544BE00FEB580974916FB24D9B869EA1F94E2B7AD82AE287AF2
+:1544D3006F573508C7BB56C5EBB6AB74D607656EEF0675DEEA92
+:1544E800EDAA2CDFA9CDBB6E40F5F7688AC835A8FECA063509AF
+:1544FD00728BDDA7D75D80B159F236A998DF1F9BD7DEEB35652F
+:154512001275FF7A70EE12D7502389974B7A3F073C392036A83C
+:15452700E53D2DEAC3D7372BF53DCD4A50BC4D1D2CF98082F66E
+:15453C002017F17167AEE2C7F83C77A54A6B0FAB078877200F1F
+:15455100A9AF4C2AA8DFE584FB28BC59757B1324DFD5DF9450C1
+:15456600697FC9BE2F7C2E0CAB6C182A0086BD0043A0A87C2C1D
+:15457B00B70E60C078942FE45F5CF6053BDFE9A27CF3F967F20B
+:15459000229E150FB3DEB578473AE49D28896B888F3CB3F2BAA4
+:1545A5009AB10555801B11CAF4AC69061C35288BC416B5F6430B
+:1545BA007CAF9B0DF4D57F9EEFDD3B3F4934C0759110C0817BDE
+:1545CF00705791DD9019D81126929358E21EAA1BC074D286E933
+:1545E40028D65DBC51ADDFB956E52A1DD8F2171DD83A01B66A62
+:1545F900B181FC1320203AF4F254B6A822C1B45D595499547755
+:15460E006DDD51680B88E73FE4F3360C8CEA893695ACFDE3E983
+:154623007BB0DC9C0D075793C2BBA784F99A05837767A3EA852E
+:15463800F2B06EBDB62E3F2ABD115ECA66F0520F6DA7624D974C
+:15464D001AE889103CDB4AB62BE580970A31A996B264DF0EBB47
+:154662006D2EA6BACF947B0ECAD221CC0BF802BAFB1C1890F65F
+:15467700F5DD372A280BD5F7DCA8CCA53F74226F39ED1BCCF4C2
+:15468C00A7FAA93D148F3BD5A2066E8AAB3CBB539D07711FE630
+:1546A10058D06DFF1BF05FD10370427BA9A88CA8DAE31DCADEFE
+:1546B600131D4AC5A9356A4003BF9DAB55ED233740DBBF41C1A6
+:1546CB003610009CD6AFB170C1C7B95E996DA0B60D729ADFCD92
+:1546E000DDA28AF112BCF7C4EFC1BD9ABAEEFE79DCADAAC8AF72
+:1546F50052C59550DE7577A8E2EA1BD4E192554A04D70156CE75
+:15470A00C42F0B5AE766287E326CC57FF233AAF844873ABC35B0
+:15471F00ACB861DCF53E7E9B52FFA1925EB48D2C24C27D9E6CDC
+:1547340047DFFD684F4A0BABF5A76E51B9931DAA067139618691
+:15474900169BB08F07E99CCD3AB4A5220C40BAE31D7D34D76B64
+:15475E0067BDA5DE505F99B7BDAF3EB556D906BC4106FF21F8F1
+:154773007E1A79CE4FD6ABE250878A72B52CDF8AB29D20263FAF
+:15478800A3726BEE5429ECC90E080FABC38033A43FB6719C93FD
+:15479D0094FF03D75B7F0A70A80DA881539F512B4E6EA736B0B1
+:1547B2000BDAC03CA07D7954EB2BE64B4877A41DE928DB34C57B
+:1547C70036791DC0D28BF0039EF16EBF1EF84F96DCA5CC837208
+:1547DC0010FEC1ADD6FFAA8BF900F225C78D71616C58B7278FDB
+:1547F1006B3856DB36606A85F843BE0773AE054EBBBA1BE290E4
+:154806003E39C070D71CFD4AEFE3B54AFDC96AC06DB57AB97630
+:15481B00F4129B6947BF64563B421A94433B0A8A77115E1EB6C7
+:15483000DB12B6A380067E73DAD2F6C49FAF2F0F6E00FAC4FB9D
+:15484500B7B35BD7CF0BC6FA39F10ED57157446F5D8F749A376F
+:15485A00B0B68F9DE8ED73BEF52FBBE87E9DF2C4DABE8A6C6F1C
+:15486F001FE7019A5FD9A0B9810E1781F688BFAB8916AEDE0ABE
+:154884006D0BD0E10EA0C30EE2E9C5B428B16991B4EEF5F17365
+:15489900C29550766CDD14D105DB4D6CDDD13974019AF86EB218
+:1548AE00E9027CD7B7B6882EEF2BA2CBABA43339D3B7B742BF10
+:1548C3001E29A213D987863680FE9B6D5A9D063A39B4D9F01E37
+:1548D800E971A6881E3FB2E9817D3A60D3E2123A006D8A695101
+:1548ED0016FDD4FAD2E8DAF5EC6ED62B663FD5374FDAD057C62A
+:15490200FE7A7D79E26FFAC4ECADE4AEFF3CF5579FC8C01DBD70
+:1549170093F0CE6F6ED05CC07B2F96C5B47207EFD04F2BC4AD95
+:15492C00C0FFFE42AD5873EF2CBC975F0EEFA9C548F322BCC7E7
+:1549410009EF4E7D8BF10F3CDF779D8D7F5C13C17EE2E0DF5732
+:15495600847F17AD6D58F81DB1F15B897C0AC2F0DEF0E23EE01F
+:15496B00A47F89C6058B66988EECD3DB74B0701E9905CB97015C
+:15498000CF6286EB7D12BE49E03DA59007DE9FBCF763B7A9F5A9
+:154995003D5D8A54B254292BB956C1362C02EF61273AFAF6FE68
+:1549AA000B849D5AA3F84A3EA2784A3E6A8571ABFAD8F537F4B0
+:1549BF006D8BBB7A11AEC5F69DF2D046BCA5B28BC648F4477B35
+:1549D40018CE1C05CB47BB9125CED86D8F1F180F75A511AEE79C
+:1549E900F3793FC429F4FD27A1EFE3D87506A693B85E82F2017F
+:1549FE008C75FE27ECF8DF82FFFA9779FCFA8E505E2975976B5E
+:154A1300FC36D4D3629C7597298C2C795F74FC768369A4F38504
+:104A2800FEFE99F5D6F2FF06E2E5D1A4A89C0000A7
+:00000001FF
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/sba200e_ecd.data linux/drivers/atm/sba200e_ecd.data
--- v2.3.47/linux/drivers/atm/sba200e_ecd.data	Wed Dec 31 16:00:00 1969
+++ linux/drivers/atm/sba200e_ecd.data	Mon Feb 21 16:32:27 2000
@@ -0,0 +1,928 @@
+:150000001F8B0808AC5A10380203736261323030655F65636426
+:150015002E62696E327D00DC3A0D6C14D7996FD7B3F5AE71CCD4
+:15002A0078592F3F8DD70F0AA949E8DD022E07F61A1644AA40C3
+:15003F00012D88A433EE52268844E8924B571792229D1B0F8EB1
+:15005400013B7DD0C7608813E1640D5E58529C6C909D101DE4AC
+:1500690016357749A4E4BA8A7227541DC9AA17295C4A2F76455E
+:15007E00259438EC7DDF9B19EF7831C4A1524F772B8DDF9BF742
+:15009300BEF7FDBFEFFBDE1B3FFCD3BF7F88B808896E2484FED3
+:1500A8008890844A880EFD1CB4BBA00DB710128396439B8076CC
+:1500BD0018DA4E68B51FC3036D16DA1DB8364E88026DE92FBA6D
+:1500D2001EFE486452BF7C63D90D63AE825E0863FB54E1A984C2
+:1500E700782F999F6AB59F9E3C49B19D522690D8ED9FFB737D9F
+:1500FC00FCD38F45DB66F353D2B6AD1433AEF2F2F209D77F491D
+:15011100BE34E18787275C3FF52678EDF13693B20B7EE47FE17D
+:15012600E71A20BB45FB4AA95D5E29DC72DD983C8589E52B4C68
+:15013B00927E7959B9A987A7DA6E4DCF24842D778E97CC7F63BA
+:15015000F90B6D6DE8BEAEEBF97C299D49C95956A43F7A5BF4D5
+:150165005F7C512AA1FBB7D87EF4AFBF99905E79919E97FCDF83
+:15017A00FFB93C759E5BCDF3F48DEFDA29E89C2A8EA109DC0E0B
+:15018F005FF8FFFE2B387E24ACB3FC6765A432BB6F911CF4C674
+:1501A400C1977CFA72F2308031121A8EE3BC3E026FE14E96FF67
+:1501B900025AF9AA21793BD46B5B3B1A708EC8A429FF1CF1557A
+:1501CE003E4F7C81FDC4977802FA5DC447C2618EEBEA932EC057
+:1501E3004BB79000C012130F873C52EDEA50657DA14AB86BAFA6
+:1501F80014D4B75C5C467C1D4F126F20B8231E269759EF9EFE32
+:15020D009D846F61249CE1FA03844C0B6A716FD52F20EB9C6518
+:1502220035C1447C7AEB6916F59268404FA9249C341086C4F6C2
+:15023700182477ACC79FE300570FFC87E3FBC3A4657AEB6A1692
+:15024C0085F4D4BE7FB34AE4F5AC7D7DB3FA3C213546D2DD045F
+:150261007C32C81F7230EF6A9E22B7A8B81EE7116EDFCCCB8A9D
+:1502760067E549751FF5B490DC6C5641483010844C26EF66BEA1
+:15028B006067FCC3B9C4E721F3D53DC3EE1669F72655BAB04CF6
+:1502A00095B6AC654B008EF03EFD6EBA6531EA08F113F958A63E
+:1502B500F8F4EB015853B966BE7AB950A8FEB04D8DB4FF933BA0
+:1502CA00021254BC2478DA75DB3C456FC2D306E429775C5F2546
+:1502DF0078A202FFB7626115F9D9AB95B5608BFC601B04DD5402
+:1502F4000575C0F90BA1C39DD5640A91FBF4DC8A2D0DE780D715
+:150309001DC0AB3D1FAB26E3C3487898BD07DA0F053964FC6180
+:15031E00B09F6E2C85F4EFDDC054B2B33F93978886ED30B49447
+:15033300768879E085CA723BCEF75CC37918AB1763BB718C8F81
+:15034800E218973A503F887F41CB78FCF545FC0256ACB3E8DA10
+:15035D0034052D8BEE84341DF8D924F1874DFC62BDC065D1B458
+:1503720069396575E2BF52823F5CC47F03AE9BF17F2BFD283F5C
+:15038700BE7DFE1BC41863C362AC4325B1FE8C3D3EF66ED31296
+:15039C00F6BE39FF0257281DAF69ED17F8883C2F83386A5A1923
+:1503B1001BB5E418C30B73E3E48AF573539E9BF37F2BFCD76E07
+:1503C600827FCCEEB1FE1E1B7F838D9FA45929AE521C387FCD8B
+:1503DB00E143B62C02A73CD433A10CE3F647A7B91FAAFA55D204
+:1503F00030CFB4AD06B685FE0DBED990327DD38903EC5BB9A572
+:15040500685F6F5587E09B3474B0AC44A2105B784D2CAD1ECE76
+:15041A00B85B80BE512D77A9570A85A0D33FD6FD99EB3BC4FAF6
+:15042F00CE09D78FAD053C57715DCCE12B18A2352F4BE4DF3E26
+:15044400A3E73F3562F9670D7FEEAC3AFD034D21B14BAC4EB966
+:15045900475D4C7FC5F6DC3B9020F2BF81EF26793FC4F5605035
+:15046E0089631EE0D00FC49222DEE3788D3E00FDB481E324B744
+:15048300A8470EEE8A93DC7B10B366C4F7CDDCA178E9E3ACFDEA
+:15049800FD956A27C4B7F6F7D7837DE688787987152FBF0532CD
+:1504AD00C87598AB92BC1BCF26E134E7D056692EE07F3ED0CF67
+:1504C20033CC96D2CAB56AA12CCB24D72A55EADDC8BAC949C5A3
+:1504D700A50DB0EEB2E30AC28C421A3D4C5E56C05E0CAB886E6F
+:1504EC00F23A8C67712DF4FF45113C02DE68FE6D03E4309096C9
+:15050100DB45AABB203749D1BBD5BB80A7629CBF17F86C6701DD
+:15051600E06D6788F8BC40FB933677C4BBE135950CFEDCC09CF9
+:15052B0087FC728B5FC455F5515EED2E3BA9A05ED65592181934
+:150540001C30B244C0E918E7BB519E705AC4FC2A42FC2496D294
+:1505550047B7F635873457A377C309F0B30106F089DD3F9C0F86
+:15056A00364FF16B85424D9DF26B359AFF9457B94EA8B1FCDB9D
+:15057F009C84327177E57915E18379C83D202BD2385A0672CBE6
+:1505940003461053742C63CEC97F32C0F601EF8697D559078ED5
+:1505A900C3BE4D097EC0EE19B0BBD8136BE99A8829F3A21ECFAA
+:1505BE00CAE3AAB013E634CB4601878D1EADB5725A02721ADA1A
+:1505D30000748276C8A27FA15F800E9016D959D40FEAE5975DB2
+:1505E800DF079D844D9D583CD83A09002E874EAA854E56AC5F7D
+:1505FD002CF0900C0BB60AF9C00FF764AC07F676126B984CB013
+:1506120055E82BFA3CD80FD619159837071F671F423DF547CC48
+:150627009D9ABBB94EF94FD5EDFED9920D9ABB2948DDCDE3ED05
+:15063C007B3FE4F1ACE201DD96CA8CF2A1DC1EB2006AA3679877
+:150651000CB2CABD9BD88E3B896FAFB6B1C9BBE105F0796ED6EE
+:1506660014E1A5ACB002FD803221E3D52B26CFBC5F7F80DEBF28
+:15067B00988492F15AB2470D8C32C12FE9EF63DDD98560AF85B3
+:1506900006ECCF8CF5F4E05E053D0AD9486CD0C0F501D8C35394
+:1506A5001C72BD05754ABA6D6364519B29DBDD753F5B485DC4FE
+:1506BA006BCAFA6BF53A79F216B2E641D6939396B5F5DBC477B6
+:1506CF004CC8FA30C8BAC39435047BBBE1F7A67CB1E3FA532095
+:1506E4005F6DF63BEAD4489390AD2C36430DE9A1E66F635D12CB
+:1506F9003B20628096FFDC38EB2553A0E5B81F85AE5007644910
+:15070E00D12FE4BE8CF5801EFA8A7AC8BD6A209D523DF4801E4A
+:1507230074D043D0D24325E80169074B68831F4E194FF38472E3
+:15073800C0972AEED189F7E6346B6F46C6E6D1C78027EC8760F4
+:15074D00EF3AF72BEE55C253FAB5151EC10BC417D8AF2761BF9D
+:150762007ECADD9543AA6BE659D5D53524F6EC11C79EED297B45
+:15077700C5DEB37E9C3F52DCB335E8FFE8D7CE7D3B0BE05046FB
+:15078C00BF4346AD9C4C71EEE7B1FC943BCDFDC1CBF1EA46B191
+:1507A1005788F48AD452BDAC53F4AB5DEB45BC8E06486C8EF056
+:1507B6005F6EE65EC88572F20A93D6ACC59C974940CE2B4C4D3A
+:1507CB00B05EFDB8C2662694C06E880F77A4541FFA4FCCB0FC60
+:1507E00087C7671D931ABD55AB61BFC6581BD118FA4ADA05352E
+:1507F50041586188A322F20CD3A03568598B1F7CEB04ACF36627
+:15080A008FA9011DF3FFEF0D51CBE01EF84BB6DB3E6764B09B53
+:15081F00E9E04BC89773FE51F0AD1524C1B6E9879693F065A3B1
+:150834001E6581396FB61DCE4A585F7C435A0F9AB4B278CE7380
+:15084900CCAD4A8E3621FE34B9357E5D33D7E74BD637265BC568
+:15085E00FAA513ACA7DA492677758B1C6DCF47110FCCDD958C37
+:1508730034A1FEEDB501FD984A61CE8BF0B1B9803B950925C1C8
+:15088800A6164C8305238BF5A9CC647C22F0A6D48CF11F7DAC82
+:15089D00167D35D76F94D64FEB1E76D43FA2AE642C8AB58F2916
+:1508B200DF196CCD7ACFEA53689DF58F63FD1C0D7D1060A1FEDC
+:1508C700411CD21AA61EC43D0BF2E27E1A572BE3F1F93E2FEEED
+:1508DC0053C31FCCC6F17C5BA75C51FF86BE06E7DDA19D24F6BF
+:1508F10004C39C9E7B40D4893C8BF50E9C875D33CD9A270A7153
+:1509060003EB2B92DB8E7006C2C9C119702E7E5A9C8BA747FA68
+:15091B00C59938181D54B1CEC0F544AE15676212AA8F4F8F3447
+:150930008873309E89CB8066FBFEFBADF3F0BDEAF32EFB3CBC70
+:15094500D43C7BDE10C78B67CF89F2349E3DDFAA29397B62AE9C
+:15095A00B6CFC3B992F33087986B3F373B0F7F4D8C7C4CDB1875
+:15096F00F11C3CA3BA601DC6BA3D10C776BF9B56BC55C7314647
+:150984008A5A40C43898C739A0853569CD9CA4A7C98449A13EBA
+:15099900A222060A9B891858EDADFA15F8C48098DB4EACF36D2F
+:1509AE0091DF1EC423D60B9D9B7024F62763F7BB19657A24259F
+:1509C3006C00670103C726F7FCB3217C16EC1BA8492A585360D5
+:1509D8002C47BF7906F9224BD94BA843FB5EE0366C531F98D827
+:1509ED003613DD0B94C796AA28EB3EBC178056DC0B403BFE5E71
+:150A020060693CEEBAF15EE0EB6CD6FE17B0D944FAE413D8D15A
+:150A17005B750FD830CA2C7939CAEB6D9D6DE290470CBF43DE6A
+:150A2C00042153049FAD7D967D070C8499DC73613C3F729F6190
+:150A4100E39D01786D5BDBF1E9CE478AF1C5E5EB107ADA94DD30
+:150A5600D3689F51E58D49A5A67590C5800FAC0FF04CAA79CD1A
+:150A6B003C8DF05CE80DFC0A748363EE92B161475C9A41E7F61F
+:150A800060CCB93802B97A659F1AD0D07F1A18C81E708580C77E
+:150A950031BED23C564648A3E66944597640DFB5C63C7FE1F838
+:150AAA00E1DA2106B508F7C82F412CEF33EEA4A70D29B9C7210B
+:150ABF0097CE104EFF119EB74C5C4B268B2B79AA880BE087AD61
+:150AD40073A08BE8784634F0DDA6F34DE4D11DF2F43878D02783
+:150AE900290FC2651E30E5D11DF27C2DAE1279AE96C873F536FA
+:150AFE00E5C938E479C7C1436692F2205CFE7E539E8C439EAFE6
+:150B1300C55522CFB51279AEDDA63CC991A23C67478A3CE0F891
+:150B280064E44138D99207FB4B268BAB449ED11279461DF2440C
+:150B3D00ADFB0C19F3B9E5E3750A53EFFB09D2357D04DF975A45
+:150B5200EF19EBBDDE7A47FAF83E43BC2799F065A0B1AB4CB4FF
+:150B6700ECAAF59EB6DEAF59EF17ADF751EBFD1DC0B38B9EE038
+:150B7C00D8D760AE93BECCC5BD03F47BE86B5CD403D04FD337E7
+:150B91007994DEC5CC73C5592303EBE05C51334BF33407939EC7
+:150BA600667FDED3EC053B606D8F3236D05302CF7658BB9ABEDF
+:150BBB002AF074437F337D83E3FAB74C3E38D2DC4E777313AFA4
+:150BD0006E0C025EBC6B5841DE6167B6BEBC5CDC59004C15F5B9
+:150BE50034E2D80B5B5F136359C7D8335BDF1463C8933DF6E484
+:150BFA00D6BDCB6DFC7751D37E886796E8A7F9768B3EF2B4B65E
+:150C0F006E60998DD386455C36ACCD2BF216B26011EF5F514FEF
+:150C2400B3B84BB1743AFC88A9D39CF8EE61CA3EC3CE1F304F8C
+:150C3900C7CD9BF4EEB6700C9A638CFF9D09F3A1850369071099
+:150C4E0007CC651F2DCE452C3DC6617E1DE80F75C7A01FA7072F
+:150C6300399E8FCE099E2E0B3E1FA5CFF15EA1DF1EE3F48870DB
+:150C780040FF03D73D4D7B67526543E88D85CFE692CA0F962315
+:150C8D001F9D424715509B2E592E352D0AED5EC861EE6E319754
+:150CA20011FC56243D8DB3DE949A82A1830B0D98AB5A6EF28FE3
+:150CB700FAAA807D72FD2BA9E98BDAE7161E82B93F367B9A2BEB
+:150CCC00B4F2C6CF2EFD2182387F57CB22B8FEB7BD831184FDD0
+:150CE100E0D269C8FB3B044DE03FA38B7686E019E4CCC444BBDF
+:150CF6004BE026E1682629DA84E0036A8E0CEE89E9172EABAEBD
+:150D0B00F735D87FAFB0CA60268EFA31D75D36368BD6D41109F9
+:150D20006B8602EDB495C755D7FA47A0F6D9CFEEC05C097A3363
+:150D3500E9268D0ED1EE303A45DB23F4590EE705D7FEC701FEB1
+:150D4A007BAC2A1806782A6219C20F8A36619C15ED52A1F32969
+:150D5F001700FEFD7F10B5D5D4600CE0A386C977D2E887F6692B
+:150D740061875D467AA498DB4808EAADB0226CB30D6C93A007C3
+:150D8900B81CCCC1D845B6B4CCBA2B17ED45A301DA9DDF273E14
+:150D9E001E76B7C0318F1D182DF8D1971E85F14A7A02EA055D0D
+:150DB300E8AF0CCE160BBE8370E6BEC25CB9CD82457D5BFB8D79
+:150DC80061FF29A029FBDE533B9625AD6F6D507FC1B896FF8DAF
+:150DDD0011681D62E8C0DBF3AF1BF0CE75E02D104DA9B20FCFF3
+:150DF20039EF1B121D323E69B0F8A1B3D9F52F4D1A4761BD6C70
+:150E0700F1C32D7E8ECE29F283B9EE030B36EBE0277B0B7E623A
+:150E1C000E7E36033FF0CEF904FC6C76F0F39845E33DDC47160B
+:150E31003F598B9F4A073F98AB5659B0E86F363FD8BF193F51AC
+:150E4600073FAB811F78E7C909F8796B71919F8FBE30699C1BBB
+:150E5B00C19C66F28334909FD6D9457E30D79C3161052D37C413
+:150E7000D68EE694310A676A3BC63A3F0F6874906BF434C4E84F
+:150E8500CD4C0EDE173FBC2CCDF0FF560EE74E2AD65D9091B78B
+:150E9A0062CA7F8CE0652EF17B1D79334EFB7959D57995E60779
+:150EAF0058714DDAB868C5631B5601B86ED8DB7E888DCEF53124
+:150EC400DACD37037D05F850E85178AEF0049DCB77D105E03353
+:150ED9000DBC9346C056AB799DB24D35C8A1447D3EC5BAF55427
+:150EEE00A207E093F41C4F53C60FF79E663564409DB6A597D514
+:150F03005EBAC23AB67C97EDA99DCFF66E59C8F6F52E639D97C5
+:150F180056B223B56718DED37CFCDB32DCD30CFFB7E7D9DEF32D
+:150F2D00ACF2C231F5E0A5FD500FEC5FE2E4EB9D30F155D1D593
+:150F4200CD6363B176D6B090F8FCCE3121403B3B7A93F1CDD75E
+:150F57000A378C2B5A3BC77889FA09D44FB08EB7B33B9B26184E
+:150F6C00875AE06A1DF179434911ABC046F2DCE4318EF6C5F74D
+:150F81004F46AC1A413EC789CCB844C51D2BBF8AFF6810E6FCBA
+:150F96009A687BF8A8DBAC7586451B66A4007551554AEDD6878E
+:150FAB00946EBD5F9926A5D4236543CA91E88072186CF9ACFEB4
+:150FC00086E27DEF0FAA8005E0837A9722AF632AFA4185833FB6
+:150FD500BC8390D890187F52AB6CFCC4FE770F2B6EFCFB0A33BF
+:150FEA003F6A63B934C991E73990C72A925F35CC4A3E8179C4C6
+:150FFF00CA8567451D63E6AFB366AC039D99F98F5B303D026617
+:1510140047314F8AFDF09845277B039D3BC6D131F3E559510FD6
+:15102900D97432169D0F2D3A264C0F33E3709A87AF12D21B76BE
+:15103E00B5941F48A981E83CBCDFF3FBB5EF468290ABAE5E372C
+:15105300E5FD40FBEBC6CBD0F782FEEB14380779061290B39AFC
+:151068005DA1745CA678DF1B66C92CC489A4AB65333D652C022E
+:15107D001C92FC3DC8435D3C14DD1F3948BA13788676877AE21E
+:15109200D23D50A3C5468CB974C4705BBA8ED02E234A0F1A8197
+:1510A7007C8A734F6AE702DA67605C895D0039F2FD5C069C38D8
+:1510BC000E276206072EAF93E6A617FA9A9DEBEB9443AA61E19E
+:1510D100C0B5D8475C147049A1FA78B464BD1FD647E97306D4F3
+:1510E60010D6FAEE09D7E7FE1173537D1C7909C3DC02A833C232
+:1510FB00B48BE1DD96413A120AFD2FC3E3C238779A19E470422A
+:15111000D23A0C3FE46037D6BBB17EC3AB751B95DA39718F365C
+:15112500DE8FCF5A7EAC8FF3E331FFCDA614D9E1BF55502B8C04
+:15113A00F928F801DA0F7DB4FCC0805A43E6A9A66CF5A66CD11A
+:15114F00BE66A73F0768170F6A529384E766C29917ECB1733E0C
+:15116400F1E1FBBE999DCAC54DC4F7E2CCA422D3F9C236ABD16A
+:151179000EB096AFEE7E085BCF52F13F2D15B383264E79893719
+:15118E002E43FF568F0947444B8336DF14F65D1D91AB16A81DE5
+:1511A300EEF90F79AC71EED71FB2E7F1FF6AE4E8DC07251B479E
+:1511B800B4FB41BFDD5F591C17FB04E498438E36617E801A931D
+:1511CD004E8BF5604D631CA2520BD51883B37A0061360998CB74
+:1511E200D6779F4EBCA3A0247692076973837DCF82DF034657E0
+:1511F700342F36BFD19B7797884F4E7633C487637EB95B7D077F
+:15120C00713AE82F17B829C33B5949FE0CE87719B80EE95BEBFC
+:1512210032B80EE89D71F62F3AF158BF83B9E39073F0FBEF1552
+:15123600568DF74FFC285B8BFB92DE1B09D2798DCC8A0F3FA1C4
+:15124B000F35EA629F778AEFE5BBA75C413ADC2F3F67DE75C28B
+:1512600018E4AB1A1BBFA4CD6558B309D81F7EDE4272FD7C9ADA
+:1512750003B6C2829520374F16EE10F0BA0AE2DD0B5A5D13D6FA
+:15128A0008E677FE432A9C9E184473435AF339F8E46CD63B4C08
+:15129F00104FA67AF42893454EE83FF3BB42A11AEF06B789B5BD
+:1512B40069B17681B69FD5C84FAB776AE759448333656C9E811D
+:1512C900F489DC6F081EB09F4B19923C5745DC52FEA88DDBE4E5
+:1512DE0011F6DA589FA78C2CD058A44D6FACD2A6477EA04D6DF9
+:1512F30044BE376975CDB67C923C5B2D956F3273820F7BACC455
+:151308007E7C18BF7D9F03DB65E24B08A9C63AC6E53BA7BEE98E
+:15131D00C2FBC734D64D747A10725E6CC8C0DA424A0E31D7BBE7
+:15133200E7D5FF065E7B5CC48BF6C77BF9465AD358456B227E15
+:151347007A47E366D0D32A5ADBB8CEB237E2A8965F1577D4E057
+:15135C000C34289F51CB80C60298AF86BE1BFA088773F6B90BB5
+:15137100E15DD638AE0F26E78571BD8CB2027D19F8284CA5ECCB
+:1513860008E953189C8702AE3EF17DE059F17F5203D67D685A64
+:15139B009CD1719F797D57D4368823337C4755D7CC4EF57052CB
+:1513B0006AA9B9705E9D23EE5933868EDF5E760E88EF34384755
+:1513C5008E0DB1CBE2FB0C65B3C8A9E508432C18F17DA56F880C
+:1513DA00CDD2BE6A126B89398EDF4DF4248EFFBC89C883064DB6
+:1513EF00A6F03B8821AF1950A330EED79AC5B817DEA980AB6D72
+:1514040092F05E22F6BA7118FC026582FD5F8D7715B3A2A71B27
+:15141900C59D456ED038AC4942EF788FF70CC43C5BC6A0252368
+:15142E00CA11B1F27D7D01CF75FF43CC13064755A4D993BC91CC
+:151443001988C3038611280C0F1CD6E045326894648038C168C9
+:151458002556E40688EE7B5CD089266EB450729055768B5B5FCA
+:15146D003081041F5CF34C206BE1DE84CD94932B2203071A3D8B
+:15148200ACCBDE79BB68A5AE721677C7D5B9DEECD69E4779615E
+:151497008D6CDC65AB38E7BEAFBBDFCC9BC9A0E0DED5FD987AC3
+:1514AC006FBEEEF77D5F7FFDF5F77DDDFD7547F5F31B315A88AC
+:1514C1001BB88ED10BB618607BCEF31C0253B2E941318E59B05A
+:1514D600E751CCF18671A03F4CDCB28FC53814642D3F01387A39
+:1514EB00433155770FB3BC0699D9A328ABEF954FB03595493179
+:151500002F4698A20CB3BD8A291B2C2060E47206562A6057702E
+:151515006D46C454576DDF30DD1B292025CAB0698761DCE8CF5F
+:15152A00819102899467C3E8203CE5C8192A83AFA9C032D15E21
+:15153F00DC8F21F4769E6B22BEBFF4E59C7F70B1EFE3D4E291CB
+:151554003FC5FFF019EAE881BE606BC0316AD10929C3F44592AE
+:1515690030FAF4188BBB3F01BB07D1C3168CBB93E9B888CB7601
+:15157E00C1548AC935947C3DCD6728F916EDE819566B6CBC2309
+:151593004EF46F7DA14186B319437E5C0345D9C8C3B42F1C65B4
+:1515A800F07A019F12B1117B029F3EDC2F92193EA6035EFC1FE0
+:1515BD008E1956FFA7447F768BFE64BA60C90D6224A00FF3A197
+:1515D200D7696F826C29B2D96359B4C7259E72CEF3BD2FD3E9DE
+:1515E700C559F685CBFB75B6CF555344C27ADD1915C74C0DDB68
+:1515FC0013E730B2613AACC00E2BC6711C376BC1E339C47B8D20
+:15161100CCE1A1E409E0F7049D3FC9E4EED3053F0C0636CD57B4
+:15162600191773BF8421C3372C8708FA8C3DC3678CD9888F0E7C
+:15163B009BF9EA933CF549BAFE5B5CD600837773773ADE8E53ED
+:151650006931CC3E443BF19DB5C90BBC5B6D82F729479CE97FDA
+:15166500C09B29DF579729B7607BF3C0A40DD3614E3B2C67FFB1
+:15167A0091E9BB1863D6F8B58FED8E9CB18D4FE7C7710DCBAE50
+:15168F00F58D9EE71BABEC255B19C674ED8BC82CCBA6A03CAC55
+:1516A400727C5F72A1536BC8299F85B4EF47DA71A3028C776FB2
+:1516B900C4B945C6BD0EC0157E28639F5037702C5865E5F6325F
+:1516CE0090834BE0614F1B8EA21C1C56FBB9FE71989E0B037C5D
+:1516E3007B2C983703D3F3C0667AB261D8A62E5B9B2D58671E54
+:1516F80058A1C70ED38D4431D8B685423E246AA0FDC0F1E915CD
+:15170D00FA1E4FEB3BC0D017D8D63A4811616B1AA8BF5EA6BF42
+:1517220031C3D2F39907713D3C418FC2B8F785B86DCB8743BE31
+:15173700611C5086397BF230D6331B6CF350B4EF681FB7A15DC2
+:15174C00C1B526F8EEC0C2B8CAF0839EC14490E683CB36B861D9
+:15176100AFBF203F5C0678AB43D8DF626E732D99615C500F659D
+:1517760079E5E5CDDFD6591F27B43E7DB8EDC0C284CA7310AFE4
+:15178B00436EFF8BB8B09D5FD507C68DF0F58D7165F76B42D8B7
+:1517A0007BCB77737B9C2DEB6C7B9C8717F886F302710A3E0187
+:1517B500F76CC4C7F6C3F3C8214F7D92AE9FCDDF6E9BDEE11865
+:1517CA007678A68F71E2993EC60B3CD3C733C903DBEF9E3EC6AB
+:1517DF009D9EE9E359CA8161FD57ECDF66E6BC221EC371CE7D03
+:1517F40003CA7489CDF7C15397785C62129B2F9473CA245B99AC
+:1518090037A7CC652B5B905356642B5B2C0B3F129834E23DC8D7
+:15181E00972EF2CBAD582446838A3390893D6294E5EA425F6464
+:15183300628FA8C6E38C9CD853CEE4C8C8BE924647DD2AE853AA
+:1518480098670742867C3B2105072B357D32E5763A3AD5367878
+:15185D004A20935E85AFC3FE0874EA70F4F7E5646A805EE941AA
+:15187200044EC44576EDFFFFFDD5D610F7D86729370D75A835F8
+:15188700F749EBACBD4DDC2F24EDFA293667688F9E1A67CFD1D9
+:15189C00532CC7AA3D796A929DC989D2C446BE16678B410D07AF
+:1518B10019FE18E539713F71ABF7F3BC65EE67BBC1CF0E829F2F
+:1518C600051FC9E456C2E466F9EA1AE083783AD5F2CF84EC22A0
+:1518DB000E263BB47D51C0E307F847F749AB91D6D98D7C8C8CD2
+:1518F000C013D71B1D0A8B154DFCBF212BF68CD107BF617F17F3
+:15190500B179E0A4896D045924842C12421609218B04CAA2F079
+:15191A005E57A33D7EB95EF9E158F228CB033395AEC0D1422EFD
+:15192F002B0EBB13600702F12CD83D00EB0B9CB66045089B0F62
+:15194400B05B03A30863FB3A5CA6572E810C4196172F4D9765C3
+:15195900C37AE2BE700965E95F7DBDEDBADEF69CCBA30F054261
+:15196E001F3EAA26EEDAEA6C3E2B24E2AE075E9CC0EBDA3CBC7E
+:15198300C6A17E29E3B574F58DF4C1F5F27B3C0FBF8582DF525A
+:15199800A0DD1F9AAEBFFA35F4B77322E52E8076B44F4C6F471A
+:1519AD0012F0344F603BBCAB6F54976EA43DF13CED91447B1A71
+:1519C200818773F7417BBE01FDD6FF8236297E2A2BA594D97E0D
+:1519D700B0798EBB0889001CFF4BA4D6D88DEF01D550403A8B99
+:1519EC0015CD9495EA57D91E33D899FA08AE37478DF001EE1352
+:151A010095837CAE32FE32F86249077FD8CDD64B0DA837161922
+:151A1600328B9A4E9A139F72DC7EC09B9AAD1B53F0DFC1FFBBA4
+:151A2B002E7C9ACDCF0551F70A3C1B20DEF42A9C1E51393DA4D7
+:151A400083F4D02BDBE92D867A454D43663DD0DB2D709CFE9440
+:151A5500D3EB14F4E0BFCB2E4F59C8B3086489E5ED5524AB7C94
+:151A6A008E65FFAA7879434EF95C513E26CACB73CAE789F2E328
+:151A7F00A2DCCBCA278D1A9A39CF92823652D2A5E2DE9D0B7DD7
+:151A940074CEF9956E888768D4B905E28CAD55B8AEA977AD2A29
+:151AA90056A4A02AE29A9E8517D5AAD0BE60AD2D5F60CF48D3BE
+:151ABE000728ABE7DB3FAC0AD8E01FFFF0E5AB085FB3F5832A70
+:151AD3007B7EC18537BFFF1AC29FF8DB9F559162DCDBEE373A7F
+:151AE800FFE5856AAF4FDF4A1E236E974ADCD3F8B4E58F2987E0
+:151AFD00B2FD338F35264DB4210E0F9FC331989CDD362B3EC2C4
+:151B12007A3341D7A7D6F2DC19ACDB5337ACCE8C3C12D85FC732
+:151B2700EC391DB5EC39945967724637E69FEF1B9FA7DCF14B5D
+:151B3C002977661E46B55EDDAFE2BE0AC48DEEEE8551753D59D3
+:151B51001EF490E5AB16298EE0799045CF42AA6ED0FDC17369BF
+:151B6600B9C4D99AC4CD4C1E740FC6284E88F50673CADDB672FB
+:151B7B0009CA3B3372ED2E9048B70BCA1D65D07FA2CE22E6D307
+:151B9000F8B73741FD0651FF0EB0FF3EE1DFB0CC07651584EB9F
+:151BA50013FE5F7261402B81FF8B6C75965C8869DE1C7E1E8494
+:151BBA007E4A4462A60B7C6CF96F53EEE8D594BBF9CBD42CD1C5
+:151BCF00BE7511B0D3A03F5976C52BF45442F9839E86927F6EF3
+:151BE400E84E320BF50CE3600B37AE5FE21EA16CE30B73854FA4
+:151BF90047980F360222BFA108F02E00F97B9712B7EEE7BABFE7
+:151C0E00600DE016FB3054F8F31749BFD13B3AA8BEB90CF7E984
+:151C230002068F654B0C561EA830D07717B863DA0F963E5CEE8D
+:151C3800AD8CD2D65732F1168577A90F2255788EC2EF1CFC9498
+:151C4D005EB0AFF01B17BFD65EBEFE85F82EFE12D7BF94C6F455
+:151C6200BC4CC0A3FFC1E161012F009F5683EF7480CE837E2B7B
+:151C770000FF50CCD618264DE9DB84BC823E830E9896DCADF9D7
+:151C8C000796596D9394037406B3ADD4083C4A48D17FA6DC93CD
+:151CA100249BAEEE22B370AD1BF1FF33CC476702DD31A81376E8
+:151CB600733F65E191051EF932E76DF493947B90E7F5883A101A
+:151CCB0007D1210DC7EC646A361B23B837D6F7F7C7198C4CCED0
+:151CE00026DE9F0EF277F883F2CED48D9AB89FD6377A5C9D2F99
+:151CF500B1F50E93EFB3454DDC575B6BA3C3D71DFB8DC7C61FD8
+:151D0A001B5F363A98A53F37A3FE209FA043814ADCA386B8203C
+:151D1F003C443146DBAFAC0BB01C45CC8D8BBC4B95C819C3C77B
+:151D340072E8BF303D7CED9BF68A7557BE8E3BC2F70C020ADF8D
+:151D49002F40BA387EC227CDE7593FDC40FC373E8438D2F3B0B3
+:151D5E00AFE741D0065A69FA79F475DB3AF0CB69FB17A5E3B899
+:151D7300D62B1BEC9C14192D20E037D8FA3EE0A0631B591E841D
+:151D8800CF9A67CD2103EC0C12CA784CD834FCBEFB5EE296C690
+:151D9D005FD2E40F5F52ED362D6D77D99C6CC448FDD57B923824
+:151DB2003324A32D66F3191AA37790C120E6EA4FFDFB7095BD05
+:151DC7006F6E1263BBA482E45D1FE56B9BBAC03B22F026742EFA
+:151DDC003FC0ABC738DE25C7B3F0CE1078C757E7E0457B08F1E8
+:151DF100D5BE85FD2A3BAF0F3610F126393E7D19EEC9CB83B482
+:151E06003039AC4BC933BAAB28C6D6F966029DB961AA3922869F
+:151E1B007128296D91944EE316F91D6D2C95F279A25230334FC2
+:151E30000D1B1877EE72A0ADAA6DB4CEDD635E358B4B587EE23F
+:151E4500A4A9E2B3B8A291C80FBCCAE64201E554E8D13CED0713
+:151E5A00FF15E847FFD5CFFCD7BE8523AA67B4EB5E466F5CEA4B
+:151E6F00A49571CE7B38A67B301E13F082484C972B13AC7D8726
+:151E8400C801D584B1ECDA30C8F6D1BE85361EFAC411194EB76D
+:151E99006F6E6830687DCBED46FA7D1A3FFDFD997CEC7DE0FFB5
+:151EAE003DBAE0875E831F80CB601F91173B4D07DF4FDF9375AB
+:151EC3002604ED1501BE8B47F83C5FC44F203B2E1F9E4F922D53
+:151ED80047B9EBD5ACFD0B186FC88303FA1AD73F43C9237B8A4E
+:151EED00F95C4DFF25C07BC351D5E5116B64C0D3C5421DCF3873
+:151F0200CFC2F2B64D3C470A7DCC3231BFAB653A12D7FF14CA3C
+:151F17002CDE19DF507FD7261607B33C8E7A51EF7BB67AD5C94A
+:151F2C00D7F7C04F47786213DBD3D0314F00DB82F349E4A3F77A
+:151F4100A598EA1DE5FC20DCA2DB2AF09DCC4377C446779BA8EC
+:151F5600F7B6ADDE7AA08BF5466DF5DA44BD9FE4E16F7DF2845B
+:151F6B008EE3EA1CE3F16F74F403B5789E06F83BCC746798AD4C
+:151F800015F7FE1DF04A0619AFB5365EDB05EEF7F3F03A6EE3A1
+:151F95006197A8F78F7978BD60ABB75BD4FBD7AFE035BA39C326
+:151FAA006BFDD7F05A6FE33529700F6C9ECE6B7C7386875F8943
+:151FBF007A439BAFD19F9B33FD59738DFEACB1D1BD68F5671EA7
+:151FD400BA2336BA13567F5E836E77038EAFB328031AB6D3C5F7
+:151FE900F68AFB3F106EE9FC7EA87F84C4D23ADFE0E43A7FD59C
+:151FFE00C1755E6FC8D00E3B39ED8E86AFA00D741B045D8B5E7B
+:1520130083AD9D0D02474F7E1C14C7ACB516ADE6DA3C3C4FF630
+:152028005AC6DEB1F18CE771E5E394F92FBCB7473E4D31CE73E4
+:15203D00157569FB206E94C197C9F5EF6A0B8C33DA41DCA3B7F4
+:15205200D9A01F40BBF2D91EEB3B9F23A61ED18755D417BEF704
+:15206700774085F9EA1E9C9FAE67B832BEE12EC055007E216DFF
+:15207C005743C3AA6B438CD954664F2D7FA1A33D8D317B2AD7C5
+:1520910001FF60471DB6F7ACF61663BE4EBFEA5848B514E65951
+:1520A600E0BAEF659EFBC57D5382D3A7C29E86FB786C07BE8FF4
+:1520BB00B765909DE791C3BA46D12F4586C12FBDADB9A2670C99
+:1520D000F44D79FDC98F32F33B9ECFD0A9F970BB1AD712C4FFBC
+:1520E500A9546A5EEE5C8FAF47B2FD70B3640AECAB1BC656B88C
+:1520FA00D4A0A18E36B4C5AE426E93252BCEC6F32DBF4BA57368
+:15210F003F9529969F39DF9E372855F27B70545B3DBC8028B73B
+:152124001EFA84C30A9EA11AA188E7093C4355E6C0DBD558FC4D
+:15213900EB284E3462F92DA141ED96D0DBA8336615D6C19800DF
+:15214E00F3A901EEDB1A3333FFDFD618ECCF6218A3101F4D680E
+:15216300FCFBB7D1A77B0B3C1DDA7BBFCDF0E49F6271928DA775
+:152178008451454EAEF1298E80451BEF02BA83D18C52ACEFBB81
+:15218D00F50B33FDBEEE8B349DE492936B0BD2795F309F147980
+:1521A200F8C8D7FC5B3127A28F9AEC2C5729CB19BA17C5217371
+:1521B7005CBC6E9CA2FCC12D9AB2BC17FAFA347CD36B4ACA69E7
+:1521CC00B3D1164F5E7C84906714E79AB30E316FCD43E7218C26
+:1521E1005DF2E2F69B4EF94DC07DD620B4CF94A2EF9A986F8196
+:1521F600EB9F69DF8DF38A42317E11EFB7C57D14A20CFFE7B9AD
+:15220B00EF83E596A21E4DCC40BE127482E78C5397E0CF65E79A
+:1522200003FA1BF945BCBE6082E51BB1BC0FF9A4897CC83F5F73
+:152235008EBC73DD13EBF1150319FD463C138F703CFE298E9FB9
+:15224A00E34D30F9CCFF791775C01C0EEFAFE823C32A9EA3C3D2
+:15225F0098977F9330B14ED63800FCC707ECF7C9F07623FEC926
+:152274004778FB389D78161D6B4D00EB323926B91C6FD9DA6987
+:15228900E23D116C4E63A7993E5F1B32382F1586CCE4526BF06A
+:15229E009C8480E112F9A00C1E1EA44F2DC5D8F518CB47B4F334
+:1522B300E07D6D39B5F71DD431257908F7E6A9A5272CC606DB7A
+:1522C8007A9874AAECDEA8B0C1E4827C61B904EDA515BA819379
+:1522DD00E4C2A24E8D1EB8533B7F21E526E3036CFEEDC53E92E8
+:1522F2004F6992F22EF545F8F9796BEEB2A070FAFCA9A36E8876
+:15230700CDE7B2E650E327CD7B6F740E15FE4BD3D229CC23ECDB
+:15231C0077F2F969B64E711D425E4A845C589F04A33C7F4D1EC1
+:1523310030713E8DFE0CF5097580C94AE773E9A35FA6E6D8F47E
+:15234600384B9F59DE7800C63E9D30E6F9028DB87EE2519697DC
+:15235B007F88FE14E6E9CF287706AFC098BC2BE965E7B07B1FA4
+:15237000E5F4E38FE2251B0798DE610E97809B083F27E6B551F3
+:152385005137915357C04D841F15E3DDC2FF9EF8E67CCE37023B
+:15239A006E22BC55E03F27EA2673EA0AB889F0B502FF3281BF77
+:1523AF0053D4C57AF8BED8666FBA6D65F88E67DBF04C9B0BF426
+:1523C400A8107C95A40C98282F49DEAFA19F092883788676EE70
+:1523D900DC505F9504F3D3F91D135A9132642ED22FADF5557FB6
+:1523EE00A64991D3E66B51E71617CFFB9C373332638D14993002
+:152403002D9D9D09B62D7915D7D13263E0FBE02325766E884EE9
+:152418001B8F627CA5ED0AE2900F0E68BD85832AF23677ABDF7C
+:15242D00B4C633D301B409101B3892EFB2FD46FEFD88993B9E8E
+:1524420079FE24D08431631F272FDDDCA925FE89AFF3C9C2A6AC
+:152457007DDD38D98BB9A2D618E91960392BB2F0A7385696619D
+:15246C006E00C41A8FB1B5F7CCDED306C51910E7A9FEF0FD47F0
+:15248100DB78AA2DF83FB0D139F1445819A04E4F17936729E02E
+:15249600ABFF2CE377E9E7397E1778C13A44EEC03326265B170D
+:1524AB00298E373A0FC6B43ED015796D8CDFCF00B8703D05C6F8
+:1524C000E33C764700F8662CC77BC33087D8F2BFB8BFAA46965F
+:1524D500D2420FDEBDD7618CFF3A435BCE1387B8224097AF4988
+:1524EA0098D85F7DE0F7E5B303C6154113FB378B2694BB7268E4
+:1524FF0066B7BFA4B1C1463F6CA3AFE4A12FD9E82FCE43DF7F80
+:1525140083F431BEE8AC0C18162FC8C3D825CEC362A0954B5FF5
+:152529003E3BC46829910103EF4082B9B789B18FA4F03B8F16DC
+:15253E004706E861887BD0A74DD9E31C5C7393FD66679DA1E108
+:152553005D60532FFAABD87E5FC96D2BFC75CD41E54F2A2AB7BB
+:152568002A0FFEF1A60794CDDFDBD9DEF2EC4E6553CBB696A616
+:15257D009D2D41A5FAF107B7EF686968DDFEDDEFB4B63F5EBE5C
+:15259200F2EE9501A5E4999DAD4FEFD8B1FDB9C79B9E6F0AADAF
+:1525A7005A55B9EAEE157F7497F2D4D3DB5A762A81CAB255156B
+:1525BC006595ABE125581E0896DFADF8D3FB5B16BDB2B2E696EB
+:1525D100B6EDED654F6E7FB6ADACA9B9A96DE70B65CF363DFDA7
+:1525E6005CD9CE1D4F96B5EC6C2B7BEA85B2A6A66D0CB66DFB24
+:1525FB00F6B6953B6F5B758F72A7D2D2FC74BBD2DCF254D3775B
+:15261000B7B52B4FB6363DF79D16A564577BCBAEF61548E5FA76
+:15262500F037EF78FAF9961D654F41B31E6F6A7FF6F1E61DCF95
+:15263A00AF7CF2B67B2AAE853F8D9E9D679AE30B37EE67F71A4D
+:15264F00F88DB9BE8AC612A59CAEC4B35CD6398D88B406EFD1B8
+:1526640038143AD25640FA8DC6DFA7D2E7341A958DE627BF703B
+:15267900AC91E48735BF526DF861EC7D0CB6C40BCF37D176E26F
+:15268E003E09DD6FB47E9172FF74A9146C50866829942D22C3C6
+:1526A3005521A587B2F2B0B4370030B4376B6D30AC27830F04B5
+:1526B8009C66B752B4CEF2090BC036CE203C96C0FF5701F73E78
+:1526CD00F9E5368C13CFFD756A16F2653FD7603FD310BDC2F71F
+:1526E200CABA58FD12A31FEA13F9B2E9856FCE027D3B4FB48D99
+:1526F700B0B3D32B1D642EF2877C78959314DB3003E6A998E3FD
+:15270C0046C657E03EA9D7577DA7866DEF02393A7F52A9E1B5D5
+:152721006A7EC0C5D7AB0E1961E58746CD08D08678CA0BDF5BC8
+:1527360074F01C97B77A850630D34EF3A1548AD1EC62FD72CC9E
+:15274B003C9D4ACDC1FBC4F8BA738F7113F805C439F916AEE733
+:152760000700768CF1E5047F7908F90AEFC775B9F956BF5967CC
+:152775006CA2BFC3BEBBCCFA0EF7571405C69DDC957029F7980F
+:15278A00CEEAE3D0DF07186E1C8738068B94D7CCD22F1D6BED4A
+:15279F00EBBF28734BDEF67EA87927E5FAAAF2D27752B3ECFD49
+:1527B40081FCC8C08FD7D65F6D1197114DFEEC556C93121D4848
+:1527C900CCC13BE7E8622314ED4890E2B6464F926CF14697828B
+:1527DE003F3EC7EEC3F3F96AA1ED0F18787F29CE1DDF9470BE3A
+:1527F300A41A18D348EF3FA3E11D51F5B8CF12C6B3DB611693D4
+:15280800F6EA41D50C55AEDBA414ACFBD079D1F0856E67EB8DA0
+:15281D00462235EB23B12F128AF6D09BB2F4A01EF3BFE763BD01
+:1528320066A8773ABDAF1231F07EEE40B49A12F915EA666D83D9
+:15284700793795F63ADCEB35DC4767F617BEDFE3C0F58C8BFC2C
+:15285C00CEAAE601889DCB204E78925E29242ECFD880F69872A0
+:152871007370AE72F3AA3796CE0FBEBAECD6E018C091DED4894A
+:15288600D4AC658A23C8F8917B0C5C7376C1383C0F7A9FDE0F44
+:15289B001B3FC6FDF1F831F32F1696A86C7D186CE4D142116F97
+:1528B000290EB6761A075C565DAB5E3BD4395837A0E29DA7C812
+:1528C5002FAEE7E6D2C2F18BDFB7C2F7EF39385FB8A679E10D71
+:1528DA001C3F7BE9E2A241CDFBDF47282A4A6D14CFB45F64E72D
+:1528EF00E7CCD0EB6A1FE05D5454AADD8577C28E47D55272D174
+:15290400E80C9D68C33D2E05FBA96E8566429FA0AE38770F1B8D
+:15291900B8B71FC4F58EF08F791F88B18B31B4C4E6610AF015FA
+:15292E006A64FC877F6C8E4DA5DCA70B783BD7439FAECDD37719
+:15294300308F9E9FDBA6DEA914CBE9403CEDE2FB4530C69CE3B3
+:152958003A8C83FD4601CC4B42C923863196725BDFCE80B1811F
+:15296D0036F0AC903BEEA7A22CC22007AB4E3F94B1F7F1970D63
+:15298200CCA762FB8F50A7F48D6CD95F0539E6E315C7ED82680B
+:1529970007F57FCE653E359CFD1D933FEA33B305FB0D4BD6BDC7
+:1529AC0020EBDAE88079F5B8F0F9F676A34E8A761FFD0D6F378E
+:1529C100F63DE2DB05F84A599F458C5D2C6E133AFA2BAEA378CF
+:1529D6007EDA51F780867B86DFB2F450F40997670657E8379C5D
+:1529EB00E736D00DE083E9C6A2A2B59AEF178EA0A523783CBFC9
+:152A00008DEFB30A1D39A3625CB78C9C5987FAE1AD4C30BD3021
+:152A1500F565AAEBFD214D025BBB4CE8035F0FC8EEFF1190B788
+:152A2A004F3EC6E29DD9A01F5EB0BF577E2DE46E8D0BDB37B8AA
+:152A3F00679D4FEE2B717C437D94FD343A30AE7A218EAC17FDA3
+:152A54003EC3A623EDA023AD1F701D71809C25A123E597B99C53
+:152A690059EE01F6FFF14C3F223E4FB84D6BFDB7B672B0676627
+:152A7E0049B4CEF447FFA7BDEF8F8EE2B8F3AC1EF54833D22015
+:152A93005AC3CC20B0905A443892A33833625024598481B05E2D
+:152AA8009910769673B2DD92B0C7B1BD109B64B93B6E1FEF85E7
+:152ABD00C42318890137B8E913589615337224AF7C0B398507C9
+:152AD200397C4F24E2C239B021DC2C211C9764F1388FD8BAACE3
+:152AE700CF283E62E3C466EEFBA9EE1E8D846CECDDBDF7EE8F21
+:152AFC009B7EF3BAEBF7B7BEDF6F557DABEA5BDF5A69AC4D3DC0
+:152B110064AC4ED519D4075AF65353DC2E34E6371EB9869F2B10
+:152B26000ACEB2EE45FDB55654BA5B0DDE817DA2914EC869824F
+:152B3B007B50C5FAD98475AE1E32F7037C3D69949F0DE4EB5DA3
+:152B5000B09131CED8A10527686E3ACCD7BEA454B701BDC4D514
+:152B6500A9935CDE8BA786C193F324B9DB582D9F34747AFBF5F8
+:152B7A0011F5B46C86B3EA61EDEA07C8832E36E6FE07F17305BB
+:152B8F005F77BC253C273C2C7C56F00937D8AFD97F633F64DFE9
+:152BA40063C3EC5966B0DD6C07DBCEFE9A6D618FB38DEC61F62A
+:152BB90020EB600AFB125BCFFE8C7D917D81B5B17BD96AB68A61
+:152BCE00AD642BD8729A41B6B066D6C41AD93216664B59030BD8
+:152BE300B120FB0CBB9B7D9AD5D3F3297617ABA3A7967D929E0F
+:152BF8003BD9127A6AE8F9043D8BE9A9A647A6A78A3F95F42CC7
+:152C0D00E24F057FEEE0CF42EB59C09F72EB999F7B02D6E3CFE1
+:152C22003DBEBC675EDEE39DF694CD78A45B9EB9B73CA5B33E15
+:152C3700733EF0F17CE85372DBA7F8233FEEDB3E2E6E3B338E52
+:152C4C00F3B1C15A4DE6674B4856A96CEA8C32F928FC6AC84FD6
+:152C6100B7BE6BE93B6D7DD7D3B724D037FA96CA5A8A1FD17442
+:152C7600D6A6A569522C098A26C98B8F4A31FAA7E89F597C1419
+:152C8B00E598B6496BB90D3659B6FCDC969F407E31CBAFD8F202
+:152CA00073905FCAF22BB1FC0AC80FF95199FC2CAAC4A2412BC1
+:152CB5002FE8F906AD3CA0D71BB4D2428F374869A202F66465D7
+:152CCA002D880E49BE4BA3D975BF93E469F845B99D8790EE4D6B
+:152CDF00090DAE3375D4FEABFB5D679A558E9F0F091BFD90302C
+:152CF4006E7F87C24A298CFC0DF88B679B555E76BACEB07167CF
+:152D0900E31CF5485B30EA2F719AE8329F770775CCF318EAC994
+:152D1E00D3043B815FE0507298F1E3A7AC70EA135BE5C5866EE7
+:152D3300E593FA2FA67F94E245D15F4A8B0DD105BBA3B3BFA3AF
+:152D4800C2549C74DEB7E498FAD62D7F8EFFF1EC5CE82698E770
+:152D5D00F7656DD2B4C76AEA6D705D4699EB74145ADFFC9CB4E6
+:152D720083788DD11C34D8447DA783251C4D4611ECA1469AD5B9
+:152D8700C9EA66BE1E37F943E732E0046EAC898E533A0F6B8218
+:152D9C004EB4514FB8A08E5673C90D4611BB8B60BFCB700622DC
+:152DB1009DE959FC24C1F463F25B06FADADA996B124159E77EE0
+:152DC600E0EF029CCB151A44A29914EF6A10313F96AAF537A019
+:152DDB003B2F85A8C826BD9EAF3BC17E6C33D7C9803BEA28A727
+:152DF00032EA74942F9E2957A5785D186F57BCAE01EF28EA9AFF
+:152E05000E72191A71391FC3DE6230A8C5799B68D2225CD728D1
+:152E1A0002FF58766E1BC58972FB879095CD33CF312DC2F5F20E
+:152E2F0037F133A82CB8C53C03CDB659F714242D5D08ACEBCEA1
+:152E440025A012345F49E83A4B28D8DF81FBAD15E23296DEA113
+:152E59007B64B1814577C2AE9C8BA565DDB4FF6AEA31D5670A9B
+:152E6E001A789E941F5F47C277B4574F2E882B42AA17DF464EDC
+:152E8300CF23FA5FFB50BF0AF9A02ECA670DA62768DE242EFB76
+:152E9800EE83DFA5FC5FEE833FFCEAC9AF7F865F39F9F5CCF080
+:152EAD00DBBA82E0925EEBFBFA83AF874860D63CF2157D1B3BFC
+:152EC200A355AC7C5D6DAF7A25F46CD3045FB75814BF44F57999
+:152ED7004A5BB4F2BCEABA4FE336CACB2DBBF3934F88CBC4D496
+:152EEC0090EEA0F15196BFDFC7F4EB862B69DAE3E476D4C70FBC
+:152F01003406307FA2F298FEB7C61DC2EB2AF051CC5E098D3CFA
+:152F1600F86623C142B4BD42F09DD7056D9FFAEC86D7B43B22A6
+:152F2B005486B4CF20DCC56FAE581D72ED46F93B47D94821CDB2
+:152F4000E3BE33EA725DA3F05DFDAEB6D7C9FFE97ED3FD3796FB
+:152F5500FB3FF59FC966FD7DF679C0E8CFFB128E333AF0B68DCF
+:152F6A008D6BF11F14367CEB5B850DD07FE84F3FAB2CBCF0B4B0
+:152F7F005270FEA2BA865D0A2D1C3FA9422748F8C900F4F5CCDC
+:152F94003A120D70EED52FFD07F5FA43578C85C2CB14E792E1D4
+:152FA9008A1F69C4BC15F94F3E745E77A50A1B469F285CC6F5AF
+:152FBE00645FE26BDE47138E14D1FAB88E7AFCE1507738708AB3
+:152FD300F2977EA3A12E12608EFE68D485FD1069D75189C3FEC9
+:152FE800E3A3AF513B2C96F726B3244F16C9DDF1FD714D11D6BF
+:152FFD0069D44E7FAEC36E288D00EC2917F610B4E464F5EF0D02
+:153012008ABBE74DB97E5994E26F8FAD6EE0EBAF05E6594D31D5
+:15302700F56DEA279D0DB1F1C30D4C3FAE4F82FFB0BE47E1EB7B
+:15303C00C95F4C1D211EEAE6F6486A2D7B41BCBDE97BB9DDF0EB
+:153051005ADED648AE4DEDA5B616D744A2ABC4B430DE2EA635C4
+:15306600E08D3D3257EA00EC1D733BA2E5A9842EB85EC63C93F4
+:15307B00DB0B052FA28DB8CE216CC88842EE4E258CBBE21AF7B7
+:153090007FEF27541EB921134ED2D4D013131BCA486E445B997A
+:1530A500AC1E321606529D63379DCB0897C6E9F7B22E89E06916
+:1530BA00A5322EA16D05FB349DFAE156CA97A5068C8BBC7E4946
+:1530CF009DDAA91424C0DEEED6C24C3F053BDAA3E82F7747CE85
+:1530E4002BBF7EB4B0A18F752B7DF1034AE91271595F64AF3217
+:1530F9003FD1ABEEDFA929FB9B2F73D952CA1CEC5BB3A4F2B3DC
+:15310E007C8F28181FC5DA6BD9A204F600F58A14AF8FB986EDC6
+:1531230032EDF5E3BB4D24193AF39A2EB411EFEAA78DFDE39A1A
+:1531380082F541576A80D2ED028EF95E5E79E6A0519179CEA8B5
+:15314D0025BC54503D338524165038DA67ADBC8BDB6EE1794811
+:153162009A7191E6A1E5F2533AB7B1B841D3289D8EBE418C1DA2
+:15317700D3C3991F50DC5DD4467A699C1B509167762EF4786000
+:15318C004B80BAFC7327D583F15EC5BBB257756843AA6B7CB87A
+:1531A10011E7E87DA78E98F6BC4F33B6003A00D029A39FB8AE2A
+:1531B60047A57AF73BD6ED53134579776CA4B1D69FD4BEF10F46
+:1531CB00E28F0F0A9C667C0FC4977981EB03F25B806033057EB2
+:1531E0002CC1F5B78013733F24C9F7438CF15EA53CD3D317CC90
+:1531F500BC9092566ABC0F2958ABA9A2AC191E17F6B807B4DAA8
+:15320A00C881469CF3F277116FD1BCB63C0EF7712360B985B33F
+:15321F0003AA392E1C307C194F03FCB0B6EFCAED8FF4F13D009A
+:15323400077097EED56B389DCCF3C9021BD1A0476D9E4B1EE5BE
+:153249007DE9AF282F612DFAB214A7AF903CA20616751B4F47B0
+:15325E00CC73AC584B17BEA071BBBA12A7B3693B5AE23CFF9D4E
+:15327300A35761D392EA8DF56831437D5BFA3AA7435946C4B92C
+:15328800E57980A79CDB5F4A76DA773430FD4903F6C100A7902A
+:15329D00F986569B9917CAEFFBD1E783BEBCDFCFF5F9D4FF6FB5
+:1532B2002A6CF765DEC638C06DAB48991EE3B1F7B37EDFFBE0EC
+:1532C700779306C0B12FB34F7768BD6A598BB9E7EFA07E03F7AF
+:1532DC00DE7858EF520FF1D042D61B02FDCE7D798A77CF59B649
+:1532F1007F2F73DDAF894ECE7B4437B845BEDF11E7FB58A037C4
+:15330600E8CB6D5EA19D133D67D292E3DEA2C3ED70FB9169045F
+:15331B001AE4E3DEA6C7C7A04131A7419FB5CF33458BDBD220BD
+:153330006FECB5F11F1B87BDB4D2603E2DBCB14F86605F8345EF
+:15334500BB466F3CF1C946295644E36C972E901FFAB1CDDF28C2
+:15335A006C38F147FB3CA0D99F9413ADBC8B3443A03A8176A8A8
+:15336F00A3B9E7639681F290B77DBE7D4A7E32E9B1208F16DB67
+:15338400393C49D3EE0E85635F51CAEC3304EBBE1BB8953CFDD8
+:15339900E3AD79E9B77E39A7E7CBF583FBD830D7DBDC049A7748
+:1533AE000D2B1ED9C9FBE92D5C0F50D31744CCBE29D7EEA8CE2A
+:1533C300C2268CCBF4BEEF3CC701B553DFB63F98F5CDCCB8F661
+:1533D8000BF6DCCB03C9CE052413C82C7534C8C68F4658E668BC
+:1533ED00F93F66DDF41E25F728F98F3659E93F28BE32313DBE77
+:15340200CB8A8F717EE0EDBC32B1DF48F391FCB4A80F9F7B51F9
+:153417007D6E92FCD28AF573792CFED499934A2189F6A2DC9BBD
+:15342C00849D9A62F97412679ECDFDA0717EE651928FD13C2606
+:15344100A17B324B1A4E1FC8BA81878167B3EE9979E6C3C6F7CB
+:1534560031296DABFC8C7EFD558D64259C19485A7CF8EF0DCEEC
+:15346B00BB416EB37E723FC98F0D241F7D1CDE9C7CB5574F3836
+:15348000481E1D11DB275FD58C84A3CF6895F71B6FDF44FB88C7
+:153495005B73952EE32A6422A23FF657652A231F2737AE4CC7E0
+:1534AA0027F6772DF9D6D47FD60774C8D202B52FD491DC46F8DA
+:1534BF00DF91FC188C72BBDF763E727A2A1FDFEFB3AE0A9CED31
+:1534D4000994C32EB47E91CADC06BBF91968DC46344FA6562FE1
+:1534E9003C15527F10AF0B753735F13EAB88D1DC287D9F562434
+:1534FE003C4C7DCB9A19B2A6639928DFA7CB99681FEC1CBB5C2A
+:15351300D514DE66C9998B1B8B694EE3A8547859B08B0879DDE3
+:15352800D915524B23A17031953D54754F634546A631B3562FB7
+:15353D00CF0475C1D3A2767F3BA439C769FE986E326C7BD4D0FD
+:1535520001E132BFD445F2674D4874134CD1AF8C32FDA17E5706
+:1535670012FB88FF9ABF332B1CCB6ED5BF29B7F4306AAD7E2D55
+:15357C0048FD5A9302B9DF2B0B413E9709364DD94049BF30BA8B
+:15359100607C405D60DD59E0A3711C63314BBF64940957D55FDC
+:1535A60057977E96914CCED88426B1DF34FA846B6A69B5B301F8
+:1535BB0072648464F60A6158D593DD4A39E618D46FA29F14DD49
+:1535D000AF73FB344CDA31FA00FBEF212ECBC1760CB91792FC9F
+:1535E5008DB7FD5F2817B5E7DC83669A8FF23F9CCD06642ABF7B
+:1535FA00D1CA9FDBF69F257FFB1F4F4DE57DA7FCA73C0DEC3F98
+:15360F0049B566F92E8259B6E250BF1E58287F32945F1FF84BF5
+:15362400DC864D11CDA95ED259E685A33E6AE7C998735945E6DD
+:15363900A08EFE14BC8A7DF5329219DA16F42E8D903C8631F194
+:15364E004B4E9DCB608DCF68215BEEDAF47EF603E52ECFBBD91D
+:153663000F94BB9A6691BB1CE78EA890BD206FD9F2574EEE8AAB
+:153678000C37E28CBB6F25CEBABFAE35DD9CDE1FF23E9368DB97
+:15368D0056FD686331D7C99ED03CEC64A3EFD4FF22584E6A8B1D
+:1536A200334B7278704D38DB6D3CC006D104E1E9DECC1C93BEB6
+:1536B700382B6386EB62F2B87A37A1A1006E2B0C7E080B4085CD
+:1536CC006486DF091AAF3E088F243B841D6DD7D41BEF645DC0D6
+:1536E1002770566FE1B0E63D138715B3E010694EBFF32F8B4708
+:1536F6003FE457C2E3A2C089CECBC063747F5FECF733AE95B49A
+:15370B007065F3FFEDDCF2CCF4D103FA1AD6A7DD4FF39DEFFF58
+:15372000AC77A92C9F1AA5514CF30A24A74A970C9FD54E45E8FD
+:153735005348BF34B6B1CB5A99F0867AC7CA6BEA216A87341F91
+:15374A006FC01AB85466A898FBB2F401CD357E90DE07B53B5395
+:15375F00628397E6805EF6BAEA3D754515F8BD15A3DCBE14B79D
+:15377400AFF4438C1B716D60FC07E13B28DE1D142F30DE13B21D
+:153789006D3F4994066D54A638B63F6C3FC11FEDAB32736F4889
+:15379E009A28E434E736A7CE5EE16D0AF76905327786A6EC5777
+:1537B3005DE1FD43F0D5D2507EF9F2AB81696EE9D5CA696EE8E9
+:1537C8005BCDA7B2E673B8BAF3E03A990757771E5C272DB8FEA1
+:1537DD0084E072E6C175320FAE25A19976B582164FE7E0CAF8FC
+:1537F200A7C3955934CD0D9EA9A0B1B531833E90DF11C9F8DC00
+:153807004700EF8C111DC61AE711CFCC3F457C263F63283769B9
+:15381C009E9E7E5E0F73FB865D7DF192443BDCDBF85D55C7FA7E
+:15383100A00F5570866091BBFA1DE7BECD797284AFDD3CAF0766
+:15384600E5471BCDB897B5EB2B8A96791E7885E629BFD45DF29A
+:15385B00F7FAEBE5FF61C47F37939F7A463DD07F4CADD7CC6F34
+:15387000CCF37B46275698F98C52BE3E2BCF1B2B3636DECDFE86
+:15388500A681CFD3F3E2222DF2C84F778EE2EC78F2921294FFC4
+:15389A006229FC21BFD134EECFF0FD0C64B8684F0AF323A42D33
+:1538AF00C6990FE25D9C27ACD8FF3CE763F4AFA2957FE9B4EFA6
+:1538C400F92187F9DD572CCF0DD15B7770BD769DE7EF786E8FEB
+:1538D900CA714CF3761FC9FF46E405458A24D472C23F3FDF2953
+:1538EE009936FF6FF72799272924D7ABD85767D24E2E1749FE99
+:15390300B862CB455C4642D8C7908F6CD9C8929366958F201BEC
+:1539180041460A731B30391947D3CF99328E598ECCCAE5DF195D
+:15392D00F320EB92DCE492771B23D7B2AEE294962C26B8C3914D
+:153942004483BD76514E7216E224AF8166DD3AAB15DBB75F33B8
+:15395700E5AEF11FF3701DE141C20FD2B3D4555D583041E3BBD3
+:15396C00466D21A915A612712F9523A58EF5A19F04DF214FCC1D
+:15398100DFC17FB5F2ABFDE6BC7E265FF7F2FE653EC9C5DE53D5
+:153996007B492619D3C08315046BEB1FF3E55FAB8E54B7792958
+:1539AB00677BE6CDACBF96E4DD6DBF356556BE1741F09D79D3A5
+:1539C0004C531630CF6FB9ACFDDFD1F9CC4D7329F7C83CD38DB4
+:1539D500F3A3DB1DCC7D86FEE6FCB0D6B28F62EA383953423B4C
+:1539EA00F33569F6D962CF4F894F4E35ABAB683EE6EC1A547BD6
+:1539FF00D3834AA5EC6C59287FFA73580BE669A43A35771E3916
+:153A14005A4D7C24F488B16ADD29615D59E879E3505D985DEFCD
+:153A2900D2B6FC149750CD9C0F4D2F7F55BC6EE93FAB9C5BF459
+:153A3E00C7829D35F35989242D56A12F0E5D0DD843724A7FCB73
+:153A5300F57BEF4ABDDF0ADDBFC03743E8C3B84E1FB761111D23
+:153A680036D6523CBB3CF8B7927BEACE013E472F96024D9DA766
+:153A7D0003B0AF54DBF95E00F936987A72E5ACC4131BA4B1734E
+:153A9200897AA72C34632FD513AB366E90BFF8CD2EDDD4AB1599
+:153AA7007B2E5AF32BA7B443FD1585C13E682FE250BDB0372D1B
+:153ABC0043F78FFCC4D8A031067FFA7EA390B92F5BE98AC87D98
+:153AD10095FCF11E221AC35ED698C33CB3DB0B9AFB26614796E4
+:153AE600158DC02EE7354DBAF08C02BDEC729C75938E692ECFE7
+:153AFB0011751DD1769E2CB6176506349CF3A8A07E349041FC40
+:153B1000BD3B30C60996EDC0BB52AD4B258F797608B675E6F2B3
+:153B25003C87FB711F93CB8CE32B4F894B85915BD3B26811D7DC
+:153B3A00D7D6096F61BF797616FA59B09B0A3D948C1F77C324AA
+:153B4F0072F73188F2756333D14D24BC78A82DC7E89BCDB21F0F
+:153B64001B8CB9B458E6C747C52B5DEA7B3E3BDF8A5CBE492BCA
+:153B7900DF98653B7B0FF52D63458C9F1966E9B8C1F793A4B0E2
+:153B8E00265436758A995AC395811FD12AD3C4CB2FCF4C92FB54
+:153BA3004CA79449519EB14EACB3EF59B049E17D5BE596CE8A23
+:153BB8000C6C185CEE14E5AF196301933F6A284D6D26DD5F4F2A
+:153BCD00E9C3945FEB3CE60E527A13B63FE9036CB0B3BC0A7361
+:153BE20028669F5B8E744632EF187B16449508CF53E98C929B8F
+:153BF700E21F5D4DEF18E55D4873DAFB33878C48E6E9BEB68CD8
+:153C0C00DE1FA537F6A8A3F43D4EE10A9595F65AB6C4598AE365
+:153C210000F64B61F3B13393321EA17C63049B0FFC4AB8AAA7B5
+:153C3600B78BDEB0D12B5378057DAFA63C7CF4AEA1F9DA26FA1D
+:153C4B009E9807DE265C915F1BF989D4D75C24BF60C0A4476CD9
+:153C6000864D72E795B84A7C57E295C5E50579F412008F3C64E5
+:153C7500604D35280F515F3764CC464FF33C53588B3A58C9DDD8
+:153C8A00A987C2683785CDB216E53AAD757A39BF43A8CB30756C
+:153C9F001D841E3B8F149559D537C8CFB5080BE2EA947DA00895
+:153CB400C50B6B8CF2EB015E7CB5B9BE6DE2EF3106D6A9B8178D
+:153CC90061B1DCBE946DFD5DB7F21BC6EC7CD8D62E2DF8736B0E
+:153CDE00FF6BEBA0B685BE7B6467BB2B074FB3BE10E310C27EAD
+:153CF30063EAC9D7DBFD13F9457F0E5DD365CB5D046B8C997058
+:153D0800DBF4E6772A5AE9026CF972B6B599E76FEB8B230DE54F
+:153D1D005552CA5A7918F22A0ADC8A2FB46F9F30759E439A7424
+:153D3200501D4772753C7701753CA2AE8149D46F0EEB9317007C
+:153D4700306C5F99FB57F2CF281AFD23F48FD23F46FF2DF48FD5
+:153D5C00D35FA77F8AFEA3F41FFF9919976DED36EB6A9EF9E018
+:153D71006E7D867B74863B3DC33D39C32DBD36DD1D9CE18ECEF0
+:153D8600706F99E1D667B8475FCB3B9342F86913A6DBB78880A5
+:153D9B0076BED19C5DB049AA97BFEBB85ACACF365BF9548E74A6
+:153DB000626D684D6C43D87F7258AFBD083A4DE14D21F726FA49
+:153DC5006FA37F92FE7DF41FA1FF09FA9FA1FF65FA4FD0FFC613
+:153DDA0045332E3B36CCF196B2E94F6EE04DCF73036FF13C37CD
+:153DEF00F0B625CF0DBCC5F2DCC05B34CF0DBC45F2DCC05B3084
+:153E0400CF0DBCC9F9E5BF36657F93974F6E7F73CA006F433FFD
+:153E19005A7C62C33DB67D048EB3D9EC7F107E3D2C0FBF33E3C5
+:153E2E00FC33C3D1F78C91FC42B2947E7A0E734357B658165B92
+:153E4300FA04E676D137F5332D1E1A238BE5459FBD48E36205B5
+:153E58007D838EA2B44BDD5C467DD65C56F218AB6989CC35FBFF
+:153E6D00B407E83B3CD7ECCB2A59CD725BFF49869D72DCFB4582
+:153E820079006793A5347E53FA8952C80E2F4ED9E92019F152A8
+:153E970055178DCB872123E8932B9CCB4F531CB96CF6F1C91EC9
+:153EAC00E7B0378FF1689299363AEC781E2A77A7659780E49DE9
+:153EC100E597292F3797F7A7F7631504EF7609E321E48BDDFA81
+:153ED6009E18CEA5BDA8EF881CE6F5777FC6D92EC9753AFA7C2A
+:153EEB009C112A5B79006BB9DA9639D89F1AD499FEA2EE178621
+:153F0000D516D6CDE377BB87156141138DAD83460DD54D243929
+:153F150097DB268FEED52ECEC538A6774A65499EC7988764486F
+:153F2A004AE3925FD4451A8BDDA558571EA4BEFC450378AE91FA
+:153F3F004CF903B0A63DD3E5BB9139ACE434E5979A8371A6469B
+:153F54004FF0B1A9968F4D380F2B2C08727B0A976F66DDC5F1B1
+:153F6900AE1667B45695E56AFD8D15C2F2CD94E6CC5C5326B23D
+:153F7E00F1E0B5740FA7F477653D4EBC29A57772BB7EC85FBA96
+:153F9300F02905E78C00B33732B854245945A43C2729CF769297
+:153FA800A9708E49E4BAD87C1C862D490379A0BD8BB161C323AE
+:153FBD009BF7BA66B91EFF8B9A9FFA7C51FE9E81F8B8FB976419
+:153FD200B00D1305243FE3CEC7BCFBA71294C7DFC588F762B02A
+:153FE700B561DA75FFCF6CB0C5436E8C33C065A498B9DF269E84
+:153FFC007D8B75B5D8B09B3819E17D13F2E0677ED892161BEE59
+:15401100EB0437F45D890E25B02303DE100907176F64DDF6BD19
+:1540260005F9750AE4D5C91E6F502FAEB740FD1DE0728ED39C6C
+:15403B00233AA6F13A4883FD34F7A07AEF9EB2731CEBD27ADD53
+:15405000CCBD8660B5D37C2ED2DD029D8B9F1CF9E5618F5C6F8D
+:15406500F8B9AEB24A6D76B561C32ECA87F9BC0DDF18E3250BE4
+:15407A00476B2D386D3D4E0B977EEC15D7539837262EF7154C5C
+:15408F00B50DC95DA39AF7EBF6F1F28C5343CB59380C1D8CAC5D
+:1540A400B96796CD7EEB5498FC123AEE46294B3FA9965DB84765
+:1540B900914EAD542B65472BD7C94EEF864E94DB9D3F6E5A70DC
+:1540CE0036B0257C5C1E7531F715AAE32F88F7D8D6E7795E88FB
+:1540E300EF425F1F1EE2F7AEF0F34BADF5FCDC0EC9E1FA77E3C0
+:1540F800832D38D303FC3E8D7B0B49A6B5F0EEF5669C2DF321EE
+:15410D00AF674EEAD71F7C69F92FC88D3A8B99E1D9F98D706485
+:15412200F29BC93F9ECC71FD40C6D91E681DE6E5A19D99F4946F
+:15413700394EEDFE5A6C5D82B51884EB95E38361BBBE51613A5F
+:15414C005F42CFE6664C6801DC36DEDE1C1FE27D8027467D8299
+:1541610055CE2F288F8F5AA7CA8C7379B0783A2FB6BD9D75AFA9
+:15417600263A7A62797591BFA7439F3257179AC398F5AFCDD556
+:15418B00057088AD9FE675E1788A0D7E209E9C528D6AAD9364C6
+:1541A000515FD7A9FD5C671573A30187D54F100EA84F77E7EEE2
+:1541B5004C487769E7FE68EB0FD7F33A411FDC4EFB08A503BD44
+:1541CA00FB284D7E3FB3ED7D935F3DF2615D8E0D695F8F0C8732
+:1541DF0050367851DA3E669E8B4C0FD37CA11BFB9D567D877409
+:1541F400BBAD88992386E41E56CBA8CF3D48732B4F06FD8A6685
+:15420900D5FFC454FD892FE6B79EE4F59F4F74B3E89B1B438A6B
+:15421E00D1DFF1F6A0C1DE7FAE3DDC840D9FF0B169EDE1B7E3CD
+:15423300C7B85D1FE0ACE121D35E01CA798EED6D215E36DB49B7
+:154248006BB7C9C7046B4F1C67F0F5CE03B8B3217A7206BD7508
+:15425D0093DE5563CB0D727B624379743DA623CD145D87AC7ADB
+:154272002579BDD0E794B5EEE5755A98129783F76D5AE6F89743
+:15428700FCC414EE0A49E83DD4FECC7B42CC7AFC35F1A7CD8B26
+:15429C005E36D6524AE503961B04CB42E2BD6345D379EFDCFF00
+:1542B10026BE93F3E08B117CB13CF8641B3EB35FE2F86CEDE6C9
+:1542C600F0E5F70BF1EBA6CE03DE62CCBC07588F24B694E68D22
+:1542DB0039F1776D5ECACD5DBD2CDCCB710B5B2C7D93D9921C44
+:1542F000EF916CF32B9C55785EBC478A99F36F6FE4B0FA32A58C
+:15430500F1578BED6517FA1487C0CAE6212C7D4C972EA414DCF3
+:15431A00F17094609530E610FF6C06AFBA20776A5A2070A253C4
+:15432F00261929FE646FFB0EF827DF411FBEC375EE24D7DB9887
+:15434400A8DABB8CA5C7742328B4239FCAC45ED89CF3CDC7FD16
+:1543590068E49FC07AB5B4D710293FECCD7337952BF23DC1BDA2
+:15436E00064F87B2F4BDD07F9E87BB95BBCC343BE234A7C7BA03
+:15438300886BAD063D0E3FD7A1B3E6F412BF4F604CDFD9A6299D
+:1543980005EBAEABF16CD6DBFB794D419D454A539938B201F0C4
+:1543AD0063EC042C80CD4F75692218FC174E28F36354D7B3DF2C
+:1543C20056BD4CA33E3CA57C1FE38295A77876402519D88B7446
+:1543D70076DD7B28FFE4BEE3FC1E66F00B8F1B3DB6C3B5FB1DAF
+:1543EC003503D8A84EA80BBB3EA0812EC003D34F6AC06723D44E
+:154401005C28DCC6C5E51C1ECCB27278C07A6DDAC443E08762E3
+:154416004B721D742486B52EF2EF457B219CC00F6B1B18834D1B
+:15442B00784F120E8E28C8BF60DDEFD5ED1C0F479432AA1F70F9
+:1544400020E15C15D5DB853B83A82CD84C0E52F99581894EDBE9
+:154455001EB2699F27AEE9C4837B162495B7D884B628C8FEB2C2
+:15446A0046163F97B3D7F917DC1E32B79BD4C6D70896F49B67EE
+:15447F005B933C5D24B30B7756B8E98D7D6023F6EE149FE33C0E
+:1544940023D6AAC0A3F5984B439736D8A4E937B89E663F8DB948
+:1544A900E3F15A67BBE00AAB623CA40E10AC55CA28EEB9D475D6
+:1544BE00F9402B9F9F521C89FA0E8FFCC51697FCB51649FED26B
+:1544D30072312A63BC1EBF4AF230DE9D984B455FE43695FDCD24
+:1544E800B261E60F9971703C4861F594BE96D2D7507AF855C8F3
+:1544FD005F6AB1F3207E6AF150B88BC2AFAEF81ACFCFC3E766D2
+:15451200BFDB61C7D9827208265FF3A499B76EC20D1C85D136AC
+:1545270008CE7AF9D556B1396864281CEB05AD349F1692215583
+:15453C008A630FD88C8FFC8807FC22E58378FC7C020EA4C7CC33
+:15455100FB80D0869B9835BF06CF4B435639239DB02952CE6D45
+:154566004F987E9833C18FEB1B9A67316E992F098249CF9C3FD4
+:15457B00E55F61CF7FB85E2A95CFEF384B195BDEBD75CE659ECD
+:154590007D1DD11186FE07772CF8ADFEC69FFE8EEABBF01D0521
+:1545A500F2AAAFF59879AF1085F930F767C731BE6BAFFCB680E3
+:1545BA00558C1F6FDC42E39EC79A67983AB0A69C833B095CF13E
+:1545CF00234BE793ECE943BEC111138E5C3F99E4F0F9228930CA
+:1545E400B76F426EE4591E196AACC8CB333777A13E97A7B7FA20
+:1545F900CFDF5AFC8C7A606E47B079AFF2359D9AA934F9E76932
+:15460E00F9FDE74F69FF384BBAC333D211BFEBB3AD27453287BE
+:15462300B4FF394BFACD1F21FDB559D2856F0BEF216D6296747F
+:15463800EFB1DB9737F9FE8CFD27ACEFE4F31FD6FCDF9DBEBE22
+:15464D0031335CFAC38787C76F17FE7F3BFF19E19E7CFEFFB008
+:15466200F581FF1FFE4F0A97F2F0EF9DD92FFD3F03BFC51FD198
+:154677008F971EED6B9E287359ECCBDC46536D67B7147B641541
+:15468C0035454FD9A3AA46E1B82BDA73EF6E15ED14E3A4A76CC6
+:1546A100933A67F56E55961FD7E6DCDBA5FAD6698A47A8567DC5
+:1546B600A5D56A82E416AB4D6FB84163B35456AB22BF7F6A5E9C
+:1546CB0087EED314EC110BEB30778969D0A813E582F6AF539F69
+:1546E000ECF754ABC5EBEAD5E7EEAB53AAD6D52901CF236A774F
+:1546F500C1A714DCC5B8488CD973151FE28BC22754BEF6B0BABF
+:15470A008BF71DE843AA4A130AF413ED702F0FAF539D65712E7A
+:15471F00DF553D1057F9FE1264E459605865C15042301C22180D
+:15473400FC79E5A3DC4A8201F178BE947F7ED937AC7C27F3F2CE
+:15474900CD665FC97A60EB20C4DAD7331640DEF18298067C644E
+:15475E009999D7DD8CCD9B4FB8F15099EEB57584A36A6591A745
+:154773005EADF88CD8EE645D1D557F25B61F9A9BE034C0BA4825
+:1547880090E0C01EDC5DDC76DA14EC5EAE07833DB8F813BC6EA9
+:15479D0004D3390BA631D4DD73BF5AB56FBD2A94DAB0656FDA01
+:1547B200B0B5106CE59E6AEE1F2701D1A697BBB45EF5709876A1
+:1547C7002B8B4A13EAFE9D7B72BC003CFF219BB56060BC9EB026
+:1547DC000966EE374F3E8172D3161CB81FEC0C7DCFD54C18CA91
+:1547F100F6D5A865541EEAD66E9D4D81D226C74BD1145EAA8851
+:15480600774AD6B6AAFE75610ECFAE82DD4A31E1A5C493500B35
+:15481B0059A2638FC59B8B79DDA7CA9DA0B2740A2B237C11DDC4
+:15483000BD360CA07D55DBFD0A64A1AA75F72B33E94F8DA8AC8E
+:1548450098EF1B4CB5A7AA33033C9E70BE5EF53F105345F6B844
+:15485A003A87E23E27B080D3FA36E8BB641DC149FC52521A56D0
+:15486F00B51F352B87CE362B25E7D7AA7E8DFCF6AD56B5CFAF8A
+:1548840021DE5FA38007FC84D3AAB5262EC498D02EB34D9CB7E4
+:15489900494EF3398587544FAC0077EBF8DCD8ABA96CEB9C2374
+:1548AE003CAC7AC455AA67259577EF63AA67F51A756FC12A05F2
+:1548C300FA1EE2CAA9F84501F31C188F9F0899F15FFEAAEA3924
+:1548D800DDACEEDD19529C34EE96FDE811A5EA3305EDB0BDEDB4
+:1548ED008A873ADCE3CD1D07610F4D0BA955E71F528573CDAA2E
+:15490200467105D7142DB6A28D07F8B9B10DB005E4EAA274A731
+:154917009A3BF85CAF89B51796053B8ACA9A3AAA92EB955DD473
+:15492C0037C8E4DF43EFBF449FF3F71B554F4FB30AB95A961F63
+:15494100866CE7F224BEAA0A6B1F5779D8CBCD141E52F712CEDB
+:15495600407FF038E624C5FF5168AF3A4F38D4BA54FFF9AFAA3B
+:15496B0025E776731ED84F3C3087685F1CD13AF2FB25D01DB469
+:15498000E33AF5164DC193F7122CED809FF08CBB49D7D177A2D7
+:1549950060B33287CA01FCDD3BCDEF5537B37EF44BB61B7169FF
+:1549AA006CD83090C51A8EC9DB064DAD803FF47B34E79A67F3A6
+:1549BF00D5368AC3CF47100C9B67E80797FDA842A93A574EB8AA
+:1549D4002D5767E3A337D9141FFD9A997C041A14131F053C9B2E
+:1549E900395E9EB378097CE4D7C86F062FED8EFFF9C6E2C026AC
+:1549FE00A24FAC73377B78E39C40B453F03CA6DAEE92C8C31BD2
+:154A130041A7395DEB3BD8D9F60EFB5D75CDC1EF702A8EAFEF25
+:154A280028196FEF10DC44F34F546B4EA2C34DA23DF07737A785
+:154A3D0085A3BD44DB4174788CE8B087F7E9F9B428B0689130FA
+:154A5200EF8EF209AE4F50D9D10D67385DC037D10D6333E84242
+:154A670034F13E60D185FA5DEFFA3CBADC994797B7B8CEEF5418
+:154A7C00DBDE49EDBA378F4EDCFE38F100FCB75BB4BA803BFF2F
+:154A91002CDA6CFA98F4B894478FBFB3E88136EDB768710B1D40
+:154AA6008836F9B4288A7C65636164FD46B68DB57BC6BFD23197
+:154ABB0047DAD451C4FECDC6E2F8BFEDF08C3FCCDD557FC5DBED
+:154AD000ABD7C3C81D799CE35DDC5EAD39A8EFBD5914D58A6DA5
+:154AE500BC533B2DF1ECA4FEEF5FA9256B9F9C86F7E2D9F09E3E
+:154AFA005C0C9AE7E13DC6F16ED7371FFFD4E77BEFB5F08F35C1
+:154B0F0011B4131BFFDE3CFC3BF8DA8689DF5E0BBFA5E8A7280A
+:154B2400AC92E65AF96DC04EFF261F174C9A211DE8A658743081
+:154B3900711E9E06CBB708CF9E94D0FE32BD13D4F714521EB8D2
+:154B4E00FFFDD0171F51ABD6B52A52C152A5A8E01E053CECA121
+:154B6300BE879D6DEE38F4530A3BBF56F1167C5E71177CC10C75
+:154B7800135675B0FBD674EC8A39DA01D762E084CA261E292BCC
+:154B8D00941D7C8C843FECB9D87314940FBBA705F6D86D8D1FA2
+:154BA20088075D7FC0F55A36EBA338B9B6FF32B57D8C5D9768CE
+:154BB7003A89F512C80734D6F94E5BF1BF4FDF55D744BCBD27B6
+:154BCC00785E4975BF63E8117EC65230EF62A69125EB8D0C3DF1
+:154BE1006A308DEB88C1DF37B5DE5AFC7F00E871AED038A00037
+:014BF60000BE
+:00000001FF
diff -u --recursive --new-file v2.3.47/linux/drivers/atm/zatm.c linux/drivers/atm/zatm.c
--- v2.3.47/linux/drivers/atm/zatm.c	Thu Feb 10 17:11:06 2000
+++ linux/drivers/atm/zatm.c	Mon Feb 21 16:32:27 2000
@@ -636,12 +636,12 @@
 			event_dump();
 		}
 		if (!size) {
-			kfree_skb(skb);
+			dev_kfree_skb_irq(skb);
 			if (vcc) vcc->stats->rx_err++;
 			continue;
 		}
 		if (!atm_charge(vcc,skb->truesize)) {
-			kfree_skb(skb);
+			dev_kfree_skb_irq(skb);
 			continue;
 		}
 		skb->len = size;
@@ -854,7 +854,7 @@
 		    uPD98401_TXBD_SIZE*ATM_SKB(skb)->iovcnt,GFP_ATOMIC);
 		if (!dsc) {
 			if (vcc->pop) vcc->pop(vcc,skb);
-			else dev_kfree_skb(skb);
+			else dev_kfree_skb_irq(skb);
 			return -EAGAIN;
 		}
 		/* @@@ should check alignment */
@@ -908,7 +908,7 @@
 	*ZATM_PRV_DSC(skb) = 0; /* mark as invalid */
 	zatm_vcc->txing--;
 	if (vcc->pop) vcc->pop(vcc,skb);
-	else dev_kfree_skb(skb);
+	else dev_kfree_skb_irq(skb);
 	while ((skb = skb_dequeue(&zatm_vcc->backlog)))
 		if (do_tx(skb) == RING_BUSY) {
 			skb_queue_head(&zatm_vcc->backlog,skb);
@@ -1395,7 +1395,7 @@
 	    command | PCI_COMMAND_IO | PCI_COMMAND_MASTER))) {
 		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable IO (0x%02x)"
 		    "\n",dev->number,error);
-		return error;
+		return -EIO;
 	}
 	eprom_get_esi(dev);
 	printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%x,irq=%d,",
@@ -1741,7 +1741,6 @@
 	if (!skb) {
 		printk(KERN_CRIT "!skb in zatm_send ?\n");
 		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb(skb);
 		return -EINVAL;
 	}
 	ATM_SKB(skb)->vcc = vcc;
diff -u --recursive --new-file v2.3.47/linux/drivers/block/Config.in linux/drivers/block/Config.in
--- v2.3.47/linux/drivers/block/Config.in	Wed Feb 16 17:03:51 2000
+++ linux/drivers/block/Config.in	Sat Feb 26 20:32:13 2000
@@ -44,6 +44,7 @@
 	 bool '  RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000
 	 bool '  Generic PCI IDE chipset support' CONFIG_BLK_DEV_IDEPCI
 	 if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then
+	    bool '    Sharing PCI IDE interrupts support' CONFIG_IDEPCI_SHARE_IRQ
 	    bool '    Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI
 	    if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then
 	       bool '      Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO
@@ -54,38 +55,43 @@
 		  define_bool CONFIG_IDEDMA_PCI_EXPERIMENTAL n
 	       fi
 	    fi
+	    if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
+	       bool '    ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP
+	    fi
 	    bool '    Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD
 	    bool '    AEC6210 chipset support' CONFIG_BLK_DEV_AEC6210
-	    if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a "$CONFIG_BLK_DEV_AEC6210" = "y" ]; then
-	       bool '      AEC6210 Tuning support (EXPERIMENTAL)' CONFIG_BLK_DEV_AEC6210_TUNING
+	    if [ "$CONFIG_IDEDMA_PCI_WIP" = "y" -a "$CONFIG_BLK_DEV_AEC6210" = "y" ]; then
+	       bool '      AEC6210 Tuning support (WIP)' CONFIG_AEC6210_TUNING
 	    fi
 	    if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then
 	       bool '    ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3
-	       if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
-		  bool '    AMD Viper support (EXPERIMENTAL)' CONFIG_BLK_DEV_AMD7409
+	       bool '    AMD Viper support' CONFIG_BLK_DEV_AMD7409
+	       if [ "$CONFIG_IDEDMA_PCI_WIP" = "y" -a "$CONFIG_BLK_DEV_AMD7409" = "y" ]; then
+		  bool '      AMD Viper ATA-66 Override (WIP)' CONFIG_AMD7409_OVERRIDE
 	       fi
 	    fi
 	    bool '    CMD64X chipset support' CONFIG_BLK_DEV_CMD64X
-	    if [ "$CONFIG_BLK_DEV_CMD64X" = "y" -a "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
-	       bool '      CMD64X chipset RAID support (EXPERIMENTAL) (WIP)' CONFIG_BLK_DEV_CMD64X_RAID
+	    if [ "$CONFIG_IDEDMA_PCI_WIP" = "y" -a "$CONFIG_BLK_DEV_CMD64X" = "y" ]; then
+	       bool '      CMD64X chipset RAID (WIP)' CONFIG_CMD64X_RAID
 	    fi
 	    if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
 	       bool '    CY82C693 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CY82C693
 	    fi
+	    bool '    Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530
 	    if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then
   	       bool '    HPT34X chipset support' CONFIG_BLK_DEV_HPT34X
-	       if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a "$CONFIG_BLK_DEV_HPT34X" = "y" ]; then
-		  bool '      HPT34X DMA support (EXPERIMENTAL)' CONFIG_BLK_DEV_HPT34X_DMA
+	       if [ "$CONFIG_IDEDMA_PCI_WIP" = "y" -a "$CONFIG_BLK_DEV_HPT34X" = "y" ]; then
+		  bool '      HPT34X AUTODMA support (WIP)' CONFIG_HPT34X_AUTODMA
 	       fi
 	       bool '    HPT366 chipset support' CONFIG_BLK_DEV_HPT366
-	       if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a "$CONFIG_BLK_DEV_HPT366" = "y" ]; then
-		  bool '      HPT366 Fast Interrupt support (EXPERIMENTAL) (WIP)' CONFIG_HPT366_FAST_IRQ_PREDICTION
-		  bool '      HPT366 mode three unsupported (EXPERIMENTAL) (WIP)' CONFIG_HPT366_MODE3
+	       if [ "$CONFIG_IDEDMA_PCI_WIP" = "y" -a "$CONFIG_BLK_DEV_HPT366" = "y" ]; then
+		  bool '      HPT366 Fast Interrupts (WIP)' CONFIG_HPT366_FIP
+		  bool '      HPT366 mode Three (WIP)' CONFIG_HPT366_MODE3
 	       fi
-	       if [ "$CONFIG_X86" = "y" ]; then
+	       if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then
 		  bool '    Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX
 		  if [ "$CONFIG_BLK_DEV_PIIX" = "y" -a "$CONFIG_IDEDMA_PCI_AUTO" = "y" ]; then
-		     bool '      PIIXn Tuning support' CONFIG_BLK_DEV_PIIX_TUNING
+		     bool '      PIIXn Tuning support' CONFIG_PIIX_TUNING
 		  fi
 	       fi
 	    fi
@@ -98,21 +104,18 @@
 	    if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then
 	       bool '    PROMISE PDC20246/PDC20262 support' CONFIG_BLK_DEV_PDC202XX
 	       if [ "$CONFIG_BLK_DEV_PDC202XX" = "y" ]; then
-		  bool '      Special UDMA Feature' CONFIG_PDC202XX_FORCE_BURST_BIT
-		  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-		     bool '      Special Mode Feature (EXPERIMENTAL)' CONFIG_PDC202XX_FORCE_MASTER_MODE
+		  bool '      Special UDMA Feature' CONFIG_PDC202XX_BURST
+		  if [ "$CONFIG_IDEDMA_PCI_WIP" = "y" ]; then
+		     bool '      Special Mode Feature (WIP)' CONFIG_PDC202XX_MASTER
 		  fi
 	       fi
   	       if [ "$CONFIG_X86" = "y" ]; then
 	          bool '    SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513
 	       fi
-	       bool '    Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530
 	    fi
 	    if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
 	       bool '    Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290
-	       if [ "$CONFIG_X86" = "y" ]; then
-		  bool '    VIA82CXXX chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82CXXX
-	       fi
+	       bool '    VIA82CXXX chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82CXXX
 	    fi
          fi
 	 if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then
@@ -232,6 +235,7 @@
      "$CONFIG_BLK_DEV_AMD7409" = "y" -o \
      "$CONFIG_BLK_DEV_CMD640" = "y" -o \
      "$CONFIG_BLK_DEV_CMD64X" = "y" -o \
+     "$CONFIG_BLK_DEV_CS5530" = "y" -o \
      "$CONFIG_BLK_DEV_CY82C693" = "y" -o \
      "$CONFIG_BLK_DEV_HPT34X" = "y" -o \
      "$CONFIG_BLK_DEV_HPT366" = "y" -o \
@@ -240,7 +244,6 @@
      "$CONFIG_BLK_DEV_PDC202XX" = "y" -o \
      "$CONFIG_BLK_DEV_PIIX" = "y" -o \
      "$CONFIG_BLK_DEV_SIS5513" = "y" -o \
-     "$CONFIG_BLK_DEV_CS5530" = "y" -o \
      "$CONFIG_BLK_DEV_SL82C105" = "y" ]; then
    define_bool CONFIG_BLK_DEV_IDE_MODES y
 else
diff -u --recursive --new-file v2.3.47/linux/drivers/block/Makefile linux/drivers/block/Makefile
--- v2.3.47/linux/drivers/block/Makefile	Sun Feb 20 21:12:38 2000
+++ linux/drivers/block/Makefile	Sat Feb 26 20:32:13 2000
@@ -130,6 +130,10 @@
 IDE_OBJS += cmd64x.o
 endif
 
+ifeq ($(CONFIG_BLK_DEV_CS5530),y)
+IDE_OBJS += cs5530.o
+endif
+
 ifeq ($(CONFIG_BLK_DEV_CY82C693),y)
 IDE_OBJS += cy82c693.o
 endif
@@ -196,10 +200,6 @@
 
 ifeq ($(CONFIG_BLK_DEV_PDC202XX),y)
 IDE_OBJS += pdc202xx.o
-endif
-
-ifeq ($(CONFIG_BLK_DEV_CS5530),y)
-IDE_OBJS += cs5530.o
 endif
 
 ifeq ($(CONFIG_BLK_DEV_PDC4030),y)
diff -u --recursive --new-file v2.3.47/linux/drivers/block/README.buddha linux/drivers/block/README.buddha
--- v2.3.47/linux/drivers/block/README.buddha	Mon Aug  9 12:32:28 1999
+++ linux/drivers/block/README.buddha	Wed Dec 31 16:00:00 1969
@@ -1,210 +0,0 @@
-
-The Amiga Buddha and Catweasel IDE Driver (part of ide.c) was written by
-Geert Uytterhoeven based on the following specifications:
-
-------------------------------------------------------------------------
-
-Register map of the Buddha IDE controller and the
-Buddha-part of the Catweasel Zorro-II version
-
-The Autoconfiguration has been implemented just as Commodore
-described  in  their  manuals, no tricks have been used (for
-example leaving some address lines out of the equations...).
-If you want to configure the board yourself (for example let
-a  Linux  kernel  configure the card), look at the Commodore
-Docs.  Reading the nibbles should give this information:
-
-Vendor number: 4626 ($1212)
-product number: 0 (42 for Catweasel Z-II)
-Serial number: 0
-Rom-vector: $1000
-
-The  card  should be a Z-II board, size 64K, not for freemem
-list, Rom-Vektor is valid, no second Autoconfig-board on the
-same card, no space preferrence, supports "Shutup_forever".
-
-Setting  the  base address should be done in two steps, just
-as  the Amiga Kickstart does:  The lower nibble of the 8-Bit
-address is written to $4a, then the whole Byte is written to
-$48, while it doesn't matter how often you're writing to $4a
-as  long as $48 is not touched.  After $48 has been written,
-the  whole card disappears from $e8 and is mapped to the new
-addrress just written.  Make shure $4a is written befor $48,
-otherwise your chance is only 1:16 to find the board :-).
-
-The local memory-map is even active when mapped to $e8:
-
-$0-$7e		Autokonfig-space, see Z-II docs.
-
-$80-$7fd	reserved
-
-$7fe		Speed-select Register: Read & Write
-		(description see further down)
-
-$800-$8ff	IDE-Select 0 (Port 0, Register set 0)
-
-$900-$9ff	IDE-Select 1 (Port 0, Register set 1)
-
-$a00-$aff	IDE-Select 2 (Port 1, Register set 0)
-
-$b00-$bff	IDE-Select 3 (Port 1, Register set 1)
-
-$c00-$cff	IDE-Select 4 (Port 2, Register set 0,
-                          Catweasel only!)
-
-$d00-$dff	IDE-Select 5 (Port 3, Register set 1,
-			      Catweasel only!)
-
-$e00-$eff	local expansion port, on Catweasel Z-II the 
-		Catweasel registers are also mapped here.
-		Never touch, use multidisk.device!
-		
-$f00		read only, Byte-access: Bit 7 shows the 
-		level of the IRQ-line of IDE port 0. 
-
-$f01-$f3f	mirror of $f00
-
-$f40		read only, Byte-access: Bit 7 shows the 
-		level of the IRQ-line of IDE port 1. 
-
-$f41-$f7f	mirror of $f40
-
-$f80		read only, Byte-access: Bit 7 shows the 
-		level of the IRQ-line of IDE port 2. 
-		(Catweasel only!)
-
-$f81-$fbf	mirror of $f80
-
-$fc0		write-only: Writing any value to this
-		register enables IRQs to be passed from the 
-		IDE ports to the Zorro bus. This mechanism 
-		has been implemented to be compatible with 
-		harddisks that are either defective or have
-		a buggy firmware and pull the IRQ line up 
-		while starting up. If interrupts would 
-		always be passed to the bus, the computer 
-		might not start up. Once enabled, this flag 
-		can not be disabled again. The level of the 
-		flag can not be determined by software 
-		(what for? Write to me if it's necessary!).
-
-$fc1-$fff	mirror of $fc0
-
-$1000-$ffff	Buddha-Rom with offset $1000 in the rom
-		chip. The addresses $0 to $fff of the rom 
-		chip cannot be read. Rom is Byte-wide and
-		mapped to even addresses.
-
-The  IDE ports issue an INT2.  You can read the level of the
-IRQ-lines  of  the  IDE-ports by reading from the three (two
-for  Buddha-only)  registers  $f00, $f40 and $f80.  This way
-more  than one I/O request can be handled and you can easily
-determine  what  driver  has  to serve the INT2.  Buddha and
-Catweasel  expansion  boards  can issue an INT6.  A seperate
-memory  map  is available for the I/O module and the sysop's
-I/O module.
-
-The IDE ports are fed by the address lines A2 to A4, just as
-the  Amiga  1200  and  Amiga  4000  IDE ports are.  This way
-existing  drivers  can be easily ported to Buddha.  A move.l
-polls  two  words  out of the same address of IDE port since
-every  word  is  mirrored  once.  movem is not possible, but
-it's  not  necessary  either,  because  you can only speedup
-68000  systems  with  this  technique.   A 68020 system with
-fastmem is faster with move.l.
-
-If you're using the mirrored registers of the IDE-ports with
-A6=1,  the Buddha doesn't care about the speed that you have
-selected  in  the  speed  register (see further down).  With
-A6=1  (for example $840 for port 0, register set 0), a 780ns
-access  is being made.  These registers should be used for a
-command   access   to  the  harddisk/CD-Rom,  since  command
-accesses  are Byte-wide and have to be made slower according
-to the ATA-X3T9 manual.
-
-Now  for the speed-register:  The register is byte-wide, and
-only  the  upper  three  bits are used (Bits 7 to 5).  Bit 4
-must  always  be set to 1 to be compatible with later Buddha
-versions  (if  I'll  ever  update this one).  I presume that
-I'll  never use the lower four bits, but they have to be set
-to 1 by definition.
-  The  values in this table have to be shifted 5 bits to the
-left and or'd with $1f (this sets the lower 5 bits).
-
-All  the timings have in common:  Select and IOR/IOW rise at
-the  same  time.   IOR  and  IOW have a propagation delay of
-about  30ns  to  the clocks on the Zorro bus, that's why the
-values  are no multiple of 71.  One clock-cycle is 71ns long
-(exactly 70,5 at 14,18 Mhz on PAL systems).
-
-value 0 (Default after reset)
-
-497ns Select (7 clock cycles) , IOR/IOW after 172ns (2 clock cycles)
-(same timing as the Amiga 1200 does on it's IDE port without
-accelerator card)
-
-value 1
-
-639ns Select (9 clock cycles), IOR/IOW after 243ns (3 clock cycles)
-
-value 2
-
-781ns Select (11 clock cycles), IOR/IOW after 314ns (4 clock cycles)
-
-value 3
-
-355ns Select (5 clock cycles), IOR/IOW after 101ns (1 clock cycle)
-
-value 4
-
-355ns Select (5 clock cycles), IOR/IOW after 172ns (2 clock cycles)
-
-value 5
-
-355ns Select (5 clock cycles), IOR/IOW after 243ns (3 clock cycles)
-
-value 6
-
-1065ns Select (15 clock cycles), IOR/IOW after 314ns (4 clock cycles)
-
-value 7
-
-355ns Select, (5 clock cycles), IOR/IOW after 101ns (1 clock cycle)
-
-When accessing IDE registers with A6=1 (for example $84x),
-the timing will always be mode 0 8-bit compatible, no matter
-what you have selected in the speed register:
-
-781ns select, IOR/IOW after 4 clock cycles (=314ns) aktive. 
-
-All  the  timings with a very short select-signal (the 355ns
-fast  accesses)  depend  on the accelerator card used in the
-system:  Sometimes two more clock cycles are inserted by the
-bus  interface,  making  the  whole access 497ns long.  This
-doesn't  affect  the  reliability  of the controller nor the
-performance  of  the  card,  since  this doesn't happen very
-often.
-
-All  the  timings  are  calculated  and  only  confirmed  by
-measurements  that allowed me to count the clock cycles.  If
-the  system  is clocked by an oscillator other than 28,37516
-Mhz  (for  example  the  NTSC-frequency  28,63636 Mhz), each
-clock  cycle is shortened to a bit less than 70ns (not worth
-mentioning).   You  could think of a small performance boost
-by  overclocking  the  system,  but  you would either need a
-multisync  monitor,  or  a  graphics card, and your internal
-diskdrive would go crazy, that's why you shouldn't tune your
-Amiga this way.
-
-Giving  you  the  possibility  to  write  software  that  is
-compatible  with both the Buddha and the Catweasel Z-II, The
-Buddha  acts  just  like  a  Catweasel  Z-II  with no device
-connected  to  the  third  IDE-port.   The IRQ-register $f80
-always  shows a "no IRQ here" on the Buddha, and accesses to
-the  third  IDE  port  are  going into data's Nirwana on the
-Buddha.
-
-			    Jens Schönfeld february 19th, 1997
-					updated may 27th, 1997
-			     eMail: sysop@nostlgic.tng.oche.de
-
diff -u --recursive --new-file v2.3.47/linux/drivers/block/README.fd linux/drivers/block/README.fd
--- v2.3.47/linux/drivers/block/README.fd	Mon Dec 20 18:48:21 1999
+++ linux/drivers/block/README.fd	Wed Dec 31 16:00:00 1969
@@ -1,222 +0,0 @@
-This Readme file describes the floppy driver.
-
-FAQ list:
-=========
-
- A FAQ list may be found in the fdutils package (see below), and also
-at http://fdutils.linux.lu/FAQ.html
-
-
-LILO configuration options (Thinkpad users, read this)
-======================================================
-
- The floppy driver is configured using the 'floppy=' option in
-lilo. This option can be typed at the boot prompt, or entered in the
-lilo configuration file.
- Example: If your kernel is called linux-2.2.13, type the following line
-at the lilo boot prompt (if you have a thinkpad):
- linux-2.2.13 floppy=thinkpad
-You may also enter the following line in /etc/lilo.conf, in the description
-of linux-2.2.13:
- append = "floppy=thinkpad"
-
- Several floppy related options may be given, example:
- linux-2.2.13 floppy=daring floppy=two_fdc
- append = "floppy=daring floppy=two_fdc"
-
- If you give options both in the lilo config file and on the boot
-prompt, the option strings of both places are concatenated, the boot
-prompt options coming last. That's why there are also options to
-restore the default behavior.
-
- If you use the floppy driver as a module, use the following syntax:
- insmod floppy <options>
-
-Example:
- insmod floppy daring two_fdc
-
- Some versions of insmod are buggy in one way or another. If you have
-any problems (options not being passed correctly, segfaults during
-insmod), first check whether there is a more recent version.
-
- The floppy related options include:
-
- floppy=asus_pci
-	Sets the bit mask to allow only units 0 and 1. (default)
-
- floppy=daring
-	Tells the floppy driver that you have a well behaved floppy controller.
-	This allows more efficient and smoother operation, but may fail on
-	certain controllers. This may speed up certain operations.
-
- floppy=0,daring
-	Tells the floppy driver that your floppy controller should be used
-	with caution.
-
- floppy=one_fdc
-	Tells the floppy driver that you have only one floppy controller.
-	(default)
-
- floppy=two_fdc
- floppy=<address>,two_fdc
-	Tells the floppy driver that you have two floppy controllers.
-	The second floppy controller is assumed to be at <address>.
-	This option is not needed if the second controller is at address
-	0x370, and if you use the 'cmos' option.
-
- floppy=thinkpad
-	Tells the floppy driver that you have a Thinkpad. Thinkpads use an
-	inverted convention for the disk change line.
-
- floppy=0,thinkpad
-	Tells the floppy driver that you don't have a Thinkpad.
-
- floppy=omnibook
- floppy=nodma
-	Tells the floppy driver not to use Dma for data transfers.
-	This is needed on HP Omnibooks, which don't have a workable
-	DMA channel for the floppy driver. This option is also useful
-	if you frequently get "Unable to allocate DMA memory" messages.
-	Indeed, dma memory needs to be continuous in physical memory,
-	and is thus harder to find, whereas non-dma buffers may be
-	allocated in virtual memory. However, I advise against this if
-	you have an FDC without a FIFO (8272A or 82072). 82072A and
-	later are OK. You also need at least a 486 to use nodma.
-	If you use nodma mode, I suggest you also set the FIFO
-	threshold to 10 or lower, in order to limit the number of data
-	transfer interrupts.
-
-	If you have a FIFO-able FDC, the floppy driver automatically
-	falls back on non DMA mode if no DMA-able memory can be found.
-	If you want to avoid this, explicitely ask for 'yesdma'.
-
- floppy=yesdma
-	Tells the floppy driver that a workable DMA channel is available.
-	(default)
-
- floppy=nofifo
-	Disables the FIFO entirely. This is needed if you get "Bus
-	master arbitration error" messages from your Ethernet card (or
-	from other devices) while accessing the floppy.
-
- floppy=fifo
-	Enables the FIFO. (default)
-
- floppy=<threshold>,fifo_depth
-	Sets the FIFO threshold. This is mostly relevant in DMA
-	mode. If this is higher, the floppy driver tolerates more
-	interrupt latency, but it triggers more interrupts (i.e. it
-	imposes more load on the rest of the system). If this is
-	lower, the interrupt latency should be lower too (faster
-	processor). The benefit of a lower threshold is less
-	interrupts.
-	To tune the fifo threshold, switch on over/underrun messages
-	using 'floppycontrol --messages'. Then access a floppy
-	disk. If you get a huge amount of "Over/Underrun - retrying"
-	messages, then the fifo threshold is too low. Try with a
-	higher value, until you only get an occasional Over/Underrun.
-	It is a good idea to compile the floppy driver as a module
-	when doing this tuning. Indeed, it allows to try different
-	fifo values without rebooting the machine for each test. Note
-	that you need to do 'floppycontrol --messages' every time you
-	re-insert the module.
-	Usually, tuning the fifo threshold should not be needed, as
-	the default (0xa) is reasonable.
-
- floppy=<drive>,<type>,cmos
-	Sets the CMOS type of <drive> to <type>. This is mandatory if
-	you have more than two floppy drives (only two can be
-	described in the physical CMOS), or if your BIOS uses
-	non-standard CMOS types. The CMOS types are:
-		0 - Use the value of the physical CMOS
-		1 - 5 1/4 DD
-		2 - 5 1/4 HD
-		3 - 3 1/2 DD
-		4 - 3 1/2 HD
-		5 - 3 1/2 ED
-		6 - 3 1/2 ED
-	       16 - unknown or not installed
-	(Note: there are two valid types for ED drives. This is because 5 was
-	initially chosen to represent floppy *tapes*, and 6 for ED drives.
-	AMI ignored this, and used 5 for ED drives. That's why the floppy
-	driver handles both.)
-
- floppy=unexpected_interrupts
-	Print a warning message when an unexpected interrupt is received.
-	(default)
-
- floppy=no_unexpected_interrupts
- floppy=L40SX
-	Don't print a message when an unexpected interrupt is received. This
-	is needed on IBM L40SX laptops in certain video modes. (There seems
-	to be an interaction between video and floppy. The unexpected
-	interrupts affect only performance, and can be safely ignored.)
-
- floppy=broken_dcl
-	Don't use the disk change line, but assume that the disk was
-	changed whenever the device node is reopened. Needed on some
-	boxes where the disk change line is broken or unsupported.
-	This should be regarded as a stopgap measure, indeed it makes
-	floppy operation less efficient due to unneeded cache
-	flushings, and slightly more unreliable. Please verify your
-	cable, connection and jumper settings if you have any DCL
-	problems. However, some older drives, and also some laptops
-	are known not to have a DCL.
-
- floppy=debug
-	Print debugging messages.
-
- floppy=messages
-	Print informational messages for some operations (disk change
-	notifications, warnings about over and underruns, and about
-	autodetection).
-
- floppy=silent_dcl_clear
-	Uses a less noisy way to clear the disk change line (which
-	doesn't involve seeks). Implied by 'daring' option.
-
- floppy=<nr>,irq
-	Sets the floppy IRQ to <nr> instead of 6.
-
- floppy=<nr>,dma
-	Sets the floppy DMA channel to <nr> instead of 2.
-
- floppy=slow
-	Use PS/2 stepping rate:
-	 " PS/2 floppies have much slower step rates than regular floppies.
-	   It's been recommended that take about 1/4 of the default speed
-	   in some more extreme cases."
-
-
-
-Supporting utilities and additional documentation:
-==================================================
-
- Additional parameters of the floppy driver can be configured at
-runtime. Utilities which do this can be found in the fdutils package.
-This package also contains a new version of mtools which allows to
-access high capacity disks (up to 1992K on a high density 3 1/2 disk!).
-It also contains additional documentation about the floppy driver.
-
-The latest version can be found at fdutils homepage:
- http://fdutils.linux.lu
-
-The fdutils-5.3 release can be found at:
- http://fdutils.linux.lu/fdutils-5.3.src.tar.gz
- http://www.tux.org/pub/knaff/fdutils/fdutils-5.3.src.tar.gz
- ftp://tsx-11.mit.edu/pub/linux/sources/sbin/fdutils-5.3.src.tar.gz
- ftp://metalab.unc.edu/pub/Linux/utils/disk-management/fdutils-5.3.src.tar.gz
-
-Reporting problems about the floppy driver
-==========================================
-
- If you have a question or a bug report about the floppy driver, mail
-me at Alain.Knaff@poboxes.com . If you post to Usenet, preferably use
-comp.os.linux.hardware. As the volume in these groups is rather high,
-be sure to include the word "floppy" (or "FLOPPY") in the subject
-line.  If the reported problem happens when mounting floppy disks, be
-sure to mention also the type of the filesystem in the subject line.
-
- Be sure to read the FAQ before mailing/posting any bug reports!
-
- Alain
diff -u --recursive --new-file v2.3.47/linux/drivers/block/README.lvm linux/drivers/block/README.lvm
--- v2.3.47/linux/drivers/block/README.lvm	Sun Feb 20 21:12:38 2000
+++ linux/drivers/block/README.lvm	Wed Dec 31 16:00:00 1969
@@ -1,8 +0,0 @@
-
-This is the Logical Volume Manager driver for Linux,
-
-Tools, library that manage logical volumes can be found
-at <http://linux.msede.com/lvm>.
-
-There you can obtain actual driver versions too.
-
diff -u --recursive --new-file v2.3.47/linux/drivers/block/README.md linux/drivers/block/README.md
--- v2.3.47/linux/drivers/block/README.md	Tue Jun 11 03:00:11 1996
+++ linux/drivers/block/README.md	Wed Dec 31 16:00:00 1969
@@ -1,4 +0,0 @@
-Tools that manage md devices can be found at sweet-smoke.ufr-info-p7.ibp.fr
-in public/Linux/md035.tar.gz.
-
-	Marc ZYNGIER <zyngier@ufr-info-p7.ibp.fr>
diff -u --recursive --new-file v2.3.47/linux/drivers/block/aec6210.c linux/drivers/block/aec6210.c
--- v2.3.47/linux/drivers/block/aec6210.c	Fri Jan 21 18:19:16 2000
+++ linux/drivers/block/aec6210.c	Sat Feb 26 20:32:13 2000
@@ -1,7 +1,7 @@
 /*
- * linux/drivers/block/aec6210.c	Version 0.04	Dec. 13, 1999
+ * linux/drivers/block/aec6210.c		Version 0.05	Feb. 10, 2000
  *
- * Copyright (C) 1998-99	Andre Hedrick (andre@suse.com)
+ * Copyright (C) 1998-2000	Andre Hedrick (andre@suse.com)
  * May be copied or modified under the terms of the GNU General Public License
  *
  *  pio 0 ::       40: 00 07 00 00 00 00 00 00 02 07 a6 04 00 02 00 02
@@ -56,7 +56,52 @@
 
 #define ACARD_DEBUG_DRIVE_INFO 1
 
-#ifdef CONFIG_BLK_DEV_AEC6210_TUNING
+#define DISPLAY_AEC6210_TIMINGS
+
+#if defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static int aec6210_get_info(char *, char **, off_t, int);
+extern int (*aec6210_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+extern char *ide_media_verbose(ide_drive_t *);
+static struct pci_dev *bmide_dev;
+
+static int aec6210_get_info (char *buffer, char **addr, off_t offset, int count)
+{
+	char *p = buffer;
+
+	u32 bibma = bmide_dev->resource[4].start;
+	u8 c0 = 0, c1 = 0;
+	
+	p += sprintf(p, "\n                                AEC6210 Chipset.\n");
+
+        /*
+         * at that point bibma+0x2 et bibma+0xa are byte registers
+         * to investigate:
+         */
+	c0 = inb_p((unsigned short)bibma + 0x02);
+	c1 = inb_p((unsigned short)bibma + 0x0a);
+
+	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+	p += sprintf(p, "                %sabled                         %sabled\n",
+			(c0&0x80) ? "dis" : " en",
+			(c1&0x80) ? "dis" : " en");
+	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
+	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
+			(c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
+			(c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
+
+	p += sprintf(p, "UDMA\n");
+	p += sprintf(p, "DMA\n");
+	p += sprintf(p, "PIO\n");
+	return p-buffer;/* => must be less than 4k! */
+}
+#endif	/* defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+byte aec6210_proc = 0;
+
+#ifdef CONFIG_AEC6210_TUNING
 
 struct chipset_bus_clock_list_entry {
 	byte		xfer_speed;
@@ -269,7 +314,7 @@
 	}
 	return ide_dmaproc(func, drive);	/* use standard DMA stuff */
 }
-#endif /* CONFIG_BLK_DEV_AEC6210_TUNING */
+#endif /* CONFIG_AEC6210_TUNING */
 
 unsigned int __init pci_init_aec6210 (struct pci_dev *dev, const char *name)
 {
@@ -277,12 +322,19 @@
 		pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
 		printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);
 	}
+
+#if defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS)
+	aec6210_proc = 1;
+	bmide_dev = dev;
+	aec6210_display_info = &aec6210_get_info;
+#endif /* DISPLAY_AEC6210_TIMINGS && CONFIG_PROC_FS */
+
 	return dev->irq;
 }
 
 void __init ide_init_aec6210 (ide_hwif_t *hwif)
 {
-#ifdef CONFIG_BLK_DEV_AEC6210_TUNING
+#ifdef CONFIG_AEC6210_TUNING
 	hwif->tuneproc = &aec6210_tune_drive;
 
 	if (hwif->dma_base) {
@@ -291,7 +343,7 @@
 		hwif->drives[0].autotune = 1;
 		hwif->drives[1].autotune = 1;
 	}
-#endif /* CONFIG_BLK_DEV_AEC6210_TUNING */
+#endif /* CONFIG_AEC6210_TUNING */
 }
 
 void __init ide_dmacapable_aec6210 (ide_hwif_t *hwif, unsigned long dmabase)
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ali14xx.c linux/drivers/block/ali14xx.c
--- v2.3.47/linux/drivers/block/ali14xx.c	Thu Nov 18 20:25:37 1999
+++ linux/drivers/block/ali14xx.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ali14xx.c       Version 0.03  Feb 09, 1996
+ *  linux/drivers/block/ali14xx.c		Version 0.03	Feb 09, 1996
  *
  *  Copyright (C) 1996  Linus Torvalds & author (see below)
  */
@@ -55,12 +55,12 @@
 
 /* port addresses for auto-detection */
 #define ALI_NUM_PORTS 4
-static int ports[ALI_NUM_PORTS] = {0x074, 0x0f4, 0x034, 0x0e4};
+static int __init ports[ALI_NUM_PORTS] = {0x074, 0x0f4, 0x034, 0x0e4};
 
 /* register initialization data */
 typedef struct { byte reg, data; } RegInitializer;
 
-static RegInitializer initData[] = {
+static RegInitializer __init initData[] = {
 	{0x01, 0x0f}, {0x02, 0x00}, {0x03, 0x00}, {0x04, 0x00},
 	{0x05, 0x00}, {0x06, 0x00}, {0x07, 0x2b}, {0x0a, 0x0f},
 	{0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, {0x28, 0x00},
@@ -150,7 +150,7 @@
 /*
  * Auto-detect the IDE controller port.
  */
-static int findPort (void)
+static int __init findPort (void)
 {
 	int i;
 	byte t;
@@ -183,7 +183,7 @@
 /*
  * Initialize controller registers with default values.
  */
-static int initRegisters (void) {
+static int __init initRegisters (void) {
 	RegInitializer *p;
 	byte t;
 	unsigned long flags;
@@ -200,7 +200,7 @@
 	return t;
 }
 
-void init_ali14xx (void)
+void __init init_ali14xx (void)
 {
 	/* auto-detect IDE controller port */
 	if (!findPort()) {
diff -u --recursive --new-file v2.3.47/linux/drivers/block/alim15x3.c linux/drivers/block/alim15x3.c
--- v2.3.47/linux/drivers/block/alim15x3.c	Fri Jan 28 15:09:07 2000
+++ linux/drivers/block/alim15x3.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/block/alim15x3.c	Version 0.08	Jan. 14, 2000
+ * linux/drivers/block/alim15x3.c		Version 0.08	Jan. 14, 2000
  *
  *  Copyright (C) 1998-2000 Michel Aubry, Maintainer
  *  Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
@@ -493,7 +493,6 @@
 		default:
 			break;
 	}
-
 	return ide_dmaproc(func, drive);	/* use standard DMA stuff */
 }
 
@@ -518,6 +517,13 @@
 		if (inb(fixdma_base+2) & 0x80)
 			printk("%s: simplex device: DMA will fail!!\n", name);
 	}
+
+#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
+	ali_proc = 1;
+	bmide_dev = dev;
+	ali_display_info = &ali_get_info;
+#endif  /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
+
 	return 0;
 }
 
@@ -666,22 +672,11 @@
 		 */
 		hwif->dmaproc = &ali15x3_dmaproc;
 		hwif->autodma = 1;
-		hwif->drives[0].autotune = 0;
-		hwif->drives[1].autotune = 0;
 	} else {
 		hwif->autodma = 0;
 		hwif->drives[0].autotune = 1;
 		hwif->drives[1].autotune = 1;
 	}
-	
-#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
-	if (!ali_proc) {
-		ali_proc = 1;
-		bmide_dev = hwif->pci_dev;
-		ali_display_info = &ali_get_info;
-	}
-#endif  /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
-
 	return;
 }
 
diff -u --recursive --new-file v2.3.47/linux/drivers/block/amd7409.c linux/drivers/block/amd7409.c
--- v2.3.47/linux/drivers/block/amd7409.c	Fri Jan 21 18:19:16 2000
+++ linux/drivers/block/amd7409.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/block/amd7409.c	Version 0.01	Jan. 10, 2000
+ * linux/drivers/block/amd7409.c		Version 0.03	Feb. 10, 2000
  *
  * Copyright (C) 2000			Andre Hedrick <andre@suse.com>
  * May be copied or modified under the terms of the GNU General Public License
@@ -24,6 +24,51 @@
 
 #include "ide_modes.h"
 
+#define DISPLAY_VIPER_TIMINGS
+
+#if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static int amd7409_get_info(char *, char **, off_t, int);
+extern int (*amd7409_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+extern char *ide_media_verbose(ide_drive_t *);
+static struct pci_dev *bmide_dev;
+
+static int amd7409_get_info (char *buffer, char **addr, off_t offset, int count)
+{
+	char *p = buffer;
+	u32 bibma = bmide_dev->resource[4].start;
+	u8 c0 = 0, c1 = 0;
+
+	/*
+	 * at that point bibma+0x2 et bibma+0xa are byte registers
+	 * to investigate:
+	 */
+	c0 = inb_p((unsigned short)bibma + 0x02);
+	c1 = inb_p((unsigned short)bibma + 0x0a);
+
+	p += sprintf(p, "\n                                AMD 7409 VIPER Chipset.\n");
+	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+	p += sprintf(p, "                %sabled                         %sabled\n",
+			(c0&0x80) ? "dis" : " en",
+			(c1&0x80) ? "dis" : " en");
+	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
+	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
+			(c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
+			(c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
+	p += sprintf(p, "UDMA\n");
+	p += sprintf(p, "DMA\n");
+	p += sprintf(p, "PIO\n");
+
+	return p-buffer;	/* => must be less than 4k! */
+}
+#endif  /* defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+byte amd7409_proc = 0;
+
+extern char *ide_xfer_verbose (byte xfer_rate);
+
 /*
  * Here is where all the hard work goes to program the chipset.
  *
@@ -33,11 +78,13 @@
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= hwif->pci_dev;
 	int err			= 0;
-	int drive_number	= ((HWIF(drive)->channel ? 2 : 0) +
-				   (drive->select.b.unit & 0x01));
+	byte unit		= (drive->select.b.unit & 0x01);
+	int drive_number	= ((HWIF(drive)->channel ? 2 : 0) + unit);
+	unsigned long dma_base	= hwif->dma_base;
 	byte drive_pci		= 0x00;
 	byte drive_pci2		= 0x00;
-	byte drive_timing	= 0x00;
+	byte ultra_timing	= 0x00;
+	byte dma_pio_timing	= 0x00;
 	byte pio_timing		= 0x00;
 
         switch (drive_number) {
@@ -49,54 +96,99 @@
                         return ((int) ide_dma_off_quietly);
         }
 
-	pci_read_config_byte(dev, drive_pci, &drive_timing);
-	pci_read_config_byte(dev, drive_pci2, &pio_timing);
+	pci_read_config_byte(dev, drive_pci, &ultra_timing);
+	pci_read_config_byte(dev, drive_pci2, &dma_pio_timing);
+	pci_read_config_byte(dev, 0x4c, &pio_timing);
+
+#ifdef DEBUG
+	printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
+		drive->name, ultra_timing, dma_pio_timing, pio_timing);
+#endif
 
-	printk("%s: UDMA 0x%02x PIO 0x%02x ",
-		drive->name, drive_timing, pio_timing);
+	ultra_timing &= ~0xC7;
+	dma_pio_timing &= ~0xFF;
+	pio_timing &= ~(0x03 << drive_number);
+
+#ifdef DEBUG
+	printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
+		ultra_timing, dma_pio_timing, pio_timing);
+#endif
 
 	switch(speed) {
 		case XFER_UDMA_4:
-			drive_timing &= ~0xC7;
-			drive_timing |= 0x45;
-			pci_write_config_byte(dev, drive_pci, drive_timing);
+			ultra_timing |= 0x45;
+			dma_pio_timing |= 0x20;
+			pio_timing |= (0x03 << drive_number);
 			break;
 		case XFER_UDMA_3:
-			drive_timing &= ~0xC7;
-			drive_timing |= 0x44;
-			pci_write_config_byte(dev, drive_pci, drive_timing);
+			ultra_timing |= 0x44;
+			dma_pio_timing |= 0x20;
+			pio_timing |= (0x03 << drive_number);
 			break;
 		case XFER_UDMA_2:
-			drive_timing &= ~0xC7;
-			drive_timing |= 0x40;
-			pci_write_config_byte(dev, drive_pci, drive_timing);
+			ultra_timing |= 0x40;
+			dma_pio_timing |= 0x20;
+			pio_timing |= (0x03 << drive_number);
 			break;
 		case XFER_UDMA_1:
-			drive_timing &= ~0xC7;
-			drive_timing |= 0x41;
-			pci_write_config_byte(dev, drive_pci, drive_timing);
+			ultra_timing |= 0x41;
+			dma_pio_timing |= 0x20;
+			pio_timing |= (0x03 << drive_number);
 			break;
 		case XFER_UDMA_0:
-			drive_timing &= ~0xC7;
-			drive_timing |= 0x42;
-			pci_write_config_byte(dev, drive_pci, drive_timing);
-			break;
-		case XFER_MW_DMA_2:break;
-		case XFER_MW_DMA_1:break;
-		case XFER_MW_DMA_0:break;
-		case XFER_SW_DMA_2:break;
-		case XFER_SW_DMA_1:break;
-		case XFER_SW_DMA_0:break;
-		case XFER_PIO_4:break;
-		case XFER_PIO_3:break;
-		case XFER_PIO_2:break;
-		case XFER_PIO_1:break;
-		case XFER_PIO_0:break;
-		default: break;
+			ultra_timing |= 0x42;
+			dma_pio_timing |= 0x20;
+			pio_timing |= (0x03 << drive_number);
+			break;
+		case XFER_MW_DMA_2:
+			dma_pio_timing |= 0x20;
+			pio_timing |= (0x03 << drive_number);
+			break;
+		case XFER_MW_DMA_1:
+			dma_pio_timing |= 0x21;
+			pio_timing |= (0x03 << drive_number);
+			break;
+		case XFER_MW_DMA_0:
+			dma_pio_timing |= 0x77;
+			pio_timing |= (0x03 << drive_number);
+			break;
+		case XFER_PIO_4:
+			dma_pio_timing |= 0x20;
+			pio_timing |= (0x03 << drive_number);
+			break;
+		case XFER_PIO_3:
+			dma_pio_timing |= 0x22;
+			pio_timing |= (0x03 << drive_number);
+			break;
+		case XFER_PIO_2:
+			dma_pio_timing |= 0x42;
+			pio_timing |= (0x03 << drive_number);
+			break;
+		case XFER_PIO_1:
+			dma_pio_timing |= 0x65;
+			pio_timing |= (0x03 << drive_number);
+			break;
+		case XFER_PIO_0:
+		default:
+			dma_pio_timing |= 0xA8;
+			pio_timing |= (0x03 << drive_number);
+			break;
         }
 
-	printk(":: UDMA 0x%02x PIO 0x%02x\n", drive_timing, pio_timing);
+	pci_write_config_byte(dev, drive_pci, ultra_timing);
+	pci_write_config_byte(dev, drive_pci2, dma_pio_timing);
+	pci_write_config_byte(dev, 0x4c, pio_timing);
+
+#ifdef DEBUG
+	printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
+		ultra_timing, dma_pio_timing, pio_timing);
+#endif
 
+	if (speed > XFER_PIO_4) {
+		outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
+	} else {
+		outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
+	}
 	err = ide_config_drive_speed(drive, speed);
 	return (err);
 }
@@ -109,12 +201,14 @@
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
 	struct hd_driveid *id	= drive->id;
+	byte udma_66		= ((id->hw_config & 0x2000) &&
+				   (HWIF(drive)->udma_four)) ? 1 : 0;
 	byte speed		= 0x00;
 	int  rval;
 
-	if ((id->dma_ultra & 0x0010) && (HWIF(drive)->udma_four)) {
+	if ((id->dma_ultra & 0x0010) && (udma_66)) {
 		speed = XFER_UDMA_4;
-	} else if ((id->dma_ultra & 0x0008) && (HWIF(drive)->udma_four)) {
+	} else if ((id->dma_ultra & 0x0008) && (udma_66)) {
 		speed = XFER_UDMA_3;
 	} else if (id->dma_ultra & 0x0004) {
 		speed = XFER_UDMA_2;
@@ -128,12 +222,6 @@
 		speed = XFER_MW_DMA_1;
 	} else if (id->dma_mword & 0x0001) {
 		speed = XFER_MW_DMA_0;
-	} else if (id->dma_1word & 0x0004) {
-		speed = XFER_SW_DMA_2;
-	} else if (id->dma_1word & 0x0002) {
-		speed = XFER_SW_DMA_1;
-	} else if (id->dma_1word & 0x0001) {
-		speed = XFER_SW_DMA_0;
         } else {
 		return ((int) ide_dma_off_quietly);
 	}
@@ -143,7 +231,6 @@
 	rval = (int)(	((id->dma_ultra >> 11) & 3) ? ide_dma_on :
 			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
 			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-			((id->dma_1word >> 8) & 7) ? ide_dma_on :
 						     ide_dma_off_quietly);
 
 	return rval;
@@ -222,8 +309,7 @@
 			}
 		} else if (id->field_valid & 2) {
 try_dma_modes:
-			if ((id->dma_mword & 0x0007) ||
-			    (id->dma_1word & 0x0007)) {
+			if (id->dma_mword & 0x0007) {
 				/* Force if Capable regular DMA modes */
 				dma_func = config_chipset_for_dma(drive);
 				if (dma_func != ide_dma_on)
@@ -265,16 +351,45 @@
 	return ide_dmaproc(func, drive);	/* use standard DMA stuff */
 }
 
+unsigned int __init pci_init_amd7409 (struct pci_dev *dev, const char *name)
+{
+	unsigned long fixdma_base = dev->resource[4].start;
+
+	if (!fixdma_base || fixdma_base == PCI_BASE_ADDRESS_IO_MASK) {
+		/*
+		 *
+		 */
+	} else {
+		/*
+		 * enable DMA capable bit, and "not" simplex only
+		 */
+		outb(inb(fixdma_base+2) & 0x60, fixdma_base+2);
+
+		if (inb(fixdma_base+2) & 0x80)
+			printk("%s: simplex device: DMA will fail!!\n", name);
+	}
+#if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS)
+	amd7409_proc = 1;
+	bmide_dev = dev;
+	amd7409_display_info = &amd7409_get_info;
+#endif /* DISPLAY_VIPER_TIMINGS && CONFIG_PROC_FS */
+
+	return 0;
+}
+
 unsigned int __init ata66_amd7409 (ide_hwif_t *hwif)
 {
-#if 0
+#ifdef CONFIG_AMD7409_OVERRIDE
+	byte ata66 = 1;
+#else
 	byte ata66 = 0;
+#endif /* CONFIG_AMD7409_OVERRIDE */
 
+#if 0
 	pci_read_config_byte(hwif->pci_dev, 0x48, &ata66);
 	return ((ata66 & 0x02) ? 0 : 1);
-#else
-	return 0;
 #endif
+	return ata66;
 }
 
 void __init ide_init_amd7409 (ide_hwif_t *hwif)
@@ -287,4 +402,9 @@
 		hwif->drives[0].autotune = 1;
 		hwif->drives[1].autotune = 1;
 	}
+}
+
+void ide_dmacapable_amd7409 (ide_hwif_t *hwif, unsigned long dmabase)
+{
+	ide_setup_dma(hwif, dmabase, 8);
 }
diff -u --recursive --new-file v2.3.47/linux/drivers/block/buddha.c linux/drivers/block/buddha.c
--- v2.3.47/linux/drivers/block/buddha.c	Fri Jan 28 15:09:07 2000
+++ linux/drivers/block/buddha.c	Sat Feb 26 20:32:13 2000
@@ -42,7 +42,7 @@
 #define BUDDHA_BASE2	0xa00
 #define BUDDHA_BASE3	0xc00
 
-static const u_int buddha_bases[CATWEASEL_NUM_HWIFS] = {
+static const u_int __init buddha_bases[CATWEASEL_NUM_HWIFS] = {
     BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3
 };
 
@@ -61,7 +61,7 @@
 #define BUDDHA_STATUS	0x1e		/* see status-bits */
 #define BUDDHA_CONTROL	0x11a
 
-static int buddha_offsets[IDE_NR_PORTS] = {
+static int __init buddha_offsets[IDE_NR_PORTS] = {
     BUDDHA_DATA, BUDDHA_ERROR, BUDDHA_NSECTOR, BUDDHA_SECTOR, BUDDHA_LCYL,
     BUDDHA_HCYL, BUDDHA_SELECT, BUDDHA_STATUS, BUDDHA_CONTROL
 };
@@ -75,7 +75,7 @@
 #define BUDDHA_IRQ2	0xf40		/* interrupt */
 #define BUDDHA_IRQ3	0xf80
 
-static const int buddha_irqports[CATWEASEL_NUM_HWIFS] = {
+static const int __init buddha_irqports[CATWEASEL_NUM_HWIFS] = {
     BUDDHA_IRQ1, BUDDHA_IRQ2, BUDDHA_IRQ3
 };
 
@@ -109,7 +109,7 @@
      *  Any Buddha or Catweasel boards present?
      */
 
-static int find_buddha(void)
+static int __init find_buddha(void)
 {
     struct zorro_dev *z = NULL;
 
@@ -143,7 +143,7 @@
      *  We support only _one_ of them, no multiple boards!
      */
 
-void buddha_init(void)
+void __init buddha_init(void)
 {
     hw_regs_t hw;
     int i, index;
diff -u --recursive --new-file v2.3.47/linux/drivers/block/cmd640.c linux/drivers/block/cmd640.c
--- v2.3.47/linux/drivers/block/cmd640.c	Thu Nov 18 20:25:37 1999
+++ linux/drivers/block/cmd640.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/cmd640.c	Version 1.02  Sep 01, 1996
+ *  linux/drivers/block/cmd640.c		Version 1.02  Sep 01, 1996
  *
  *  Copyright (C) 1995-1996  Linus Torvalds & authors (see below)
  */
@@ -290,7 +290,7 @@
 	return b;
 }
 
-static int match_pci_cmd640_device (void)
+static int __init match_pci_cmd640_device (void)
 {
 	const byte ven_dev[4] = {0x95, 0x10, 0x40, 0x06};
 	unsigned int i;
@@ -310,7 +310,7 @@
 /*
  * Probe for CMD640x -- pci method 1
  */
-static int probe_for_cmd640_pci1 (void)
+static int __init probe_for_cmd640_pci1 (void)
 {
 	get_cmd640_reg = get_cmd640_reg_pci1;
 	put_cmd640_reg = put_cmd640_reg_pci1;
@@ -324,7 +324,7 @@
 /*
  * Probe for CMD640x -- pci method 2
  */
-static int probe_for_cmd640_pci2 (void)
+static int __init probe_for_cmd640_pci2 (void)
 {
 	get_cmd640_reg = get_cmd640_reg_pci2;
 	put_cmd640_reg = put_cmd640_reg_pci2;
@@ -338,7 +338,7 @@
 /*
  * Probe for CMD640x -- vlb
  */
-static int probe_for_cmd640_vlb (void)
+static int __init probe_for_cmd640_vlb (void)
 {
 	byte b;
 
@@ -359,7 +359,7 @@
  *  Returns 1 if an IDE interface/drive exists at 0x170,
  *  Returns 0 otherwise.
  */
-static int secondary_port_responding (void)
+static int __init secondary_port_responding (void)
 {
 	unsigned long flags;
 
@@ -403,7 +403,7 @@
  * Check whether prefetch is on for a drive,
  * and initialize the unmask flags for safe operation.
  */
-static void check_prefetch (unsigned int index)
+static void __init check_prefetch (unsigned int index)
 {
 	ide_drive_t *drive = cmd_drives[index];
 	byte b = get_cmd640_reg(prefetch_regs[index]);
@@ -424,7 +424,7 @@
 /*
  * Figure out which devices we control
  */
-static void setup_device_ptrs (void)
+static void __init setup_device_ptrs (void)
 {
 	unsigned int i;
 
@@ -507,7 +507,7 @@
 /*
  * This routine retrieves the initial drive timings from the chipset.
  */
-static void retrieve_drive_counts (unsigned int index)
+static void __init retrieve_drive_counts (unsigned int index)
 {
 	byte b;
 
@@ -694,7 +694,7 @@
 /*
  * Probe for a cmd640 chipset, and initialize it if found.  Called from ide.c
  */
-int ide_probe_for_cmd640x (void)
+int __init ide_probe_for_cmd640x (void)
 {
 #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
 	int second_port_toggled = 0;
diff -u --recursive --new-file v2.3.47/linux/drivers/block/cmd64x.c linux/drivers/block/cmd64x.c
--- v2.3.47/linux/drivers/block/cmd64x.c	Tue Feb  1 01:35:43 2000
+++ linux/drivers/block/cmd64x.c	Sat Feb 26 20:32:13 2000
@@ -1,4 +1,4 @@
-/* $Id: cmd64x.c,v 1.20 1999/12/30 03:48:37
+/* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16
  *
  * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
  *           Note, this driver is not used at all on other systems because
@@ -8,7 +8,7 @@
  *
  * Copyright (C) 1998       Eddie C. Dost  (ecd@skynet.be)
  * Copyright (C) 1998       David S. Miller (davem@redhat.com)
- * Copyright (C) 1999       Andre Hedrick (andre@suse.com)
+ * Copyright (C) 1999-2000  Andre Hedrick (andre@suse.com)
  */
 
 #include <linux/types.h>
@@ -18,8 +18,10 @@
 #include <linux/ide.h>
 
 #include <asm/io.h>
+#include "ide_modes.h"
 
 #define CMD_DEBUG 0
+#undef NO_WRITE
 
 #if CMD_DEBUG
 #define cmdprintk(x...)	printk(##x)
@@ -27,6 +29,235 @@
 #define cmdprintk(x...)
 #endif
 
+/*
+ * CMD64x specific registers definition.
+ */
+
+#define CNTRL		0x51
+#define	  CNTRL_DIS_RA0		0x40
+#define   CNTRL_DIS_RA1		0x80
+#define	  CNTRL_ENA_2ND		0x08
+
+#define	CMDTIM		0x52
+#define	ARTTIM0		0x53
+#define	DRWTIM0		0x54
+#define ARTTIM1 	0x55
+#define DRWTIM1		0x56
+#define ARTTIM23	0x57
+#define   ARTTIM23_DIS_RA2	0x04
+#define   ARTTIM23_DIS_RA3	0x08
+#define DRWTIM23	0x58
+#define DRWTIM2		0x58
+#define BRST		0x59
+#define DRWTIM3		0x5b
+
+#define MRDMODE		0x71
+
+#define DISPLAY_CMD64X_TIMINGS
+
+#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static int cmd64x_get_info(char *, char **, off_t, int);
+extern int (*cmd64x_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+extern char *ide_media_verbose(ide_drive_t *);
+static struct pci_dev *bmide_dev;
+
+static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
+{
+	char *p = buffer;
+	u32 bibma = bmide_dev->resource[4].start;
+	u8  c0 = 0, c1 = 0;
+
+	switch(bmide_dev->device) {
+		case PCI_DEVICE_ID_CMD_648:
+			p += sprintf(p, "\n                                CMD648 Chipset.\n");
+			break;
+		case PCI_DEVICE_ID_CMD_646:
+			p += sprintf(p, "\n                                CMD646 Chipset.\n");
+			break;
+		case PCI_DEVICE_ID_CMD_643:
+			p += sprintf(p, "\n                                CMD643 Chipset.\n");
+			break;
+		default:
+			p += sprintf(p, "\n                                CMD64? Chipse.\n");
+			break;
+	}
+
+	/*
+	 * at that point bibma+0x2 et bibma+0xa are byte registers
+	 * to investigate:
+	 */
+	c0 = inb_p((unsigned short)bibma + 0x02);
+	c1 = inb_p((unsigned short)bibma + 0x0a);
+	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+	p += sprintf(p, "                %sabled                         %sabled\n",
+			(c0&0x80) ? "dis" : " en",
+			(c1&0x80) ? "dis" : " en");
+	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
+	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
+			(c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
+			(c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
+
+	p += sprintf(p, "UDMA\n");
+	p += sprintf(p, "DMA\n");
+	p += sprintf(p, "PIO\n");
+
+	return p-buffer;	/* => must be less than 4k! */
+}
+#endif	/* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+byte cmd64x_proc = 0;
+
+/*
+ * Registers and masks for easy access by drive index:
+ */
+#if 0
+static byte prefetch_regs[4]  = {CNTRL, CNTRL, ARTTIM23, ARTTIM23};
+static byte prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3};
+#endif
+
+/*
+ * This routine writes the prepared setup/active/recovery counts
+ * for a drive into the cmd646 chipset registers to active them.
+ */
+static void program_drive_counts (ide_drive_t *drive, int setup_count, int active_count, int recovery_count)
+{
+	unsigned long flags;
+	ide_drive_t *drives = HWIF(drive)->drives;
+	byte temp_b;
+	static const byte setup_counts[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
+	static const byte recovery_counts[] =
+		{15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0};
+	static const byte arttim_regs[2][2] = {
+			{ ARTTIM0, ARTTIM1 },
+			{ ARTTIM23, ARTTIM23 }
+		};
+	static const byte drwtim_regs[2][2] = {
+			{ DRWTIM0, DRWTIM1 },
+			{ DRWTIM2, DRWTIM3 }
+		};
+	int channel = (int) HWIF(drive)->channel;
+	int slave = (drives != drive);  /* Is this really the best way to determine this?? */
+
+	cmdprintk("program_drive_count parameters = s(%d),a(%d),r(%d),p(%d)\n", setup_count,
+		active_count, recovery_count, drive->present);
+	/*
+	 * Set up address setup count registers.
+	 * Primary interface has individual count/timing registers for
+	 * each drive.  Secondary interface has one common set of registers,
+	 * for address setup so we merge these timings, using the slowest
+	 * value.
+	 */
+	if (channel) {
+		drive->drive_data = setup_count;
+		setup_count = IDE_MAX(drives[0].drive_data, drives[1].drive_data);
+		cmdprintk("Secondary interface, setup_count = %d\n", setup_count);
+	}
+
+	/*
+	 * Convert values to internal chipset representation
+	 */
+	setup_count = (setup_count > 5) ? 0xc0 : (int) setup_counts[setup_count];
+	active_count &= 0xf; /* Remember, max value is 16 */
+	recovery_count = (int) recovery_counts[recovery_count];
+
+	cmdprintk("Final values = %d,%d,%d\n", setup_count, active_count, recovery_count);
+
+	/*
+	 * Now that everything is ready, program the new timings
+	 */
+	__save_flags (flags);
+	__cli();
+	/*
+	 * Program the address_setup clocks into ARTTIM reg,
+	 * and then the active/recovery counts into the DRWTIM reg
+	 */
+	(void) pci_read_config_byte(HWIF(drive)->pci_dev, arttim_regs[channel][slave], &temp_b);
+#ifndef NO_WRITE
+	(void) pci_write_config_byte(HWIF(drive)->pci_dev, arttim_regs[channel][slave],
+		((byte) setup_count) | (temp_b & 0x3f));
+	(void) pci_write_config_byte(HWIF(drive)->pci_dev, drwtim_regs[channel][slave],
+		(byte) ((active_count << 4) | recovery_count));
+#endif
+	cmdprintk ("Write %x to %x\n", ((byte) setup_count) | (temp_b & 0x3f), arttim_regs[channel][slave]);
+	cmdprintk ("Write %x to %x\n", (byte) ((active_count << 4) | recovery_count), drwtim_regs[channel][slave]);
+	__restore_flags(flags);
+}
+
+/*
+ * Attempts to set the interface PIO mode.
+ * The preferred method of selecting PIO modes (e.g. mode 4) is 
+ * "echo 'piomode:4' > /proc/ide/hdx/settings".  Special cases are
+ * 8: prefetch off, 9: prefetch on, 255: auto-select best mode.
+ * Called with 255 at boot time.
+ */
+static void cmd64x_tuneproc (ide_drive_t *drive, byte mode_wanted)
+{
+	int setup_time, active_time, recovery_time, clock_time, pio_mode, cycle_time;
+	byte recovery_count2, cycle_count;
+	int setup_count, active_count, recovery_count;
+	int bus_speed = ide_system_bus_speed();
+	/*byte b;*/
+	ide_pio_data_t  d;
+
+	switch (mode_wanted) {
+		case 8: /* set prefetch off */
+		case 9: /* set prefetch on */
+			mode_wanted &= 1;
+			/*set_prefetch_mode(index, mode_wanted);*/
+			cmdprintk("%s: %sabled cmd640 prefetch\n", drive->name, mode_wanted ? "en" : "dis");
+			return;
+	}
+
+	(void) ide_get_best_pio_mode (drive, mode_wanted, 5, &d);
+	pio_mode = d.pio_mode;
+	cycle_time = d.cycle_time;
+
+	/*
+	 * I copied all this complicated stuff from cmd640.c and made a few minor changes.
+	 * For now I am just going to pray that it is correct.
+	 */
+	if (pio_mode > 5)
+		pio_mode = 5;
+	setup_time  = ide_pio_timings[pio_mode].setup_time;
+	active_time = ide_pio_timings[pio_mode].active_time;
+	recovery_time = cycle_time - (setup_time + active_time);
+	clock_time = 1000 / bus_speed;
+	cycle_count = (cycle_time + clock_time - 1) / clock_time;
+
+	setup_count = (setup_time + clock_time - 1) / clock_time;
+
+	active_count = (active_time + clock_time - 1) / clock_time;
+
+	recovery_count = (recovery_time + clock_time - 1) / clock_time;
+	recovery_count2 = cycle_count - (setup_count + active_count);
+	if (recovery_count2 > recovery_count)
+		recovery_count = recovery_count2;
+	if (recovery_count > 16) {
+		active_count += recovery_count - 16;
+		recovery_count = 16;
+	}
+	if (active_count > 16)
+		active_count = 16; /* maximum allowed by cmd646 */
+
+	/*
+	 * In a perfect world, we might set the drive pio mode here
+	 * (using WIN_SETFEATURE) before continuing.
+	 *
+	 * But we do not, because:
+	 *	1) this is the wrong place to do it (proper is do_special() in ide.c)
+	 * 	2) in practice this is rarely, if ever, necessary
+	 */
+	program_drive_counts (drive, setup_count, active_count, recovery_count);
+
+	printk ("%s: selected cmd646 PIO mode%d (%dns)%s, clocks=%d/%d/%d\n",
+		drive->name, pio_mode, cycle_time,
+		d.overridden ? " (overriding vendor mode)" : "",
+		setup_count, active_count, recovery_count);
+}
+
 static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66)
 {
 	struct hd_driveid *id	= drive->id;
@@ -123,7 +354,7 @@
 
 static void config_chipset_for_pio (ide_drive_t *drive, unsigned int rev)
 {
-	/*  FIXME!! figure out some PIOing junk.... */
+	cmd64x_tuneproc(drive, 5);
 }
 
 static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
@@ -198,7 +429,7 @@
 no_dma_set:
 		config_chipset_for_pio(drive, class_rev);
 	}
-	return hwif->dmaproc(dma_func, drive);
+	return HWIF(drive)->dmaproc(dma_func, drive);
 }
 
 static int cmd64x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
@@ -277,9 +508,9 @@
 #endif
 
 	/* Setup interrupts. */
-	(void) pci_read_config_byte(dev, 0x71, &mrdmode);
+	(void) pci_read_config_byte(dev, MRDMODE, &mrdmode);
 	mrdmode &= ~(0x30);
-	(void) pci_write_config_byte(dev, 0x71, mrdmode);
+	(void) pci_write_config_byte(dev, MRDMODE, mrdmode);
 
 	/* Use MEMORY READ LINE for reads.
 	 * NOTE: Although not mentioned in the PCI0646U specs,
@@ -287,16 +518,26 @@
 	 *       back as set or not.  The PCI0646U2 specs clarify
 	 *       this point.
 	 */
-	(void) pci_write_config_byte(dev, 0x71, mrdmode | 0x02);
-
+	(void) pci_write_config_byte(dev, MRDMODE, mrdmode | 0x02);
+#if 0
 	/* Set reasonable active/recovery/address-setup values. */
-	(void) pci_write_config_byte(dev, 0x53, 0x40);
-	(void) pci_write_config_byte(dev, 0x54, 0x3f);
-	(void) pci_write_config_byte(dev, 0x55, 0x40);
-	(void) pci_write_config_byte(dev, 0x56, 0x3f);
-	(void) pci_write_config_byte(dev, 0x57, 0x5c);
-	(void) pci_write_config_byte(dev, 0x58, 0x3f);
-	(void) pci_write_config_byte(dev, 0x5b, 0x3f);
+	(void) pci_write_config_byte(dev, ARTTIM0,  0x40);
+	(void) pci_write_config_byte(dev, DRWTIM0,  0x3f);
+	(void) pci_write_config_byte(dev, ARTTIM1,  0x40);
+	(void) pci_write_config_byte(dev, DRWTIM1,  0x3f);
+	(void) pci_write_config_byte(dev, ARTTIM23, 0x5c);
+	(void) pci_write_config_byte(dev, DRWTIM23, 0x3f);
+	(void) pci_write_config_byte(dev, DRWTIM3,  0x3f);
+#else
+	(void) pci_write_config_byte(dev, ARTTIM23, 0x1c);
+#endif
+
+#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
+	cmd64x_proc = 1;
+	bmide_dev = dev;
+	cmd64x_display_info = &cmd64x_get_info;
+#endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_PROC_FS */
+
 	return 0;
 }
 
@@ -317,8 +558,13 @@
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;
 
-	if (!hwif->dma_base)
+	hwif->tuneproc = &cmd64x_tuneproc;
+
+	if (!hwif->dma_base) {
+		hwif->drives[0].autotune = 1;
+		hwif->drives[1].autotune = 1;
 		return;
+	}
 
 	switch(dev->device) {
 		case PCI_DEVICE_ID_CMD_643:
diff -u --recursive --new-file v2.3.47/linux/drivers/block/cs5530.c linux/drivers/block/cs5530.c
--- v2.3.47/linux/drivers/block/cs5530.c	Sun Feb 13 19:29:03 2000
+++ linux/drivers/block/cs5530.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/block/cs5530.c		Version 0.5	Feb 13, 2000
+ * linux/drivers/block/cs5530.c			Version 0.5	Feb 13, 2000
  *
  * Copyright (C) 2000			Mark Lord <mlord@pobox.com>
  * May be copied or modified under the terms of the GNU General Public License
@@ -24,130 +24,63 @@
 #include <asm/irq.h>
 #include "ide_modes.h"
 
-/*
- * Return the mode name for a drive transfer mode value:
- */
-static const char *strmode (byte mode)
+#define DISPLAY_CS5530_TIMINGS
+
+#if defined(DISPLAY_CS5530_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static int cs5530_get_info(char *, char **, off_t, int);
+extern int (*cs5530_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+extern char *ide_media_verbose(ide_drive_t *);
+static struct pci_dev *bmide_dev;
+
+static int cs5530_get_info (char *buffer, char **addr, off_t offset, int count)
 {
-	switch (mode) {
-		case XFER_UDMA_4:	return("UDMA4");
-		case XFER_UDMA_3:	return("UDMA3");
-		case XFER_UDMA_2:	return("UDMA2");
-		case XFER_UDMA_1:	return("UDMA1");
-		case XFER_UDMA_0:	return("UDMA0");
-		case XFER_MW_DMA_2:	return("MDMA2");
-		case XFER_MW_DMA_1:	return("MDMA1");
-		case XFER_MW_DMA_0:	return("MDMA0");
-		case XFER_SW_DMA_2:	return("SDMA2");
-		case XFER_SW_DMA_1:	return("SDMA1");
-		case XFER_SW_DMA_0:	return("SDMA0");
-		case XFER_PIO_4:	return("PIO4");
-		case XFER_PIO_3:	return("PIO3");
-		case XFER_PIO_2:	return("PIO2");
-		case XFER_PIO_1:	return("PIO1");
-		case XFER_PIO_0:	return("PIO0");
-		default:		return("???");
-	}
+	char *p = buffer;
+	u32 bibma = bmide_dev->resource[4].start;
+	u8  c0 = 0, c1 = 0;
+
+	/*
+	 * at that point bibma+0x2 et bibma+0xa are byte registers
+	 * to investigate:
+	 */
+
+	c0 = inb_p((unsigned short)bibma + 0x02);
+	c1 = inb_p((unsigned short)bibma + 0x0a);
+
+	p += sprintf(p, "\n                                Cyrix 5530 Chipset.\n");
+	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+	p += sprintf(p, "                %sabled                         %sabled\n",
+			(c0&0x80) ? "dis" : " en",
+			(c1&0x80) ? "dis" : " en");
+	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
+	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
+			(c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
+			(c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
+
+	p += sprintf(p, "UDMA\n");
+	p += sprintf(p, "DMA\n");
+	p += sprintf(p, "PIO\n");
+
+	return p-buffer;
 }
+#endif /* DISPLAY_CS5530_TIMINGS && CONFIG_PROC_FS */
+
+byte cs5530_proc = 0;
+
+extern char *ide_xfer_verbose (byte xfer_rate);
 
 /*
  * Set a new transfer mode at the drive
  */
 int cs5530_set_xfer_mode (ide_drive_t *drive, byte mode)
 {
-	int		i, error = 1;
-	byte		stat;
-	ide_hwif_t	*hwif = HWIF(drive);
+	int error = 0;
 
-	printk("%s: cs5530_set_xfer_mode(%s)\n", drive->name, strmode(mode));
-	/*
-	 * If this is a DMA mode setting, then turn off all DMA bits.
-	 * We will set one of them back on afterwards, if all goes well.
-	 *
-	 * Not sure why this is needed (it looks very silly),
-	 * but other IDE chipset drivers also do this fiddling.  ???? -ml
- 	 */
-	switch (mode) {
-		case XFER_UDMA_4:
-		case XFER_UDMA_3:
-		case XFER_UDMA_2:
-		case XFER_UDMA_1:
-		case XFER_UDMA_0:
-		case XFER_MW_DMA_2:
-		case XFER_MW_DMA_1:
-		case XFER_MW_DMA_0:
-		case XFER_SW_DMA_2:
-		case XFER_SW_DMA_1:
-		case XFER_SW_DMA_0:
-			drive->id->dma_ultra &= ~0xFF00;
-			drive->id->dma_mword &= ~0x0F00;
-			drive->id->dma_1word &= ~0x0F00;
-	}
+	printk("%s: cs5530_set_xfer_mode(%s)\n", drive->name, ide_xfer_verbose(mode));
+	error = ide_config_drive_speed(drive, mode);
 
-	/*
-	 * Select the drive, and issue the SETFEATURES command
-	 */
-	disable_irq(hwif->irq);
-	udelay(1);
-	SELECT_DRIVE(HWIF(drive), drive);
-	udelay(1);
-	if (IDE_CONTROL_REG)
-		OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
-	OUT_BYTE(mode, IDE_NSECTOR_REG);
-	OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
-	OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
-	udelay(1);	/* spec allows drive 400ns to assert "BUSY" */
-
-	/*
-	 * Wait for drive to become non-BUSY
-	 */
-	if ((stat = GET_STAT()) & BUSY_STAT) {
-		unsigned long flags, timeout;
-		__save_flags(flags);	/* local CPU only */
-		ide__sti();		/* local CPU only -- for jiffies */
-		timeout = jiffies + WAIT_CMD;
-		while ((stat = GET_STAT()) & BUSY_STAT) {
-			if (0 < (signed long)(jiffies - timeout))
-				break;
-		}
-		__restore_flags(flags); /* local CPU only */
-	}
-
-	/*
-	 * Allow status to settle, then read it again.
-	 * A few rare drives vastly violate the 400ns spec here,
-	 * so we'll wait up to 10usec for a "good" status
-	 * rather than expensively fail things immediately.
-	 */
-	for (i = 0; i < 10; i++) {
-		udelay(1);
-		if (OK_STAT((stat = GET_STAT()), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) {
-			error = 0;
-			break;
-		}
-	}
-	enable_irq(hwif->irq);
-
-	/*
-	 * Turn dma bit on if all is okay
-	 */
-	if (error) {
-		(void) ide_dump_status(drive, "cs5530_set_xfer_mode", stat);
-	} else {
-		switch (mode) {
-			case XFER_UDMA_4:   drive->id->dma_ultra |= 0x1010; break;
-			case XFER_UDMA_3:   drive->id->dma_ultra |= 0x0808; break;
-			case XFER_UDMA_2:   drive->id->dma_ultra |= 0x0404; break;
-			case XFER_UDMA_1:   drive->id->dma_ultra |= 0x0202; break;
-			case XFER_UDMA_0:   drive->id->dma_ultra |= 0x0101; break;
-			case XFER_MW_DMA_2: drive->id->dma_mword |= 0x0404; break;
-			case XFER_MW_DMA_1: drive->id->dma_mword |= 0x0202; break;
-			case XFER_MW_DMA_0: drive->id->dma_mword |= 0x0101; break;
-			case XFER_SW_DMA_2: drive->id->dma_1word |= 0x0404; break;
-			case XFER_SW_DMA_1: drive->id->dma_1word |= 0x0202; break;
-			case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break;
-		}
-	}
 	return error;
 }
 
@@ -302,8 +235,10 @@
 		case ide_dma_check:
 			return cs5530_config_dma(drive);
 		default:
-			return ide_dmaproc(func, drive);
+			break;
 	}
+	/* Other cases are done by generic IDE-DMA code. */
+	return ide_dmaproc(func, drive);
 }
 
 /*
@@ -384,6 +319,13 @@
 	pci_write_config_byte(master_0, 0x43, 0xc1);
 
 	restore_flags(flags);
+
+#if defined(DISPLAY_CS5530_TIMINGS) && defined(CONFIG_PROC_FS)
+	cs5530_proc = 1;
+	bmide_dev = dev;
+	cs5530_display_info = &cs5530_get_info;
+#endif /* DISPLAY_CS5530_TIMINGS && CONFIG_PROC_FS */
+
 	return 0;
 }
 
diff -u --recursive --new-file v2.3.47/linux/drivers/block/cy82c693.c linux/drivers/block/cy82c693.c
--- v2.3.47/linux/drivers/block/cy82c693.c	Fri Jan 21 18:19:16 2000
+++ linux/drivers/block/cy82c693.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/block/cy82c693.c	Version 0.34	Dec. 13, 1999
+ * linux/drivers/block/cy82c693.c		Version 0.34	Dec. 13, 1999
  *
  *  Copyright (C) 1998-99 Andreas S. Krebs (akrebs@altavista.net), Maintainer
  *  Copyright (C) 1998-99 Andre Hedrick, Integrater
@@ -54,7 +54,7 @@
 #include "ide_modes.h"
 
 /* the current version */
-#define CY82_VERSION	"CY82C693U driver v0.34 99-09-03 Andreas S. Krebs (akrebs@altavista.net)"
+#define CY82_VERSION	"CY82C693U driver v0.34 99-13-12 Andreas S. Krebs (akrebs@altavista.net)"
 
 /*
  *	The following are used to debug the driver.
@@ -439,4 +439,3 @@
 		hwif->drives[1].autotune = 1;
 	}
 }
-
diff -u --recursive --new-file v2.3.47/linux/drivers/block/dtc2278.c linux/drivers/block/dtc2278.c
--- v2.3.47/linux/drivers/block/dtc2278.c	Thu May 13 11:04:54 1999
+++ linux/drivers/block/dtc2278.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/dtc2278.c       Version 0.02  Feb 10, 1996
+ *  linux/drivers/block/dtc2278.c		Version 0.02	Feb 10, 1996
  *
  *  Copyright (C) 1996  Linus Torvalds & author (see below)
  */
@@ -95,7 +95,7 @@
 	HWIF(drive)->drives[!drive->select.b.unit].io_32bit = 1;
 }
 
-void init_dtc2278 (void)
+void __init init_dtc2278 (void)
 {
 	unsigned long flags;
 
diff -u --recursive --new-file v2.3.47/linux/drivers/block/falconide.c linux/drivers/block/falconide.c
--- v2.3.47/linux/drivers/block/falconide.c	Thu May 13 11:04:54 1999
+++ linux/drivers/block/falconide.c	Sat Feb 26 20:32:13 2000
@@ -40,7 +40,7 @@
 #define ATA_HD_STATUS	0x1d		/* see status-bits */
 #define ATA_HD_CONTROL	0x39
 
-static int falconide_offsets[IDE_NR_PORTS] = {
+static int __init falconide_offsets[IDE_NR_PORTS] = {
     ATA_HD_DATA, ATA_HD_ERROR, ATA_HD_NSECTOR, ATA_HD_SECTOR, ATA_HD_LCYL,
     ATA_HD_HCYL, ATA_HD_SELECT, ATA_HD_STATUS, ATA_HD_CONTROL, -1
 };
@@ -50,7 +50,7 @@
      *  Probe for a Falcon IDE interface
      */
 
-void falconide_init(void)
+void __init falconide_init(void)
 {
     if (MACH_IS_ATARI && ATARIHW_PRESENT(IDE)) {
 	hw_regs_t hw;
diff -u --recursive --new-file v2.3.47/linux/drivers/block/gayle.c linux/drivers/block/gayle.c
--- v2.3.47/linux/drivers/block/gayle.c	Thu May 13 11:04:54 1999
+++ linux/drivers/block/gayle.c	Sat Feb 26 20:32:13 2000
@@ -41,7 +41,7 @@
 #define GAYLE_STATUS	0x1e		/* see status-bits */
 #define GAYLE_CONTROL	0x101a
 
-static int gayle_offsets[IDE_NR_PORTS] = {
+static int __init gayle_offsets[IDE_NR_PORTS] = {
     GAYLE_DATA, GAYLE_ERROR, GAYLE_NSECTOR, GAYLE_SECTOR, GAYLE_LCYL,
     GAYLE_HCYL, GAYLE_SELECT, GAYLE_STATUS, -1, -1
 };
@@ -105,7 +105,7 @@
      *  Probe for a Gayle IDE interface (and optionally for an IDE doubler)
      */
 
-void gayle_init(void)
+void __init gayle_init(void)
 {
     int a4000, i;
 
diff -u --recursive --new-file v2.3.47/linux/drivers/block/hpt34x.c linux/drivers/block/hpt34x.c
--- v2.3.47/linux/drivers/block/hpt34x.c	Fri Jan 28 15:09:07 2000
+++ linux/drivers/block/hpt34x.c	Sat Feb 26 20:32:13 2000
@@ -1,7 +1,7 @@
 /*
- * linux/drivers/block/hpt34x.c		Version 0.28	Dec. 13, 1999
+ * linux/drivers/block/hpt34x.c		Version 0.29	Feb. 10, 2000
  *
- * Copyright (C) 1998-99	Andre Hedrick (andre@suse.com)
+ * Copyright (C) 1998-2000	Andre Hedrick (andre@suse.com)
  * May be copied or modified under the terms of the GNU General Public License
  *
  *
@@ -16,6 +16,12 @@
  * hdg: DMA 1  (0x0012 0x0052) (0x0030 0x0070)
  * hdh: DMA 1  (0x0052 0x0252) (0x0070 0x00f0)
  *
+ * ide-pci.c reference
+ *
+ * Since there are two cards that report almost identically,
+ * the only discernable difference is the values reported in pcicmd.
+ * Booting-BIOS card or HPT363 :: pcicmd == 0x07
+ * Non-bootable card or HPT343 :: pcicmd == 0x05
  */
 
 #include <linux/config.h>
@@ -27,7 +33,6 @@
 #include <linux/ioport.h>
 #include <linux/blkdev.h>
 #include <linux/hdreg.h>
-
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -35,16 +40,56 @@
 
 #include <asm/io.h>
 #include <asm/irq.h>
-
 #include "ide_modes.h"
 
 #ifndef SPLIT_BYTE
 #define SPLIT_BYTE(B,H,L)	((H)=(B>>4), (L)=(B-((B>>4)<<4)))
 #endif
 
-#define HPT343_DEBUG_DRIVE_INFO		0
-#define HPT343_DISABLE_ALL_DMAING	0
-#define HPT343_DMA_DISK_ONLY		0
+#define HPT343_DEBUG_DRIVE_INFO		1
+
+#define DISPLAY_HPT34X_TIMINGS
+#if defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static int hpt34x_get_info(char *, char **, off_t, int);
+extern int (*hpt34x_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+extern char *ide_media_verbose(ide_drive_t *);
+static struct pci_dev *bmide_dev;
+
+static int hpt34x_get_info (char *buffer, char **addr, off_t offset, int count)
+{
+	char *p = buffer;
+	u32 bibma = bmide_dev->resource[4].start;
+	u8  c0 = 0, c1 = 0;
+
+        /*
+         * at that point bibma+0x2 et bibma+0xa are byte registers
+         * to investigate:
+         */
+	c0 = inb_p((unsigned short)bibma + 0x02);
+	c1 = inb_p((unsigned short)bibma + 0x0a);
+
+	p += sprintf(p, "\n                                HPT34X Chipset.\n");
+	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+	p += sprintf(p, "                %sabled                         %sabled\n",
+			(c0&0x80) ? "dis" : " en",
+			(c1&0x80) ? "dis" : " en");
+	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
+	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
+			(c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
+			(c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
+
+	p += sprintf(p, "UDMA\n");
+	p += sprintf(p, "DMA\n");
+	p += sprintf(p, "PIO\n");
+
+	return p-buffer;	/* => must be less than 4k! */
+}
+#endif  /* defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+byte hpt34x_proc = 0;
 
 extern char *ide_xfer_verbose (byte xfer_rate);
 
@@ -109,12 +154,8 @@
 	struct hd_driveid *id	= drive->id;
 	byte speed		= 0x00;
 
-#if HPT343_DISABLE_ALL_DMAING
-	return ((int) ide_dma_off);
-#elif HPT343_DMA_DISK_ONLY
 	if (drive->media != ide_disk)
 		return ((int) ide_dma_off_quietly);
-#endif /* HPT343_DISABLE_ALL_DMAING */
 
 	hpt34x_clear_chipset(drive);
 
@@ -249,14 +290,13 @@
 fast_ata_pio:
 		dma_func = ide_dma_off_quietly;
 no_dma_set:
-
 		config_chipset_for_pio(drive);
 	}
 
-#if 0
+#ifndef CONFIG_HPT34X_AUTODMA
 	if (dma_func == ide_dma_on)
 		dma_func = ide_dma_off;
-#endif
+#endif /* CONFIG_HPT34X_AUTODMA */
 
 	return HWIF(drive)->dmaproc(dma_func, drive);
 }
@@ -273,18 +313,10 @@
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	unsigned long dma_base = hwif->dma_base;
-	byte unit = (drive->select.b.unit & 0x01);
 	unsigned int count, reading = 0;
 	byte dma_stat;
 
 	switch (func) {
-		case ide_dma_off:
-		case ide_dma_off_quietly:
-			outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
-			break;
-		case ide_dma_on:
-			outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
-			break;
 		case ide_dma_check:
 			return config_drive_xfer_rate(drive);
 		case ide_dma_read:
@@ -357,11 +389,16 @@
 	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, dev->resource[1].start);
 	pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, dev->resource[2].start);
 	pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, dev->resource[3].start);
-
 	pci_write_config_word(dev, PCI_COMMAND, cmd);
 
 	__restore_flags(flags);	/* local CPU only */
 
+#if defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS)
+	hpt34x_proc = 1;
+	bmide_dev = dev;
+	hpt34x_display_info = &hpt34x_get_info;
+#endif /* DISPLAY_HPT34X_TIMINGS && CONFIG_PROC_FS */
+
 	return dev->irq;
 }
 
@@ -372,11 +409,7 @@
 		unsigned short pcicmd = 0;
 
 		pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd);
-#ifdef CONFIG_BLK_DEV_HPT34X_DMA
-#if 0
 		hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0;
-#endif
-#endif /* CONFIG_BLK_DEV_HPT34X_DMA */
 		hwif->dmaproc = &hpt34x_dmaproc;
 	} else {
 		hwif->drives[0].autotune = 1;
diff -u --recursive --new-file v2.3.47/linux/drivers/block/hpt366.c linux/drivers/block/hpt366.c
--- v2.3.47/linux/drivers/block/hpt366.c	Thu Feb 10 17:11:06 2000
+++ linux/drivers/block/hpt366.c	Sat Feb 26 20:32:13 2000
@@ -1,7 +1,7 @@
 /*
- * linux/drivers/block/hpt366.c		Version 0.15	Dec. 22, 1999
+ * linux/drivers/block/hpt366.c		Version 0.16	Feb. 10, 2000
  *
- * Copyright (C) 1999			Andre Hedrick <andre@suse.com>
+ * Copyright (C) 1999-2000		Andre Hedrick <andre@suse.com>
  * May be copied or modified under the terms of the GNU General Public License
  *
  * Thanks to HighPoint Technologies for their assistance, and hardware.
@@ -30,6 +30,13 @@
 
 #include "ide_modes.h"
 
+#define DISPLAY_HPT366_TIMINGS
+
+#if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+#endif  /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */
+
 const char *bad_ata66_4[] = {
 	"WDC AC310200R",
 	NULL
@@ -120,6 +127,48 @@
 #define HPT366_ALLOW_ATA66_4		1
 #define HPT366_ALLOW_ATA66_3		1
 
+#if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
+static int hpt366_get_info(char *, char **, off_t, int);
+extern int (*hpt366_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+extern char *ide_media_verbose(ide_drive_t *);
+static struct pci_dev *bmide_dev;
+static struct pci_dev *bmide2_dev;
+
+static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count)
+{
+	char *p		= buffer;
+	u32 bibma	= bmide_dev->resource[4].start;
+	u32 bibma2 	= bmide2_dev->resource[4].start;
+	u8  c0 = 0, c1 = 0;
+
+        /*
+         * at that point bibma+0x2 et bibma+0xa are byte registers
+         * to investigate:
+         */
+	c0 = inb_p((unsigned short)bibma + 0x02);
+	if (bmide2_dev)
+		c1 = inb_p((unsigned short)bibma2 + 0x02);
+
+	p += sprintf(p, "\n                                HPT366 Chipset.\n");
+	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+	p += sprintf(p, "                %sabled                         %sabled\n",
+			(c0&0x80) ? "dis" : " en",
+			(c1&0x80) ? "dis" : " en");
+	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
+	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
+			(c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
+			(c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
+
+	p += sprintf(p, "UDMA\n");
+	p += sprintf(p, "DMA\n");
+	p += sprintf(p, "PIO\n");
+
+	return p-buffer;/* => must be less than 4k! */
+}
+#endif  /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+byte hpt366_proc = 0;
+
 extern char *ide_xfer_verbose (byte xfer_rate);
 byte hpt363_shared_irq = 0;
 byte hpt363_shared_pin = 0;
@@ -263,20 +312,20 @@
 
 	pci_read_config_byte(HWIF(drive)->pci_dev, 0x51, &reg51h);
 
-#ifdef CONFIG_HPT366_FAST_IRQ_PREDICTION
+#ifdef CONFIG_HPT366_FIP
 	/*
 	 * Some drives prefer/allow for the method of handling interrupts.
 	 */
 	if (!(reg51h & 0x80))
 		pci_write_config_byte(HWIF(drive)->pci_dev, 0x51, reg51h|0x80);
-#else /* ! CONFIG_HPT366_FAST_IRQ_PREDICTION */
+#else /* ! CONFIG_HPT366_FIP */
 	/*
 	 * Disable the "fast interrupt" prediction.
 	 * Instead, always wait for the real interrupt from the drive!
 	 */
 	if (reg51h & 0x80)
 		pci_write_config_byte(HWIF(drive)->pci_dev, 0x51, reg51h & ~0x80);
-#endif /* CONFIG_HPT366_FAST_IRQ_PREDICTION */
+#endif /* CONFIG_HPT366_FIP */
 
 	/*
 	 * Preserve existing PIO settings:
@@ -420,7 +469,6 @@
  * This is specific to the HPT366 UDMA bios chipset
  * by HighPoint|Triones Technologies, Inc.
  */
-
 int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
 {
 	byte reg50h = 0;
@@ -434,7 +482,6 @@
 			pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, &reg50h);
 			/* ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); */
 		case ide_dma_timeout:
-			break;
 		default:
 			break;
 	}
@@ -464,6 +511,17 @@
 	if (test != 0x08)
 		pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
 
+#if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
+	if (!hpt366_proc) {
+		hpt366_proc = 1;
+		bmide_dev = dev;
+		hpt366_display_info = &hpt366_get_info;
+	}
+	if ((hpt366_proc) && ((dev->devfn - bmide_dev->devfn) == 1)) {
+		bmide2_dev = dev;
+	}
+#endif /* DISPLAY_HPT366_TIMINGS && CONFIG_PROC_FS */
+
 	return dev->irq;
 }
 
@@ -482,18 +540,6 @@
 
 void __init ide_init_hpt366 (ide_hwif_t *hwif)
 {
-#if 0
-	if ((PCI_FUNC(hwif->pci_dev->devfn) & 1) && (hpt363_shared_irq)) {
-		hwif->mate = &ide_hwifs[hwif->index-1];
-		hwif->mate->mate = hwif;
-		hwif->serialized = hwif->mate->serialized = 1;
-	}
-
-	if ((PCI_FUNC(hwif->pci_dev->devfn) & 1) && (hpt363_shared_pin)) {
-
-	}
-#endif
-
 	hwif->tuneproc = &hpt366_tune_drive;
 	if (hwif->dma_base) {
 		hwif->dmaproc = &hpt366_dmaproc;
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ht6560b.c linux/drivers/block/ht6560b.c
--- v2.3.47/linux/drivers/block/ht6560b.c	Thu May 13 11:04:54 1999
+++ linux/drivers/block/ht6560b.c	Sat Feb 26 20:32:13 2000
@@ -1,7 +1,7 @@
 /*
- *  linux/drivers/block/ht6580.c       Version 0.04  Mar 19, 1996
+ *  linux/drivers/block/ht6560b.c		Version 0.07	Feb  1, 2000
  *
- *  Copyright (C) 1995-1996  Linus Torvalds & author (see below)
+ *  Copyright (C) 1995-2000  Linus Torvalds & author (see below)
  */
 
 /*
@@ -12,42 +12,31 @@
  *
  *  Version 0.03        Some cleanups
  *
- * I reviewed some assembler source listings of htide drivers and found
- * out how they setup those cycle time interfacing values, as they at Holtek
- * call them. IDESETUP.COM that is supplied with the drivers figures out
- * optimal values and fetches those values to drivers. I found out that
- * they use IDE_SELECT_REG to fetch timings to the ide board right after
- * interface switching. After that it was quite easy to add code to
- * ht6560b.c.
+ *  Version 0.05        PIO mode cycle timings auto-tune using bus-speed
  *
- * IDESETUP.COM gave me values 0x24, 0x45, 0xaa, 0xff that worked fine
- * for hda and hdc. But hdb needed higher values to work, so I guess
- * that sometimes it is necessary to give higher value than IDESETUP
- * gives.   [see cmd640.c for an extreme example of this. -ml]
+ *  Version 0.06        Prefetch mode now defaults no OFF. To set
+ *                      prefetch mode OFF/ON use "hdparm -p8/-p9".
+ *                      Unmask irq is disabled when prefetch mode
+ *                      is enabled.
  *
- * Perhaps I should explain something about these timing values:
- * The higher nibble of value is the Recovery Time  (rt) and the lower nibble
- * of the value is the Active Time  (at). Minimum value 2 is the fastest and
- * the maximum value 15 is the slowest. Default values should be 15 for both.
- * So 0x24 means 2 for rt and 4 for at. Each of the drives should have
- * both values, and IDESETUP gives automatically rt=15 st=15 for CDROMs or
- * similar. If value is too small there will be all sorts of failures.
- *
- * Port 0x3e6 bit 0x20 sets these timings on/off. If 0x20 bit is set
- * these timings are disabled.
+ *  Version 0.07        Trying to fix CD-ROM detection problem.
+ *                      "Prefetch" mode bit OFF for ide disks and
+ *                      ON for anything else.
  *
- * Mikko Ala-Fossi
  *
- * More notes:
+ *  HT-6560B EIDE-controller support
+ *  To activate controller support use kernel parameter "ide0=ht6560b".
+ *  Use hdparm utility to enable PIO mode support.
  *
- * There's something still missing from the initialization code, though.
- * If I have booted to dos sometime after power on, I can get smaller
- * timing values working. Perhaps I could soft-ice the initialization.
+ *  Author:    Mikko Ala-Fossi            <maf@iki.fi>
+ *             Jan Evert van Grootheest   <janevert@iae.nl>
  *
- * -=- malafoss@snakemail.hut.fi -=- searching the marvels of universe -=-
+ *  Try:  http://www.maf.iki.fi/~maf/ht6560b/
  */
 
-#undef REALLY_SLOW_IO           /* most systems can safely undef this */
+#define HT6560B_VERSION "v0.07"
+
+#undef REALLY_SLOW_IO		/* most systems can safely undef this */
 
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -63,175 +52,291 @@
 
 #include "ide_modes.h"
 
-/*
- * This routine handles interface switching for the peculiar hardware design
- * on the F.G.I./Holtek HT-6560B VLB IDE interface.
- * The HT-6560B can only enable one IDE port at a time, and requires a
- * silly sequence (below) whenever we switch between primary and secondary.
- *
- * This stuff is courtesy of malafoss@snakemail.hut.fi
- *                          (or maf@nemesis.tky.hut.fi)
- *
- * At least one user has reported that this code can confuse the floppy
- * controller and/or driver -- perhaps this should be changed to use
- * a read-modify-write sequence, so as not to disturb other bits in the reg?
- */
+/* #define DEBUG */  /* remove comments for DEBUG messages */
 
 /*
- * The special i/o-port that HT-6560B uses to select interfaces:
+ * The special i/o-port that HT-6560B uses to configuration:
+ *    bit0 (0x01): "1" selects secondary interface
+ *    bit2 (0x04): "1" enables FIFO function
+ *    bit5 (0x20): "1" enables prefetched data read function  (???)
+ *
+ * The special i/o-port that HT-6560A uses to configuration:
+ *    bit0 (0x01): "1" selects secondary interface
+ *    bit1 (0x02): "1" enables prefetched data read function
+ *    bit2 (0x04): "0" enables multi-master system	      (?)
+ *    bit3 (0x08): "1" 3 cycle time, "0" 2 cycle time	      (?)
  */
-#define HT_SELECT_PORT     0x3e6
-
+#define HT_CONFIG_PORT	  0x3e6
+#define HT_CONFIG(drivea) (byte)(((drivea)->drive_data & 0xff00) >> 8)
 /*
- * We don't know what all of the bits are for, but we *do* know about these:
- *	bit5 (0x20): "1" selects slower speed by disabling use of timing values
- *	bit0 (0x01): "1" selects second interface
+ * FIFO + PREFETCH (both a/b-model)
  */
-static byte ht6560b_selects [2][MAX_DRIVES] = {{0x3c,0x3c}, {0x3d,0x3d}};
+#define HT_CONFIG_DEFAULT 0x1c /* no prefetch */
+/* #define HT_CONFIG_DEFAULT 0x3c */ /* with prefetch */
+#define HT_SECONDARY_IF	  0x01
+#define HT_PREFETCH_MODE  0x20
 
 /*
- * VLB ht6560b Timing values:
+ * ht6560b Timing values:
+ *
+ * I reviewed some assembler source listings of htide drivers and found
+ * out how they setup those cycle time interfacing values, as they at Holtek
+ * call them. IDESETUP.COM that is supplied with the drivers figures out
+ * optimal values and fetches those values to drivers. I found out that
+ * they use IDE_SELECT_REG to fetch timings to the ide board right after
+ * interface switching. After that it was quite easy to add code to
+ * ht6560b.c.
+ *
+ * IDESETUP.COM gave me values 0x24, 0x45, 0xaa, 0xff that worked fine
+ * for hda and hdc. But hdb needed higher values to work, so I guess
+ * that sometimes it is necessary to give higher value than IDESETUP
+ * gives.   [see cmd640.c for an extreme example of this. -ml]
+ *
+ * Perhaps I should explain something about these timing values:
+ * The higher nibble of value is the Recovery Time  (rt) and the lower nibble
+ * of the value is the Active Time  (at). Minimum value 2 is the fastest and
+ * the maximum value 15 is the slowest. Default values should be 15 for both.
+ * So 0x24 means 2 for rt and 4 for at. Each of the drives should have
+ * both values, and IDESETUP gives automatically rt=15 st=15 for CDROMs or
+ * similar. If value is too small there will be all sorts of failures.
  *
  * Timing byte consists of
- *      High nibble:  Recovery Time  (rt)
- *           The valid values range from 2 to 15. The default is 15.
+ *	High nibble:  Recovery Cycle Time  (rt)
+ *	     The valid values range from 2 to 15. The default is 15.
  *
- *      Low nibble:   Active Time    (at)
- *           The valid values range from 2 to 15. The default is 15.
+ *	Low nibble:   Active Cycle Time	   (at)
+ *	     The valid values range from 2 to 15. The default is 15.
  *
  * You can obtain optimized timing values by running Holtek IDESETUP.COM
  * for DOS. DOS drivers get their timing values from command line, where
  * the first value is the Recovery Time and the second value is the
  * Active Time for each drive. Smaller value gives higher speed.
  * In case of failures you should probably fall back to a higher value.
- *
- * Here's an example to make it clearer:
- *
- * DOS:    DEVICE=C:\bin\HTIDE\HTIDE.SYS /D0=2,4 /D1=4,5 /D2=10,10 /D3=15,15
- * Linux:  byte ht6560b_timings [][] = {{0x24, 0x45}, {0xaa, 0xff}};
- *
- * Note: There are no ioctls to change these values directly,
- * but settings can be approximated as PIO modes, using "hdparm":
- *
- * rc.local:  hdparm -p3 /dev/hda -p2 /dev/hdb -p1 /dev/hdc -p0 /dev/hdd
  */
+#define HT_TIMING(drivea) (byte)((drivea)->drive_data & 0x00ff)
+#define HT_TIMING_DEFAULT 0xff
 
-static byte ht6560b_timings [2][MAX_DRIVES] = {{0xff,0xff}, {0xff,0xff}};
-
-static byte pio_to_timings[6] = {0xff, 0xaa, 0x45, 0x24, 0x13, 0x12};
+/*
+ * This routine handles interface switching for the peculiar hardware design
+ * on the F.G.I./Holtek HT-6560B VLB IDE interface.
+ * The HT-6560B can only enable one IDE port at a time, and requires a
+ * silly sequence (below) whenever we switch between primary and secondary.
+ */
 
 /*
  * This routine is invoked from ide.c to prepare for access to a given drive.
  */
 static void ht6560b_selectproc (ide_drive_t *drive)
 {
-	byte t;
 	unsigned long flags;
 	static byte current_select = 0;
 	static byte current_timing = 0;
-	byte select = ht6560b_selects[HWIF(drive)->index][drive->select.b.unit];
-        byte timing = ht6560b_timings[HWIF(drive)->index][drive->select.b.unit];
-
+	byte select, timing;
+	
+	__save_flags (flags);	/* local CPU only */
+	__cli();		/* local CPU only */
+	
+	select = HT_CONFIG(drive);
+	timing = HT_TIMING(drive);
+	
 	if (select != current_select || timing != current_timing) {
 		current_select = select;
 		current_timing = timing;
-		__save_flags (flags);	/* local CPU only */
-		__cli();		/* local CPU only */
-		(void) inb(HT_SELECT_PORT);
-		(void) inb(HT_SELECT_PORT);
-		(void) inb(HT_SELECT_PORT);
+		if (drive->media != ide_disk || !drive->present)
+			select |= HT_PREFETCH_MODE;
+		(void) inb(HT_CONFIG_PORT);
+		(void) inb(HT_CONFIG_PORT);
+		(void) inb(HT_CONFIG_PORT);
+		(void) inb(HT_CONFIG_PORT);
+		outb(select, HT_CONFIG_PORT);
 		/*
-		 * Note: input bits are reversed to output bits!!
+		 * Set timing for this drive:
 		 */
-		t = inb(HT_SELECT_PORT) ^ 0x3f;
-		t &= (~0x21);
-		t |= (current_select & 0x21);
-		outb(t, HT_SELECT_PORT);
-                /*
-                 * Set timing for this drive:
-                 */
-                outb (timing, IDE_SELECT_REG);
-                (void) inb (IDE_STATUS_REG);
-		__restore_flags (flags);	/* local CPU only */
+		outb(timing, IDE_SELECT_REG);
+		(void) inb(IDE_STATUS_REG);
 #ifdef DEBUG
-		printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, t, timing);
+		printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, select, timing);
 #endif
 	}
+	__restore_flags (flags);	/* local CPU only */
 }
 
 /*
  * Autodetection and initialization of ht6560b
  */
-int try_to_init_ht6560b(void)
+static int __init try_to_init_ht6560b(void)
 {
 	byte orig_value;
 	int i;
-
+	
 	/* Autodetect ht6560b */
-	if ((orig_value=inb(HT_SELECT_PORT)) == 0xff)
+	if ((orig_value=inb(HT_CONFIG_PORT)) == 0xff)
 		return 0;
-
+	
 	for (i=3;i>0;i--) {
-		outb(0x00, HT_SELECT_PORT);
-		if (!( (~inb(HT_SELECT_PORT)) & 0x3f )) {
-			  outb(orig_value, HT_SELECT_PORT);
-			  return 0;
+		outb(0x00, HT_CONFIG_PORT);
+		if (!( (~inb(HT_CONFIG_PORT)) & 0x3f )) {
+			outb(orig_value, HT_CONFIG_PORT);
+			return 0;
 		}
 	}
-	outb(0x00, HT_SELECT_PORT);
-	if ((~inb(HT_SELECT_PORT))& 0x3f) {
-		outb(orig_value, HT_SELECT_PORT);
+	outb(0x00, HT_CONFIG_PORT);
+	if ((~inb(HT_CONFIG_PORT))& 0x3f) {
+		outb(orig_value, HT_CONFIG_PORT);
 		return 0;
 	}
 	/*
-	 * Ht6560b autodetected:
-	 *     reverse input bits to output bits
-	 *     initialize bit1 to 0
+	 * Ht6560b autodetected
 	 */
-	outb((orig_value ^ 0x3f) & 0xfd, HT_SELECT_PORT);
-
-	printk("\nht6560b: detected and initialized");
+	outb(HT_CONFIG_DEFAULT, HT_CONFIG_PORT);
+	outb(HT_TIMING_DEFAULT, 0x1f6);  /* IDE_SELECT_REG */
+	(void) inb(0x1f7);               /* IDE_STATUS_REG */
+	
+	printk("\nht6560b " HT6560B_VERSION
+	       ": chipset detected and initialized"
+#ifdef DEBUG
+	       " with debug enabled"
+#endif
+		);
 	return 1;
 }
 
-static void tune_ht6560b (ide_drive_t *drive, byte pio)
+static byte ht_pio2timings(ide_drive_t *drive, byte pio)
 {
-	unsigned int hwif, unit;
+	int bus_speed, active_time, recovery_time;
+	int active_cycles, recovery_cycles;
+	ide_pio_data_t d;
+	
+        if (pio) {
+		pio = ide_get_best_pio_mode(drive, pio, 5, &d);
+		
+		/*
+		 *  Just like opti621.c we try to calculate the
+		 *  actual cycle time for recovery and activity
+		 *  according system bus speed.
+		 */
+		bus_speed = ide_system_bus_speed();
+		active_time = ide_pio_timings[pio].active_time;
+		recovery_time = d.cycle_time 
+			- active_time
+			- ide_pio_timings[pio].setup_time;
+		/*
+		 *  Cycle times should be Vesa bus cycles
+		 */
+		active_cycles   = (active_time   * bus_speed + 999) / 1000;
+		recovery_cycles = (recovery_time * bus_speed + 999) / 1000;
+		/*
+		 *  Upper and lower limits
+		 */
+		if (active_cycles   < 2)  active_cycles   = 2;
+		if (recovery_cycles < 2)  recovery_cycles = 2;
+		if (active_cycles   > 15) active_cycles   = 15;
+		if (recovery_cycles > 15) recovery_cycles = 0;  /* 0==16 */
+		
+#ifdef DEBUG
+		printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n", drive->name, pio, recovery_cycles, recovery_time, active_cycles, active_time);
+#endif
+		
+		return (byte)((recovery_cycles << 4) | active_cycles);
+	} else {
+		
+#ifdef DEBUG
+		printk("ht6560b: drive %s setting pio=0\n", drive->name);
+#endif
+		
+		return HT_TIMING_DEFAULT;    /* default setting */
+	}
+}
+
+/*
+ *  Enable/Disable so called prefetch mode
+ */
+static void ht_set_prefetch(ide_drive_t *drive, byte state)
+{
+	unsigned long flags;
+	int t = HT_PREFETCH_MODE << 8;
+	
+	save_flags (flags);	/* all CPUs */
+	cli();		        /* all CPUs */
+	
+	/*
+	 *  Prefetch mode and unmask irq seems to conflict
+	 */
+	if (state) {
+		drive->drive_data |= t;   /* enable prefetch mode */
+		drive->no_unmask = 1;
+		drive->unmask = 0;
+	} else {
+		drive->drive_data &= ~t;  /* disable prefetch mode */
+		drive->no_unmask = 0;
+	}
+	
+	restore_flags (flags);	/* all CPUs */
+	
+#ifdef DEBUG
+	printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis"));
+#endif
+}
 
-	if (pio == 255)  {	/* auto-tune */
-		if (drive->media != ide_disk)
-			pio = 0; /* some CDROMs don't like fast modes (?) */
-		else
-			pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
-	}
-	unit = drive->select.b.unit;
-	hwif = HWIF(drive)->index;
-	ht6560b_timings[hwif][unit] = pio_to_timings[pio];
-	if (pio == 0)
-		ht6560b_selects[hwif][unit] |= 0x20;
-	else
-		ht6560b_selects[hwif][unit] &= ~0x20;
+static void tune_ht6560b (ide_drive_t *drive, byte pio)
+{
+	unsigned long flags;
+	byte timing;
+	
+	switch (pio) {
+	case 8:         /* set prefetch off */
+	case 9:         /* set prefetch on */
+		ht_set_prefetch(drive, pio & 1);
+		return;
+	}
+	
+	timing = ht_pio2timings(drive, pio);
+	
+	save_flags (flags);	/* all CPUs */
+	cli();		        /* all CPUs */
+	
+	drive->drive_data &= 0xff00;
+	drive->drive_data |= timing;
+	
+	restore_flags (flags);	/* all CPUs */
+	
+#ifdef DEBUG
+	printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing);
+#endif
 }
 
-void init_ht6560b (void)
+void __init init_ht6560b (void)
 {
-	if (check_region(HT_SELECT_PORT,1)) {
-		printk("\nht6560b: PORT 0x3e6 ALREADY IN USE\n");
+	int t;
+	
+	if (check_region(HT_CONFIG_PORT,1)) {
+		printk(KERN_ERR "ht6560b: PORT %#x ALREADY IN USE\n", HT_CONFIG_PORT);
 	} else {
 		if (try_to_init_ht6560b()) {
-			request_region(HT_SELECT_PORT, 1, ide_hwifs[0].name);
+			request_region(HT_CONFIG_PORT, 1, ide_hwifs[0].name);
 			ide_hwifs[0].chipset = ide_ht6560b;
 			ide_hwifs[1].chipset = ide_ht6560b;
 			ide_hwifs[0].selectproc = &ht6560b_selectproc;
 			ide_hwifs[1].selectproc = &ht6560b_selectproc;
 			ide_hwifs[0].tuneproc = &tune_ht6560b;
 			ide_hwifs[1].tuneproc = &tune_ht6560b;
-			ide_hwifs[0].serialized = 1;
-			ide_hwifs[1].serialized = 1;
+			ide_hwifs[0].serialized = 1;  /* is this needed? */
+			ide_hwifs[1].serialized = 1;  /* is this needed? */
 			ide_hwifs[0].mate = &ide_hwifs[1];
 			ide_hwifs[1].mate = &ide_hwifs[0];
 			ide_hwifs[1].channel = 1;
+			
+			/*
+			 * Setting default configurations for drives
+			 */
+			t = (HT_CONFIG_DEFAULT << 8);
+			t |= HT_TIMING_DEFAULT;
+			ide_hwifs[0].drives[0].drive_data = t;
+			ide_hwifs[0].drives[1].drive_data = t;
+			t |= (HT_SECONDARY_IF << 8);
+			ide_hwifs[1].drives[0].drive_data = t;
+			ide_hwifs[1].drives[1].drive_data = t;
 		} else
-			printk("\nht6560b: not found\n");
+			printk(KERN_ERR "ht6560b: not found\n");
 	}
 }
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ide-cd.h linux/drivers/block/ide-cd.h
--- v2.3.47/linux/drivers/block/ide-cd.h	Tue Dec 14 01:27:23 1999
+++ linux/drivers/block/ide-cd.h	Sat Feb 26 20:51:25 2000
@@ -1,11 +1,11 @@
-#ifndef _IDE_CD_H
-#define _IDE_CD_H
 /*
  *  linux/drivers/block/ide_cd.h
  *
- *  Copyright (C) 1996, 1997, 1998  Erik Andersen
- *  Copyright (C) 1998, 1999 Jens Axboe
+ *  Copyright (C) 1996-98  Erik Andersen
+ *  Copyright (C) 1998-2000 Jens Axboe
  */
+#ifndef _IDE_CD_H
+#define _IDE_CD_H
 
 #include <linux/cdrom.h>
 #include <asm/byteorder.h>
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ide-disk.c linux/drivers/block/ide-disk.c
--- v2.3.47/linux/drivers/block/ide-disk.c	Wed Feb 16 17:03:51 2000
+++ linux/drivers/block/ide-disk.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ide-disk.c	Version 1.09  April 23, 1999
+ *  linux/drivers/block/ide-disk.c	Version 1.09	April 23, 1999
  *
  *  Copyright (C) 1994-1998  Linus Torvalds & authors (see below)
  */
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ide-dma.c linux/drivers/block/ide-dma.c
--- v2.3.47/linux/drivers/block/ide-dma.c	Sun Feb 20 21:12:38 2000
+++ linux/drivers/block/ide-dma.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ide-dma.c	Version 4.09	April 23, 1999
+ *  linux/drivers/block/ide-dma.c		Version 4.09	April 23, 1999
  *
  *  Copyright (c) 1999  Andre Hedrick
  *  May be copied or modified under the terms of the GNU General Public License
@@ -91,6 +91,8 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
+extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc);
+
 #ifdef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS
 
 struct drive_list_entry {
@@ -401,6 +403,7 @@
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	unsigned long dma_base = hwif->dma_base;
+	byte unit = (drive->select.b.unit & 0x01);
 	unsigned int count, reading = 0;
 	byte dma_stat;
 
@@ -408,8 +411,11 @@
 		case ide_dma_off:
 			printk("%s: DMA disabled\n", drive->name);
 		case ide_dma_off_quietly:
+			outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
 		case ide_dma_on:
 			drive->using_dma = (func == ide_dma_on);
+			if (drive->using_dma)
+				outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
 			return 0;
 		case ide_dma_check:
 			return config_drive_for_dma (drive);
@@ -424,7 +430,7 @@
 			drive->waiting_for_dma = 1;
 			if (drive->media != ide_disk)
 				return 0;
-			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);/* issue cmd to drive */
+			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);	/* issue cmd to drive */
 			OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 		case ide_dma_begin:
 			/* Note that this is done *after* the cmd has
@@ -449,12 +455,10 @@
 			return check_drive_lists(drive, (func == ide_dma_good_drive));
 		case ide_dma_lostirq:
 		case ide_dma_timeout:
-			/*
-			 * printk("ide_dmaproc: chipset supported func only: %d\n", func);
-			 */
+			printk("ide_dmaproc: chipset supported %s func only: %d\n", ide_dmafunc_verbose(func),  func);
 			return 1;
 		default:
-			printk("ide_dmaproc: unsupported func: %d\n", func);
+			printk("ide_dmaproc: unsupported %s func: %d\n", ide_dmafunc_verbose(func), func);
 			return 1;
 	}
 }
@@ -541,14 +545,15 @@
 		}
 	}
 	if (dma_base) {
-		if (extra) /* PDC20246, PDC20262, & HPT343 */
+		if (extra) /* PDC20246, PDC20262, HPT343, & HPT366 */
 			request_region(dma_base+16, extra, name);
 		dma_base += hwif->channel ? 8 : 0;
 		hwif->dma_extra = extra;
 
 		switch(dev->device) {
-			case PCI_DEVICE_ID_CMD_643:
 			case PCI_DEVICE_ID_AL_M5219:
+			case PCI_DEVICE_ID_AMD_VIPER_7409:
+			case PCI_DEVICE_ID_CMD_643:
 				outb(inb(dma_base+2) & 0x60, dma_base+2);
 				if (inb(dma_base+2) & 0x80) {
 					printk("%s: simplex device: DMA forced\n", name);
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ide-features.c linux/drivers/block/ide-features.c
--- v2.3.47/linux/drivers/block/ide-features.c	Fri Jan 21 18:19:16 2000
+++ linux/drivers/block/ide-features.c	Sat Feb 26 20:32:13 2000
@@ -1,16 +1,15 @@
 /*
- * linux/drivers/block/ide-features.c
+ * linux/drivers/block/ide-features.c	Version 0.03	Feb. 10, 2000
  *
- *  Copyright (C) 1999  Linus Torvalds & authors (see below)
+ *  Copyright (C) 1999-2000	Linus Torvalds & authors (see below)
  *  
- *  Andre Hedrick <andre@suse.com>
+ *  Copyright (C) 1999-2000	Andre Hedrick <andre@suse.com>
  *
  *  Extracts if ide.c to address the evolving transfer rate code for
- *  the SETFEATURES_XFER callouts.  Below are original authors of some or
- *  various parts of any given function below.
+ *  the SETFEATURES_XFER callouts.  Various parts of any given function
+ *  are credited to previous ATA-IDE maintainers.
  *
- *  Mark Lord     <mlord@pobox.com>
- *  Gadi Oxman    <gadio@netvision.net.il>
+ *  May be copied or modified under the terms of the GNU General Public License
  */
 
 #define __NO_VERSION__
@@ -36,12 +35,15 @@
 #include <asm/io.h>
 #include <asm/bitops.h>
 
+#define SETFEATURES_CONTROL_REG		(0)	/* some arch's may need */
+
 /*
- *
+ * A Verbose noise maker for debugging on the attempted transfer rates.
  */
 char *ide_xfer_verbose (byte xfer_rate)
 {
 	switch(xfer_rate) {
+		case XFER_UDMA_7:	return("UDMA 7");
 		case XFER_UDMA_6:	return("UDMA 6");
 		case XFER_UDMA_5:	return("UDMA 5");
 		case XFER_UDMA_4:	return("UDMA 4");
@@ -71,14 +73,42 @@
 char *ide_media_verbose (ide_drive_t *drive)
 {
 	switch (drive->media) {
-		case ide_disk:		return("disk  ");
-		case ide_cdrom:		return("cdrom ");
-		case ide_tape:		return("tape  ");
-		case ide_floppy:	return("floppy");
-		default:		return("??????");
+		case ide_scsi:		return("scsi   ");
+		case ide_disk:		return("disk   ");
+		case ide_optical:	return("optical");
+		case ide_cdrom:		return("cdrom  ");
+		case ide_tape:		return("tape   ");
+		case ide_floppy:	return("floppy ");
+		default:		return("???????");
 	}
 }
 
+/*
+ * A Verbose noise maker for debugging on the attempted dmaing calls.
+ */
+char *ide_dmafunc_verbose (ide_dma_action_t dmafunc)
+{
+	switch (dmafunc) {
+		case ide_dma_read:		return("ide_dma_read");
+		case ide_dma_write:		return("ide_dma_write");
+		case ide_dma_begin:		return("ide_dma_begin");
+		case ide_dma_end:		return("ide_dma_end:");
+		case ide_dma_check:		return("ide_dma_check");
+		case ide_dma_on:		return("ide_dma_on");
+		case ide_dma_off:		return("ide_dma_off");
+		case ide_dma_off_quietly:	return("ide_dma_off_quietly");
+		case ide_dma_test_irq:		return("ide_dma_test_irq");
+		case ide_dma_bad_drive:		return("ide_dma_bad_drive");
+		case ide_dma_good_drive:	return("ide_dma_good_drive");
+		case ide_dma_lostirq:		return("ide_dma_lostirq");
+		case ide_dma_timeout:		return("ide_dma_timeout");
+		default:			return("unknown");
+	}
+}
+
+/*
+ * Update the 
+ */
 int ide_driveid_update (ide_drive_t *drive)
 {
 	/*
@@ -129,50 +159,6 @@
 }
 
 /*
- * Similar to ide_wait_stat(), except it never calls ide_error internally.
- * This is a kludge to handle the new ide_config_drive_speed() function,
- * and should not otherwise be used anywhere.  Eventually, the tuneproc's
- * should be updated to return ide_startstop_t, in which case we can get
- * rid of this abomination again.  :)   -ml
- */
-int ide_wait_noerr (ide_drive_t *drive, byte good, byte bad, unsigned long timeout)
-{
-	byte stat;
-	int i;
-	unsigned long flags;
-
-	udelay(1);	/* spec allows drive 400ns to assert "BUSY" */
-	if ((stat = GET_STAT()) & BUSY_STAT) {
-		__save_flags(flags);	/* local CPU only */
-		ide__sti();	/* local CPU only */
-		timeout += jiffies;
-		while ((stat = GET_STAT()) & BUSY_STAT) {
-			if (0 < (signed long)(jiffies - timeout)) {
-				__restore_flags(flags);	/* local CPU only */
-				(void)ide_dump_status(drive, "ide_wait_noerr", stat);
-				return 1;
-			}
-		}
-		__restore_flags(flags); /* local CPU only */
-	}
-	/*
-	 * Allow status to settle, then read it again.
-	 * A few rare drives vastly violate the 400ns spec here,
-	 * so we'll wait up to 10usec for a "good" status
-	 * rather than expensively fail things immediately.
-	 * This fix courtesy of Matthew Faupel & Niccolo Rigacci.
-	 */
-	for (i = 0; i < 10; i++) {
-		udelay(1);
-		if (OK_STAT((stat = GET_STAT()), good, bad))
-			return 0;
-	}
-	(void)ide_dump_status(drive, "ide_wait_noerr", stat);
-	return 1;
-}
-
-
-/*
  * Verify that we are doing an approved SETFEATURES_XFER with respect
  * to the hardware being able to support request.  Since some hardware
  * can improperly report capabilties, we check to see if the host adapter
@@ -213,70 +199,96 @@
 	return 0;
 }
 
-#if 0
-ide_startstop_t set_drive_speed_intr (ide_drive_t *drive)
-{
-	byte stat;
-
-	if (!OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT))
 /*
- *	if (!OK_STAT(stat=GET_STAT(),DRIVE_READY,BAD_STAT))
- *	if (stat != DRIVE_READY)
+ * Similar to ide_wait_stat(), except it never calls ide_error internally.
+ * This is a kludge to handle the new ide_config_drive_speed() function,
+ * and should not otherwise be used anywhere.  Eventually, the tuneproc's
+ * should be updated to return ide_startstop_t, in which case we can get
+ * rid of this abomination again.  :)   -ml
+ *
+ * It is gone..........
+ *
+ * const char *msg == consider adding for verbose errors.
  */
-		(void) ide_dump_status(drive, "set_drive_speed_status", stat);
-
-	return ide_stopped;
-}
-#endif
-
 int ide_config_drive_speed (ide_drive_t *drive, byte speed)
 {
-	unsigned long flags;
-	int err;
+	ide_hwif_t *hwif = HWIF(drive);
+	int	i, error = 1;
+	byte unit = (drive->select.b.unit & 0x01);
 	byte stat;
 
-	__save_flags(flags);	/* local CPU only */
-	__cli();		/* local CPU only */
-
 	/*
 	 * Don't use ide_wait_cmd here - it will
 	 * attempt to set_geometry and recalibrate,
 	 * but for some reason these don't work at
 	 * this point (lost interrupt).
 	 */
+        /*
+         * Select the drive, and issue the SETFEATURES command
+         */
+	disable_irq(hwif->irq);	/* disable_irq_nosync ?? */
+	udelay(1);
 	SELECT_DRIVE(HWIF(drive), drive);
+	udelay(1);
 	if (IDE_CONTROL_REG)
 		OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
 	OUT_BYTE(speed, IDE_NSECTOR_REG);
 	OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
 	OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
-
-	err = ide_wait_noerr(drive, DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT, WAIT_CMD);
-
-#if 0
-	if (IDE_CONTROL_REG)
+	if ((IDE_CONTROL_REG) && (SETFEATURES_CONTROL_REG))
 		OUT_BYTE(drive->ctl, IDE_CONTROL_REG);
-#endif
+	udelay(1);
+	/*
+	 * Wait for drive to become non-BUSY
+	 */
+	if ((stat = GET_STAT()) & BUSY_STAT) {
+		unsigned long flags, timeout;
+		__save_flags(flags);	/* local CPU only */
+		ide__sti();		/* local CPU only -- for jiffies */
+		timeout = jiffies + WAIT_CMD;
+		while ((stat = GET_STAT()) & BUSY_STAT) {
+			if (0 < (signed long)(jiffies - timeout))
+				break;
+		}
+		__restore_flags(flags); /* local CPU only */
+	}
 
-	__restore_flags(flags);	/* local CPU only */
+	/*
+	 * Allow status to settle, then read it again.
+	 * A few rare drives vastly violate the 400ns spec here,
+	 * so we'll wait up to 10usec for a "good" status
+	 * rather than expensively fail things immediately.
+	 * This fix courtesy of Matthew Faupel & Niccolo Rigacci.
+	 */
+	for (i = 0; i < 10; i++) {
+		udelay(1);
+		if (OK_STAT((stat = GET_STAT()), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) {
+			error = 0;
+			break;
+		}
+	}
 
-#if 0
-	ide_set_handler(drive, &set_drive_speed_intr, WAIT_CMD, NULL);
-#endif
+	enable_irq(hwif->irq);
 
-	stat = GET_STAT();
-	if (stat != DRIVE_READY)
+	if (error) {
 		(void) ide_dump_status(drive, "set_drive_speed_status", stat);
+		return error;
+	}
 
 	drive->id->dma_ultra &= ~0xFF00;
 	drive->id->dma_mword &= ~0x0F00;
 	drive->id->dma_1word &= ~0x0F00;
 
+	if (speed > XFER_PIO_4) {
+		outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
+	} else {
+		outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
+	}
+
 	switch(speed) {
-#if 0
-		case XFER_UDMA_6:   drive->id->dma_ultra |= 0x1010; break;
-		case XFER_UDMA_5:   drive->id->dma_ultra |= 0x1010; break;
-#endif
+		case XFER_UDMA_7:   drive->id->dma_ultra |= 0x8080; break;
+		case XFER_UDMA_6:   drive->id->dma_ultra |= 0x4040; break;
+		case XFER_UDMA_5:   drive->id->dma_ultra |= 0x2020; break;
 		case XFER_UDMA_4:   drive->id->dma_ultra |= 0x1010; break;
 		case XFER_UDMA_3:   drive->id->dma_ultra |= 0x0808; break;
 		case XFER_UDMA_2:   drive->id->dma_ultra |= 0x0404; break;
@@ -290,11 +302,10 @@
 		case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break;
 		default: break;
 	}
-	return(err);
+	return error;
 }
 
 EXPORT_SYMBOL(ide_driveid_update);
-EXPORT_SYMBOL(ide_wait_noerr);
 EXPORT_SYMBOL(ide_ata66_check);
 EXPORT_SYMBOL(set_transfer);
 EXPORT_SYMBOL(ide_config_drive_speed);
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ide-floppy.c linux/drivers/block/ide-floppy.c
--- v2.3.47/linux/drivers/block/ide-floppy.c	Wed Feb 16 17:03:51 2000
+++ linux/drivers/block/ide-floppy.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/block/ide-floppy.c	Version 0.9		Jul   4, 1999
+ * linux/drivers/block/ide-floppy.c	Version 0.9	Jul   4, 1999
  *
  * Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il>
  */
@@ -1264,8 +1264,11 @@
 		blocks = descriptor->blocks = ntohl (descriptor->blocks);
 		length = descriptor->length = ntohs (descriptor->length);
 		if (!i && descriptor->dc == CAPACITY_CURRENT) {
-			if (memcmp (descriptor, &floppy->capacity, sizeof (idefloppy_capacity_descriptor_t)))
-				printk (KERN_INFO "%s: %dkB, %d blocks, %d sector size\n", drive->name, blocks * length / 1024, blocks, length);
+			if (memcmp (descriptor, &floppy->capacity, sizeof (idefloppy_capacity_descriptor_t))) {
+				printk (KERN_INFO "%s: %dkB, %d blocks, %d sector size, %s \n",
+					drive->name, blocks * length / 1024, blocks, length,
+					drive->using_dma ? ", DMA":"");
+			}
 			floppy->capacity = *descriptor;
 			if (!length || length % 512)
 				printk (KERN_ERR "%s: %d bytes block size not supported\n", drive->name, length);
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ide-pci.c linux/drivers/block/ide-pci.c
--- v2.3.47/linux/drivers/block/ide-pci.c	Thu Feb 10 17:11:07 2000
+++ linux/drivers/block/ide-pci.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ide-pci.c	Version 1.04	July 27, 1999
+ *  linux/drivers/block/ide-pci.c		Version 1.04	July 27, 1999
  *
  *  Copyright (c) 1998-1999  Andre Hedrick
  *
@@ -31,6 +31,7 @@
 #define DEVID_PIIX4	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82371AB})
 #define DEVID_PIIX4E	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801AB_1})
 #define DEVID_PIIX4U	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801AA_1})
+#define DEVID_PIIX4U2	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82372FB_1})
 #define DEVID_VIA_IDE	((ide_pci_devid_t){PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C561})
 #define DEVID_VP_IDE	((ide_pci_devid_t){PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C586_1})
 #define DEVID_PDC20246	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246})
@@ -95,13 +96,19 @@
 #endif
 
 #ifdef CONFIG_BLK_DEV_AMD7409
+extern unsigned int pci_init_amd7409(struct pci_dev *, const char *);
 extern unsigned int ata66_amd7409(ide_hwif_t *);
 extern void ide_init_amd7409(ide_hwif_t *);
+extern void ide_dmacapable_amd7409(ide_hwif_t *, unsigned long);
+#define PCI_AMD7409	&pci_init_amd7409
 #define ATA66_AMD7409	&ata66_amd7409
 #define INIT_AMD7409	&ide_init_amd7409
+#define DMA_AMD7409	&ide_dmacapable_amd7409
 #else
+#define PCI_AMD7409	NULL
 #define ATA66_AMD7409	NULL
 #define INIT_AMD7409	NULL
+#define DMA_AMD7409	NULL
 #endif
 
 #ifdef CONFIG_BLK_DEV_CMD64X
@@ -135,11 +142,11 @@
 #ifdef CONFIG_BLK_DEV_CS5530
 extern unsigned int pci_init_cs5530(struct pci_dev *, const char *);
 extern void ide_init_cs5530(ide_hwif_t *);
-#define INIT_CS5530	&ide_init_cs5530
 #define PCI_CS5530	&pci_init_cs5530
+#define INIT_CS5530	&ide_init_cs5530
 #else
-#define INIT_CS5530	NULL
 #define PCI_CS5530	NULL
+#define INIT_CS5530	NULL
 #endif
 
 #ifdef CONFIG_BLK_DEV_HPT34X
@@ -149,7 +156,7 @@
 #define INIT_HPT34X	&ide_init_hpt34x
 #else
 #define PCI_HPT34X	NULL
-#define INIT_HPT34X	NULL
+#define INIT_HPT34X	IDE_IGNORE
 #endif
 
 #ifdef CONFIG_BLK_DEV_HPT366
@@ -289,6 +296,7 @@
 	{DEVID_PIIX4,	"PIIX4",	PCI_PIIX,	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0 },
 	{DEVID_PIIX4E,	"PIIX4",	PCI_PIIX,	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
 	{DEVID_PIIX4U,	"PIIX4",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
+	{DEVID_PIIX4U2,	"PIIX4",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
 	{DEVID_VIA_IDE,	"VIA_IDE",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_VP_IDE,	"VP_IDE",	PCI_VIA82CXXX,	ATA66_VIA82CXXX,INIT_VIA82CXXX,	DMA_VIA82CXXX,	{{0x40,0x02,0x02}, {0x40,0x01,0x01}}, 	ON_BOARD,	0 },
 	{DEVID_PDC20246,"PDC20246",	PCI_PDC202XX,	NULL,		INIT_PDC202XX,	NULL,		{{0x50,0x02,0x02}, {0x50,0x04,0x04}}, 	OFF_BOARD,	16 },
@@ -318,7 +326,7 @@
 	{DEVID_CY82C693,"CY82C693",	PCI_CY82C693,	NULL,		INIT_CY82C693,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_HINT,	"HINT_IDE",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_CS5530,	"CS5530",	PCI_CS5530,	NULL,		INIT_CS5530,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
-	{DEVID_AMD7409,	"AMD7409",	NULL,		ATA66_AMD7409,	INIT_AMD7409,	NULL,		{{0x40,0x01,0x01}, {0x40,0x02,0x02}},	ON_BOARD,	0 },
+	{DEVID_AMD7409,	"AMD7409",	PCI_AMD7409,	ATA66_AMD7409,	INIT_AMD7409,	DMA_AMD7409,	{{0x40,0x01,0x01}, {0x40,0x02,0x02}},	ON_BOARD,	0 },
 	{IDE_PCI_DEVID_NULL, "PCI_IDE",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 }};
 
 /*
@@ -329,27 +337,6 @@
 static unsigned int __init ide_special_settings (struct pci_dev *dev, const char *name)
 {
 	switch(dev->device) {
-		case PCI_DEVICE_ID_TTI_HPT343:
-			{
-				int i;
-				unsigned long hpt34xIoBase = dev->resource[4].start;
-				unsigned short pcicmd = 0;
-
-				pci_write_config_byte(dev, 0x80, 0x00);
-				pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
-				if (!(pcicmd & PCI_COMMAND_MEMORY)) {
-					pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
-				} else {
-					pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
-				}
-
-				dev->resource[0].start = (hpt34xIoBase + 0x20);
-				dev->resource[1].start = (hpt34xIoBase + 0x34);
-				dev->resource[2].start = (hpt34xIoBase + 0x28);
-				dev->resource[3].start = (hpt34xIoBase + 0x3c);
-				for(i=0; i<4; i++)
-					dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
-			}
 		case PCI_DEVICE_ID_TTI_HPT366:
 		case PCI_DEVICE_ID_PROMISE_20246:
 		case PCI_DEVICE_ID_PROMISE_20262:
@@ -535,17 +522,8 @@
 #endif
 	}
 	if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)) {
-		/*
-		 * Since there are two cards that report almost identically,
-		 * the only discernable difference is the values
-		 * reported in pcicmd.
-		 * Booting-BIOS card or HPT363 :: pcicmd == 0x07
-		 * Non-bootable card or HPT343 :: pcicmd == 0x05
-		 */
-		if (pcicmd & PCI_COMMAND_MEMORY) {
-			printk("%s: is IDE Express HPT363.\n", d->name);
-			d->bootable = OFF_BOARD;
-		}
+		/* see comments in hpt34x.c on why..... */
+		d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD;
 	}
 	/*
 	 * Set up the IDE ports
@@ -618,9 +596,7 @@
 		if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) ||
-#ifdef CONFIG_BLK_DEV_HPT34X
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X) ||
-#endif /* CONFIG_BLK_DEV_HPT34X */
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_CS5530) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) ||
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ide-probe.c linux/drivers/block/ide-probe.c
--- v2.3.47/linux/drivers/block/ide-probe.c	Sun Feb 20 21:12:38 2000
+++ linux/drivers/block/ide-probe.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ide-probe.c	Version 1.05  July 3, 1999
+ *  linux/drivers/block/ide-probe.c	Version 1.05	July 3, 1999
  *
  *  Copyright (C) 1994-1998  Linus Torvalds & authors (see below)
  */
@@ -57,7 +57,7 @@
 	ide__sti();	/* local CPU only */
 	ide_fix_driveid(id);
 	if (!drive->forced_lun)
-		drive->last_lun = id->word126 & 0x7;
+		drive->last_lun = id->last_lun & 0x7;
 #if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA)
 	/*
 	 * EATA SCSI controllers do a hardware ATA emulation:
@@ -395,6 +395,56 @@
 }
 
 /*
+ * Calculate the region that this interface occupies,
+ * handling interfaces where the registers may not be
+ * ordered sanely.  We deal with the CONTROL register
+ * separately.
+ */
+static int hwif_check_regions (ide_hwif_t *hwif)
+{
+	int region_errors = 0;
+
+	region_errors  = ide_check_region(hwif->io_ports[IDE_DATA_OFFSET], 1);
+	region_errors += ide_check_region(hwif->io_ports[IDE_ERROR_OFFSET], 1);
+	region_errors += ide_check_region(hwif->io_ports[IDE_NSECTOR_OFFSET], 1);
+	region_errors += ide_check_region(hwif->io_ports[IDE_SECTOR_OFFSET], 1);
+	region_errors += ide_check_region(hwif->io_ports[IDE_LCYL_OFFSET], 1);
+	region_errors += ide_check_region(hwif->io_ports[IDE_HCYL_OFFSET], 1);
+	region_errors += ide_check_region(hwif->io_ports[IDE_SELECT_OFFSET], 1);
+	region_errors += ide_check_region(hwif->io_ports[IDE_STATUS_OFFSET], 1);
+	if (hwif->io_ports[IDE_CONTROL_OFFSET])
+		region_errors += ide_check_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
+	if (hwif->io_ports[IDE_IRQ_OFFSET])
+		region_errors += ide_check_region(hwif->io_ports[IDE_IRQ_OFFSET], 1);
+
+	return(region_errors);
+}
+
+static void hwif_register (ide_hwif_t *hwif)
+{
+	if (hwif->io_ports[IDE_DATA_OFFSET])
+		ide_request_region(hwif->io_ports[IDE_DATA_OFFSET], 1, hwif->name);
+	if (hwif->io_ports[IDE_ERROR_OFFSET])
+		ide_request_region(hwif->io_ports[IDE_ERROR_OFFSET], 1, hwif->name);
+	if (hwif->io_ports[IDE_NSECTOR_OFFSET])
+		ide_request_region(hwif->io_ports[IDE_NSECTOR_OFFSET], 1, hwif->name);
+	if (hwif->io_ports[IDE_SECTOR_OFFSET])
+		ide_request_region(hwif->io_ports[IDE_SECTOR_OFFSET], 1, hwif->name);
+	if (hwif->io_ports[IDE_LCYL_OFFSET])
+		ide_request_region(hwif->io_ports[IDE_LCYL_OFFSET], 1, hwif->name);
+	if (hwif->io_ports[IDE_HCYL_OFFSET])
+		ide_request_region(hwif->io_ports[IDE_HCYL_OFFSET], 1, hwif->name);
+	if (hwif->io_ports[IDE_SELECT_OFFSET])
+		ide_request_region(hwif->io_ports[IDE_SELECT_OFFSET], 1, hwif->name);
+	if (hwif->io_ports[IDE_STATUS_OFFSET])
+		ide_request_region(hwif->io_ports[IDE_STATUS_OFFSET], 1, hwif->name);
+	if (hwif->io_ports[IDE_CONTROL_OFFSET])
+		ide_request_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1, hwif->name);
+	if (hwif->io_ports[IDE_IRQ_OFFSET])
+		ide_request_region(hwif->io_ports[IDE_IRQ_OFFSET], 1, hwif->name);
+}
+
+/*
  * 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.
  */
@@ -403,12 +453,6 @@
 	unsigned int unit;
 	unsigned long flags;
 
-	ide_ioreg_t ide_control_reg 	= hwif->io_ports[IDE_CONTROL_OFFSET];
-	ide_ioreg_t region_low 		= hwif->io_ports[IDE_DATA_OFFSET];
-	ide_ioreg_t region_high 	= region_low;
-	unsigned int region_request	= 8;
-	int i;
-
 	if (hwif->noprobe)
 		return;
 	if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) {
@@ -417,30 +461,11 @@
 		probe_cmos_for_drives (hwif);
 	}
 
-	/*
-	 * Calculate the region that this interface occupies,
-	 * handling interfaces where the registers may not be
-	 * ordered sanely.  We deal with the CONTROL register
-	 * separately.
-	 */
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		if (hwif->io_ports[i]) {
-			if (hwif->io_ports[i] < region_low)
-				region_low = hwif->io_ports[i];
-			if (hwif->io_ports[i] > region_high)
-				region_high = hwif->io_ports[i];
-		}
-	}
-	region_request = (region_high - region_low);
-	if (region_request == 0x0007)
-		region_request++;
 	if ((hwif->chipset != ide_4drives || !hwif->mate->present) &&
 #if CONFIG_BLK_DEV_PDC4030
 	    (hwif->chipset != ide_pdc4030 || hwif->channel == 0) &&
 #endif /* CONFIG_BLK_DEV_PDC4030 */
-	    (ide_check_region(region_low, region_request) ||
-	    (ide_control_reg && ide_check_region(ide_control_reg,1))))
-	{
+	    (hwif_check_regions(hwif))) {
 		int msgout = 0;
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
 			ide_drive_t *drive = &hwif->drives[unit];
@@ -467,20 +492,18 @@
 		if (drive->present && !hwif->present) {
 			hwif->present = 1;
 			if (hwif->chipset != ide_4drives || !hwif->mate->present) {
-				ide_request_region(region_low, region_request, hwif->name);
-				if (ide_control_reg)
-					ide_request_region(ide_control_reg, 1, hwif->name);
+				hwif_register(hwif);
 			}
 		}
 	}
-	if (ide_control_reg && hwif->reset) {
+	if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) {
 		unsigned long timeout = jiffies + WAIT_WORSTCASE;
 		byte stat;
 
 		printk("%s: reset\n", hwif->name);
-		OUT_BYTE(12, ide_control_reg);
+		OUT_BYTE(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
 		udelay(10);
-		OUT_BYTE(8, ide_control_reg);
+		OUT_BYTE(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
 		do {
 			ide_delay_50ms();
 			stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]);
@@ -594,7 +617,11 @@
 	 * Allocate the irq, if not already obtained for another hwif
 	 */
 	if (!match || match->irq != hwif->irq) {
+#ifdef CONFIG_IDEPCI_SHARE_IRQ
+		int sa = (hwif->chipset == ide_pci) ? SA_SHIRQ : SA_INTERRUPT;
+#else /* !CONFIG_IDEPCI_SHARE_IRQ */
 		int sa = (hwif->chipset == ide_pci) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT;
+#endif /* CONFIG_IDEPCI_SHARE_IRQ */
 		if (ide_request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwgroup)) {
 			if (!match)
 				kfree(hwgroup);
@@ -784,20 +811,18 @@
 		return (hwif->present = 0);
 	}
 	
-	if (init_irq (hwif)) {
+	if (init_irq(hwif)) {
 		int i = hwif->irq;
 		/*
 		 *	It failed to initialise. Find the default IRQ for 
 		 *	this port and try that.
 		 */
-		if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) 
-		{
+		if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) {
 			printk("%s: Disabled unable to get IRQ %d.\n", hwif->name, i);
 			(void) unregister_blkdev (hwif->major, hwif->name);
 			return (hwif->present = 0);
 		}
-		if(init_irq (hwif)) 
-		{
+		if (init_irq(hwif)) {
 			printk("%s: probed IRQ %d and default IRQ %d failed.\n",
 				hwif->name, i, hwif->irq);
 			(void) unregister_blkdev (hwif->major, hwif->name);
@@ -863,7 +888,8 @@
 	for (index = 0; index < MAX_HWIFS; ++index)
 		if (probe[index])
 			hwif_init(&ide_hwifs[index]);
-	ide_register_module(&ideprobe_module);
+	if (!ide_probe)
+		ide_probe = &ideprobe_module;
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
@@ -882,6 +908,6 @@
 
 void cleanup_module (void)
 {
-	ide_unregister_module(&ideprobe_module);
+	ide_probe = NULL;
 }
 #endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ide-proc.c linux/drivers/block/ide-proc.c
--- v2.3.47/linux/drivers/block/ide-proc.c	Tue Dec  7 09:32:43 1999
+++ linux/drivers/block/ide-proc.c	Sat Feb 26 20:32:13 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ide-proc.c	Version 1.03	January   2, 1998
+ *  linux/drivers/block/ide-proc.c	Version 1.03	January  2, 1998
  *
  *  Copyright (C) 1997-1998	Mark Lord
  */
@@ -73,21 +73,46 @@
 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
 #endif
 
+#ifdef CONFIG_BLK_DEV_AEC6210
+extern byte aec6210_proc;
+int (*aec6210_display_info)(char *, char **, off_t, int) = NULL;
+#endif /* CONFIG_BLK_DEV_AEC6210 */
 #ifdef CONFIG_BLK_DEV_ALI15X3
 extern byte ali_proc;
 int (*ali_display_info)(char *, char **, off_t, int) = NULL;
 #endif /* CONFIG_BLK_DEV_ALI15X3 */
-
+#ifdef CONFIG_BLK_DEV_AMD7409
+extern byte amd7409_proc;
+int (*amd7409_display_info)(char *, char **, off_t, int) = NULL;
+#endif /* CONFIG_BLK_DEV_AMD7409 */
+#ifdef CONFIG_BLK_DEV_CMD64X
+extern byte cmd64x_proc;
+int (*cmd64x_display_info)(char *, char **, off_t, int) = NULL;
+#endif /* CONFIG_BLK_DEV_CMD64X */
+#ifdef CONFIG_BLK_DEV_CS5530
+extern byte cs5530_proc;
+int (*cs5530_display_info)(char *, char **, off_t, int) = NULL;
+#endif /* CONFIG_BLK_DEV_CS5530 */
+#ifdef CONFIG_BLK_DEV_HPT34X
+extern byte hpt34x_proc;
+int (*hpt34x_display_info)(char *, char **, off_t, int) = NULL;
+#endif /* CONFIG_BLK_DEV_HPT34X */
+#ifdef CONFIG_BLK_DEV_HPT366
+extern byte hpt366_proc;
+int (*hpt366_display_info)(char *, char **, off_t, int) = NULL;
+#endif /* CONFIG_BLK_DEV_HPT366 */
+#ifdef CONFIG_BLK_DEV_PDC202XX
+extern byte pdc202xx_proc;
+int (*pdc202xx_display_info)(char *, char **, off_t, int) = NULL;
+#endif /* CONFIG_BLK_DEV_PDC202XX */
 #ifdef CONFIG_BLK_DEV_PIIX
 extern byte piix_proc;
 int (*piix_display_info)(char *, char **, off_t, int) = NULL;
 #endif /* CONFIG_BLK_DEV_PIIX */
-
 #ifdef CONFIG_BLK_DEV_SIS5513
 extern byte sis_proc;
 int (*sis_display_info)(char *, char **, off_t, int) = NULL;
 #endif /* CONFIG_BLK_DEV_SIS5513 */
-
 #ifdef CONFIG_BLK_DEV_VIA82CXXX
 extern byte via_proc;
 int (*via_display_info)(char *, char **, off_t, int) = NULL;
@@ -229,7 +254,7 @@
 #endif	/* CONFIG_BLK_DEV_IDEPCI */
 			if (for_real) {
 #if 0
-				printk("proc_ide_write_config: type=%c, reg=0x%x, val=0x%x, digits=%d\n", is_pci ? 'PCI' : 'non-PCI', reg, val, digits);
+				printk("proc_ide_write_config: type=%c, reg=0x%x, val=0x%x, digits=%d\n", is_pci ? "PCI" : "non-PCI", reg, val, digits);
 #endif
 				if (is_pci) {
 #ifdef CONFIG_BLK_DEV_IDEPCI
@@ -349,7 +374,7 @@
 
 	while (p) {
 		driver = (ide_driver_t *) p->info;
-		if (p->type == IDE_DRIVER_MODULE && driver)
+		if (driver)
 			out += sprintf(out, "%s version %s\n", driver->name, driver->version);
 		p = p->next;
 	}
@@ -775,10 +800,38 @@
 	create_proc_read_entry("drivers",0,proc_ide_root,
 				proc_ide_read_drivers, NULL);
 
+#ifdef CONFIG_BLK_DEV_AEC6210
+	if ((aec6210_display_info) && (aec6210_proc))
+		create_proc_info_entry("aec6210", 0, proc_ide_root, aec6210_display_info);
+#endif /* CONFIG_BLK_DEV_AEC6210 */
 #ifdef CONFIG_BLK_DEV_ALI15X3
 	if ((ali_display_info) && (ali_proc))
 		create_proc_info_entry("ali", 0, proc_ide_root, ali_display_info);
 #endif /* CONFIG_BLK_DEV_ALI15X3 */
+#ifdef CONFIG_BLK_DEV_AMD7409
+	if ((amd7409_display_info) && (amd7409_proc))
+		create_proc_info_entry("amd7409", 0, proc_ide_root, amd7409_display_info);
+#endif /* CONFIG_BLK_DEV_AMD7409 */
+#ifdef CONFIG_BLK_DEV_CMD64X
+	if ((cmd64x_display_info) && (cmd64x_proc))
+		create_proc_info_entry("cmd64x", 0, proc_ide_root, cmd64x_display_info);
+#endif /* CONFIG_BLK_DEV_CMD64X */
+#ifdef CONFIG_BLK_DEV_CS5530
+	if ((cs5530_display_info) && (cs5530_proc))
+		create_proc_info_entry("cs5530", 0, proc_ide_root, cs5530_display_info);
+#endif /* CONFIG_BLK_DEV_CS5530 */
+#ifdef CONFIG_BLK_DEV_HPT34X
+	if ((hpt34x_display_info) && (hpt34x_proc))
+		create_proc_info_entry("", 0, proc_ide_root, hpt34x_display_info);
+#endif /* CONFIG_BLK_DEV_HPT34X */
+#ifdef CONFIG_BLK_DEV_HPT366
+	if ((hpt366_display_info) && (hpt366_proc))
+		create_proc_info_entry("", 0, proc_ide_root, hpt366_display_info);
+#endif /* CONFIG_BLK_DEV_HPT366 */
+#ifdef CONFIG_BLK_DEV_PDC202XX
+	if ((pdc202xx_display_info) && (pdc202xx_proc))
+		create_proc_info_entry("pdc202xx", 0, proc_ide_root, pdc202xx_display_info);
+#endif /* CONFIG_BLK_DEV_PDC202XX */
 #ifdef CONFIG_BLK_DEV_PIIX
 	if ((piix_display_info) && (piix_proc))
 		create_proc_info_entry("piix", 0, proc_ide_root, piix_display_info);
@@ -799,10 +852,38 @@
 	 * Mmmm.. does this free up all resources,
 	 * or do we need to do a more proper cleanup here ??
 	 */
+#ifdef CONFIG_BLK_DEV_AEC6210
+	if ((aec6210_display_info) && (aec6210_proc))
+		remove_proc_entry("ide/aec6210",0);
+#endif /* CONFIG_BLK_DEV_AEC6210 */
 #ifdef CONFIG_BLK_DEV_ALI15X3
 	if ((ali_display_info) && (ali_proc))
 		remove_proc_entry("ide/ali",0);
 #endif /* CONFIG_BLK_DEV_ALI15X3 */
+#ifdef CONFIG_BLK_DEV_AMD7409
+	if ((amd7409_display_info) && (amd7409_proc))
+		remove_proc_entry("ide/amd7409",0);
+#endif /* CONFIG_BLK_DEV_AMD7409 */
+#ifdef CONFIG_BLK_DEV_CMD64X
+	if ((cmd64x_display_info) && (cmd64x_proc))
+		remove_proc_entry("ide/cmd64x",0);
+#endif /* CONFIG_BLK_DEV_CMD64X */
+#ifdef CONFIG_BLK_DEV_CS5530
+	if ((cs5530_display_info) && (cs5530_proc))
+		remove_proc_entry("ide/cs5530",0);
+#endif /* CONFIG_BLK_DEV_CS5530 */
+#ifdef CONFIG_BLK_DEV_HPT34X
+	if ((hpt34x_display_info) && (hpt34x_proc))
+		remove_proc_entry("ide/hpt34x",0);
+#endif /* CONFIG_BLK_DEV_HPT34X */
+#ifdef CONFIG_BLK_DEV_HPT366
+	if ((hpt366_display_info) && (hpt366_proc))
+		remove_proc_entry("ide/hpt366",0);
+#endif /* CONFIG_BLK_DEV_HPT366 */
+#ifdef CONFIG_BLK_DEV_PDC202XX
+	if ((pdc202xx_display_info) && (pdc202xx_proc))
+		remove_proc_entry("ide/pdc202xx",0);
+#endif /* CONFIG_BLK_DEV_PDC202XX */
 #ifdef CONFIG_BLK_DEV_PIIX
 	if ((piix_display_info) && (piix_proc))
 		remove_proc_entry("ide/piix",0);
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c
--- v2.3.47/linux/drivers/block/ide-tape.c	Wed Feb 16 17:03:51 2000
+++ linux/drivers/block/ide-tape.c	Sat Feb 26 20:32:14 2000
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/block/ide-tape.c	Version 1.16f		Dec  15, 1999
+ * linux/drivers/block/ide-tape.c		Version 1.16f	Dec  15, 1999
  *
  * Copyright (C) 1995 - 1999 Gadi Oxman <gadio@netvision.net.il>
  *
@@ -411,12 +411,12 @@
 #include <asm/bitops.h>
 
 
-#define NO_LONGER_REQUIRE	(1)
+#define NO_LONGER_REQUIRED	(1)
 
 /*
  *	OnStream support
  */
-#define ONSTREAM_DEBUG		(1)
+#define ONSTREAM_DEBUG		(0)
 #define OS_CONFIG_PARTITION	(0xff)
 #define OS_DATA_PARTITION	(0)
 #define OS_PARTITION_VERSION	(1)
@@ -543,6 +543,7 @@
 /*
  *	The following are used to debug the driver:
  *
+ *	Setting IDETAPE_DEBUG_INFO to 1 will report device capabilities.
  *	Setting IDETAPE_DEBUG_LOG to 1 will log driver flow control.
  *	Setting IDETAPE_DEBUG_BUGS to 1 will enable self-sanity checks in
  *	some places.
@@ -557,7 +558,9 @@
  *	is verified to be stable enough. This will make it much more
  *	esthetic.
  */
+#define IDETAPE_DEBUG_INFO		0
 #define IDETAPE_DEBUG_LOG		1
+#define IDETAPE_DEBUG_LOG_VERBOSE	0
 #define IDETAPE_DEBUG_BUGS		1
 
 /*
@@ -700,9 +703,10 @@
  */
 typedef struct {
 	unsigned	page_code	:6;	/* Page code - Should be 0x2a */
-	unsigned	reserved1_67	:2;
-	u8		page_length;		/* Page Length - Should be 0x12 */
-	u8		reserved2, reserved3;
+	__u8		reserved0_6	:1;
+	__u8		ps		:1;	/* parameters saveable */
+	__u8		page_length;		/* Page Length - Should be 0x12 */
+	__u8		reserved2, reserved3;
 	unsigned	ro		:1;	/* Read Only Mode */
 	unsigned	reserved4_1234	:4;
 	unsigned	sprev		:1;	/* Supports SPACE in the reverse direction */
@@ -716,7 +720,8 @@
 	unsigned	locked		:1;	/* The volume is locked */
 	unsigned	prevent		:1;	/* The device defaults in the prevent state after power up */	
 	unsigned	eject		:1;	/* The device can eject the volume */
-	unsigned	reserved6_45	:2;	/* Reserved */	
+	__u8		disconnect	:1;	/* The device can break request > ctl */	
+	__u8		reserved6_5	:1;
 	unsigned	ecc		:1;	/* Supports error correction */
 	unsigned	cmprs		:1;	/* Supports data compression */
 	unsigned	reserved7_0	:1;
@@ -726,12 +731,12 @@
 	unsigned	blk32768	:1;	/* slowb - the device restricts the byte count for PIO */
 						/* transfers for slow buffer memory ??? */
 						/* Also 32768 block size in some cases */
-	u16		max_speed;		/* Maximum speed supported in KBps */
-	u8		reserved10, reserved11;
-	u16		ctl;			/* Continuous Transfer Limit in blocks */
-	u16		speed;			/* Current Speed, in KBps */
-	u16		buffer_size;		/* Buffer Size, in 512 bytes */
-	u8		reserved18, reserved19;
+	__u16		max_speed;		/* Maximum speed supported in KBps */
+	__u8		reserved10, reserved11;
+	__u16		ctl;			/* Continuous Transfer Limit in blocks */
+	__u16		speed;			/* Current Speed, in KBps */
+	__u16		buffer_size;		/* Buffer Size, in 512 bytes */
+	__u8		reserved18, reserved19;
 } idetape_capabilities_page_t;
 
 /*
@@ -741,8 +746,8 @@
 	unsigned	page_code	:6;	/* Page code - Should be 0x30 */
 	unsigned	reserved1_6	:1;
 	unsigned	ps		:1;
-	u8		page_length;		/* Page Length - Should be 2 */
-	u8		reserved2;
+	__u8		page_length;		/* Page Length - Should be 2 */
+	__u8		reserved2;
 	unsigned	play32		:1;
 	unsigned	play32_5	:1;
 	unsigned	reserved2_23	:2;
@@ -768,23 +773,23 @@
 typedef struct {
 	unsigned	error_code	:7;	/* Current of deferred errors */
 	unsigned	valid		:1;	/* The information field conforms to QIC-157C */
-	u8		reserved1	:8;	/* Segment Number - Reserved */
+	__u8		reserved1	:8;	/* Segment Number - Reserved */
 	unsigned	sense_key	:4;	/* Sense Key */
 	unsigned	reserved2_4	:1;	/* Reserved */
 	unsigned	ili		:1;	/* Incorrect Length Indicator */
 	unsigned	eom		:1;	/* End Of Medium */
 	unsigned	filemark 	:1;	/* Filemark */
-	u32		information __attribute__ ((packed));
-	u8		asl;			/* Additional sense length (n-7) */
-	u32		command_specific;	/* Additional command specific information */
-	u8		asc;			/* Additional Sense Code */
-	u8		ascq;			/* Additional Sense Code Qualifier */
-	u8		replaceable_unit_code;	/* Field Replaceable Unit Code */
+	__u32		information __attribute__ ((packed));
+	__u8		asl;			/* Additional sense length (n-7) */
+	__u32		command_specific;	/* Additional command specific information */
+	__u8		asc;			/* Additional Sense Code */
+	__u8		ascq;			/* Additional Sense Code Qualifier */
+	__u8		replaceable_unit_code;	/* Field Replaceable Unit Code */
 	unsigned	sk_specific1 	:7;	/* Sense Key Specific */
 	unsigned	sksv		:1;	/* Sense Key Specific information is valid */
-	u8		sk_specific2;		/* Sense Key Specific */
-	u8		sk_specific3;		/* Sense Key Specific */
-	u8		pad[2];			/* Padding to 20 bytes */
+	__u8		sk_specific2;		/* Sense Key Specific */
+	__u8		sk_specific3;		/* Sense Key Specific */
+	__u8		pad[2];			/* Padding to 20 bytes */
 } idetape_request_sense_result_t;
 
 
@@ -1247,13 +1252,13 @@
 	unsigned	reserved3_45	:2;	/* Reserved */
 	unsigned	reserved3_6	:1;	/* TrmIOP - Reserved */
 	unsigned	reserved3_7	:1;	/* AENC - Reserved */
-	u8		additional_length;	/* Additional Length (total_length-4) */
-	u8		rsv5, rsv6, rsv7;	/* Reserved */
-	u8		vendor_id[8];		/* Vendor Identification */
-	u8		product_id[16];		/* Product Identification */
-	u8		revision_level[4];	/* Revision Level */
-	u8		vendor_specific[20];	/* Vendor Specific - Optional */
-	u8		reserved56t95[40];	/* Reserved - Optional */
+	__u8		additional_length;	/* Additional Length (total_length-4) */
+	__u8		rsv5, rsv6, rsv7;	/* Reserved */
+	__u8		vendor_id[8];		/* Vendor Identification */
+	__u8		product_id[16];		/* Product Identification */
+	__u8		revision_level[4];	/* Revision Level */
+	__u8		vendor_specific[20];	/* Vendor Specific - Optional */
+	__u8		reserved56t95[40];	/* Reserved - Optional */
 						/* Additional information may be returned */
 } idetape_inquiry_result_t;
 
@@ -1287,10 +1292,25 @@
  *	Mode Parameter Header for the MODE SENSE packet command
  */
 typedef struct {
-	u8		mode_data_length;	/* Length of the following data transfer */
-	u8		medium_type;		/* Medium Type */
-	u8		dsp;			/* Device Specific Parameter */
-	u8		bdl;			/* Block Descriptor Length */
+	__u8	mode_data_length;	/* Length of the following data transfer */
+	__u8	medium_type;		/* Medium Type */
+	__u8	dsp;			/* Device Specific Parameter */
+	__u8	bdl;			/* Block Descriptor Length */
+#if 0
+	/* data transfer page */
+	__u8	page_code	:6;
+	__u8	reserved0_6	:1;
+	__u8	ps		:1;	/* parameters saveable */
+	__u8	page_length;		/* page Length == 0x02 */
+	__u8	reserved2;
+	__u8	read32k		:1;	/* 32k blk size (data only) */
+	__u8	read32k5	:1;	/* 32.5k blk size (data&AUX) */
+	__u8	reserved3_23	:2;
+	__u8	write32k	:1;	/* 32k blk size (data only) */
+	__u8	write32k5	:1;	/* 32.5k blk size (data&AUX) */
+	__u8	reserved3_6	:1;
+	__u8	streaming	:1;	/* streaming mode enable */
+#endif
 } idetape_mode_parameter_header_t;
 
 /*
@@ -1299,10 +1319,10 @@
  *	Support for block descriptors is optional.
  */
 typedef struct {
-	u8		density_code;		/* Medium density code */
-	u8		blocks[3];		/* Number of blocks */
-	u8		reserved4;		/* Reserved */
-	u8		length[3];		/* Block Length */
+	__u8		density_code;		/* Medium density code */
+	__u8		blocks[3];		/* Number of blocks */
+	__u8		reserved4;		/* Reserved */
+	__u8		length[3];		/* Block Length */
 } idetape_parameter_block_descriptor_t;
 
 /*
@@ -1312,16 +1332,16 @@
 	unsigned	page_code	:6;	/* Page Code - Should be 0xf */
 	unsigned	reserved0	:1;	/* Reserved */
 	unsigned	ps		:1;
-	u8		page_length;		/* Page Length - Should be 14 */
+	__u8		page_length;		/* Page Length - Should be 14 */
 	unsigned	reserved2	:6;	/* Reserved */
 	unsigned	dcc		:1;	/* Data Compression Capable */
 	unsigned	dce		:1;	/* Data Compression Enable */
 	unsigned	reserved3	:5;	/* Reserved */
 	unsigned	red		:2;	/* Report Exception on Decompression */
 	unsigned	dde		:1;	/* Data Decompression Enable */
-	u32		ca;			/* Compression Algorithm */
-	u32		da;			/* Decompression Algorithm */
-	u8		reserved[4];		/* Reserved */
+	__u32		ca;			/* Compression Algorithm */
+	__u32		da;			/* Decompression Algorithm */
+	__u8		reserved[4];		/* Reserved */
 } idetape_data_compression_page_t;
 
 /*
@@ -1331,16 +1351,16 @@
 	unsigned	page_code	:6;	/* Page Code - Should be 0x11 */
 	unsigned	reserved1_6	:1;	/* Reserved */
 	unsigned	ps		:1;
-	u8		page_length;		/* Page Length - Should be 6 */
-	u8		map;			/* Maximum Additional Partitions - Should be 0 */
-	u8		apd;			/* Additional Partitions Defined - Should be 0 */
+	__u8		page_length;		/* Page Length - Should be 6 */
+	__u8		map;			/* Maximum Additional Partitions - Should be 0 */
+	__u8		apd;			/* Additional Partitions Defined - Should be 0 */
 	unsigned	reserved4_012	:3;	/* Reserved */
 	unsigned	psum		:2;	/* Should be 0 */
 	unsigned	idp		:1;	/* Should be 0 */
 	unsigned	sdp		:1;	/* Should be 0 */
 	unsigned	fdp		:1;	/* Fixed Data Partitions */
-	u8		mfr;			/* Medium Format Recognition */
-	u8		reserved[2];		/* Reserved */
+	__u8		mfr;			/* Medium Format Recognition */
+	__u8		reserved[2];		/* Reserved */
 } idetape_medium_partition_page_t;
 
 /*
@@ -1359,6 +1379,53 @@
 static idetape_chrdev_t idetape_chrdevs[MAX_HWIFS * MAX_DRIVES];
 static int idetape_chrdev_present = 0;
 
+#if IDETAPE_DEBUG_LOG_VERBOSE
+
+/*
+ * DO NOT REMOVE, BUILDING A VERBOSE DEBUG SCHEME FOR ATAPI
+ */
+
+char *idetape_sense_key_verbose (byte idetape_sense_key)
+{
+	switch (idetape_sense_key) {
+		default: {
+			char buf[22];
+			sprintf(buf, "IDETAPE_SENSE (0x%02x)", idetape_sense_key);
+			return(buf);
+		}
+
+	}
+}
+
+char *idetape_command_key_verbose (byte idetape_command_key)
+{
+	switch (idetape_command_key) {
+		case IDETAPE_TEST_UNIT_READY_CMD:	return("TEST_UNIT_READY_CMD");
+		case IDETAPE_REWIND_CMD:		return("REWIND_CMD");
+		case IDETAPE_REQUEST_SENSE_CMD:		return("REQUEST_SENSE_CMD");
+		case IDETAPE_READ_CMD:			return("READ_CMD");
+		case IDETAPE_WRITE_CMD:			return("WRITE_CMD");
+		case IDETAPE_WRITE_FILEMARK_CMD:	return("WRITE_FILEMARK_CMD");
+		case IDETAPE_SPACE_CMD:			return("SPACE_CMD");
+		case IDETAPE_INQUIRY_CMD:		return("INQUIRY_CMD");
+		case IDETAPE_ERASE_CMD:			return("ERASE_CMD")
+		case IDETAPE_MODE_SENSE_CMD:		return("MODE_SENSE_CMD");
+		case IDETAPE_MODE_SELECT_CMD:		return("MODE_SELECT_CMD");
+		case IDETAPE_LOAD_UNLOAD_CMD:		return("LOAD_UNLOAD_CMD");
+		case IDETAPE_PREVENT_CMD:		return("PREVENT_CMD");
+		case IDETAPE_LOCATE_CMD:		return("LOCATE_CMD");
+		case IDETAPE_READ_POSITION_CMD:		return("READ_POSITION_CMD");
+		case IDETAPE_READ_BUFFER_CMD:		return("READ_BUFFER_CMD");
+		case IDETAPE_SET_SPEED_CMD:		return("SET_SPEED_CMD");
+		default: {
+				char buf[20];
+				sprintf(buf, "CMD (0x%02x)", idetape_command_key);
+				return(buf);
+			}
+	}
+}
+#endif /* IDETAPE_DEBUG_LOG_VERBOSE */
+
 /*
  *	Too bad. The drive wants to send us data which we are not ready to accept.
  *	Just throw it away.
@@ -1523,6 +1590,14 @@
 	 */
 	if (tape->debug_level >= 1)
 		printk (KERN_INFO "ide-tape: pc = %x, sense key = %x, asc = %x, ascq = %x\n",pc->c[0],result->sense_key,result->asc,result->ascq);
+#if IDETAPE_DEBUG_LOG_VERBOSE
+	if (tape->debug_level >= 1)
+		printk (KERN_INFO "ide-tape: pc = %s, sense key = %x, asc = %x, ascq = %x\n",
+			idetape_command_key_verbose((byte) pc->c[0]),
+			result->sense_key,
+			result->asc,
+			result->ascq);
+#endif /* IDETAPE_DEBUG_LOG_VERBOSE */
 #endif /* IDETAPE_DEBUG_LOG */
 
 	if (tape->onstream && result->sense_key == 2 && result->asc == 0x53 && result->ascq == 2) {
@@ -3833,7 +3908,7 @@
 			if (tape->onstream) {
 #if ONSTREAM_DEBUG
 				if (tape->debug_level >= 1)
-					printk(KERN_INFO "ide-tape: %s: first_stage == NULL, pipeline error %d\n", tape->name, test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags));
+					printk(KERN_INFO "ide-tape: %s: first_stage == NULL, pipeline error %ld\n", tape->name, (long)test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags));
 #endif
 				clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
 				position = idetape_read_position(drive);
@@ -5280,16 +5355,16 @@
 static int idetape_identify_device (ide_drive_t *drive,struct hd_driveid *id)
 {
 	struct idetape_id_gcw gcw;
-#if IDETAPE_DEBUG_LOG
+#if IDETAPE_DEBUG_INFO
 	unsigned short mask,i;
-#endif /* IDETAPE_DEBUG_LOG */
+#endif /* IDETAPE_DEBUG_INFO */
 
 	if (!id)
 		return 0;
 
 	*((unsigned short *) &gcw) = id->config;
 
-#if IDETAPE_DEBUG_LOG
+#if IDETAPE_DEBUG_INFO
 	printk (KERN_INFO "ide-tape: Dumping ATAPI Identify Device tape parameters\n");
 	printk (KERN_INFO "ide-tape: Protocol Type: ");
 	switch (gcw.protocol) {
@@ -5377,7 +5452,7 @@
 		
 	} else
 		printk (KERN_INFO "ide-tape: According to the device, fields 64-70 are not valid.\n");
-#endif /* IDETAPE_DEBUG_LOG */
+#endif /* IDETAPE_DEBUG_INFO */
 
 	/* Check that we can support this device */
 
@@ -5462,12 +5537,12 @@
 	header = (idetape_mode_parameter_header_t *) pc.buffer;
 	bs = (idetape_block_size_page_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t) + header->bdl);
 
-#if IDETAPE_DEBUG_LOG
+#if IDETAPE_DEBUG_INFO
 	printk(KERN_INFO "ide-tape: 32KB play back: %s\n", bs->play32 ? "Yes" : "No");
 	printk(KERN_INFO "ide-tape: 32.5KB play back: %s\n", bs->play32_5 ? "Yes" : "No");
 	printk(KERN_INFO "ide-tape: 32KB record: %s\n", bs->record32 ? "Yes" : "No");
 	printk(KERN_INFO "ide-tape: 32.5KB record: %s\n", bs->record32_5 ? "Yes" : "No");
-#endif
+#endif /* IDETAPE_DEBUG_INFO */
 
 	/*
 	 * Configure default auto columns mode, 32.5KB block size
@@ -5587,7 +5662,7 @@
 	else if (tape->onstream && capabilities->blk32768)
 		tape->tape_block_size = 32768;
 
-#if IDETAPE_DEBUG_LOG
+#if IDETAPE_DEBUG_INFO
 	printk (KERN_INFO "ide-tape: Dumping the results of the MODE SENSE packet command\n");
 	printk (KERN_INFO "ide-tape: Mode Parameter Header:\n");
 	printk (KERN_INFO "ide-tape: Mode Data Length - %d\n",header->mode_data_length);
@@ -5615,7 +5690,7 @@
 	printk (KERN_INFO "ide-tape: Continuous transfer limits in blocks - %d\n",capabilities->ctl);
 	printk (KERN_INFO "ide-tape: Current speed in KBps - %d\n",capabilities->speed);	
 	printk (KERN_INFO "ide-tape: Buffer size - %d\n",capabilities->buffer_size*512);
-#endif /* IDETAPE_DEBUG_LOG */
+#endif /* IDETAPE_DEBUG_INFO */
 }
 
 static void idetape_add_settings (ide_drive_t *drive)
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v2.3.47/linux/drivers/block/ide.c	Wed Feb 16 17:03:51 2000
+++ linux/drivers/block/ide.c	Sat Feb 26 20:32:14 2000
@@ -186,6 +186,7 @@
  * ide_modules keeps track of the available IDE chipset/probe/driver modules.
  */
 ide_module_t *ide_modules = NULL;
+ide_module_t *ide_probe = NULL;
 
 /*
  * This is declared extern in ide.h, for access by other IDE modules:
@@ -281,7 +282,7 @@
  * for the max possible number (MAX_HWIFS * MAX_DRIVES) of them.
  */
 #define MAGIC_COOKIE 0x12345678
-static void init_ide_data (void)
+static void __init init_ide_data (void)
 {
 	unsigned int index;
 	static unsigned long magic_cookie = MAGIC_COOKIE;
@@ -1093,13 +1094,18 @@
 #endif
 	block    = rq->sector;
 	blockend = block + rq->nr_sectors;
-	if ((blockend < block) || (blockend > drive->part[minor&PARTN_MASK].nr_sects)) {
-		printk("%s%c: bad access: block=%ld, count=%ld\n", drive->name,
-		 (minor&PARTN_MASK)?'0'+(minor&PARTN_MASK):' ', block, rq->nr_sectors);
-		goto kill_rq;
+#if 0
+	if ((rq->cmd == READ || rq->cmd == WRITE) &&
+	    (drive->media == ide_disk || drive->media == ide_floppy))
+#endif
+	{
+		if ((blockend < block) || (blockend > drive->part[minor&PARTN_MASK].nr_sects)) {
+			printk("%s%c: bad access: block=%ld, count=%ld\n", drive->name,
+			 (minor&PARTN_MASK)?'0'+(minor&PARTN_MASK):' ', block, rq->nr_sectors);
+			goto kill_rq;
+		}
+		block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0;
 	}
-	block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0;
-
 	/* Yecch - this will shift the entire interval,
 	   possibly killing some innocent following sector */
 	if (block == 0 && drive->remap_0_to_1 == 1)
@@ -1409,9 +1415,9 @@
 		}
 	} else {
 		ide_drive_t *drive = hwgroup->drive;
-		hwgroup->handler = NULL;
 		if (!drive) {
 			printk("ide_timer_expiry: hwgroup->drive was NULL\n");
+			hwgroup->handler = NULL;
 		} else {
 			ide_hwif_t *hwif;
 			ide_startstop_t startstop;
@@ -1429,6 +1435,7 @@
 					return;
 				}
 			}
+			hwgroup->handler = NULL;
 			/*
 			 * We need to simulate a real interrupt when invoking
 			 * the handler() function, which means we need to globally
@@ -1436,7 +1443,7 @@
 			 */
 			spin_unlock(&io_request_lock);
 			hwif  = HWIF(drive);
-			disable_irq(hwif->irq);
+			disable_irq(hwif->irq);	/* disable_irq_nosync ?? */
 			__cli();	/* local CPU only, as if we were handling an interrupt */
 			if (hwgroup->poll_timeout != 0) {
 				startstop = handler(drive);
@@ -1802,23 +1809,33 @@
 	}
 }
 
-static void ide_init_module (int type)
+static void ide_probe_module (void)
+{
+	if (!ide_probe) {
+#ifdef CONFIG_KMOD
+		(void) request_module("ide-probe-mod");
+#endif /* CONFIG_KMOD */
+	} else {
+		(void) ide_probe->init();
+	}
+	revalidate_drives();
+}
+
+static void ide_driver_module (void)
 {
-	int found = 0;
+	int index;
 	ide_module_t *module = ide_modules;
-	
+
+	for (index = 0; index < MAX_HWIFS; ++index)
+		if (ide_hwifs[index].present)
+			goto search;
+	ide_probe_module();
+search:
 	while (module) {
-		if (module->type == type) {
-			found = 1;
-			(void) module->init();
-		}
+		(void) module->init();
 		module = module->next;
 	}
 	revalidate_drives();
-#ifdef CONFIG_KMOD
-	if (!found && type == IDE_PROBE_MODULE)
-		(void) request_module("ide-probe-mod");
-#endif /* CONFIG_KMOD */
 }
 
 static int ide_open (struct inode * inode, struct file * filp)
@@ -1830,7 +1847,7 @@
 		return -ENXIO;
 	MOD_INC_USE_COUNT;
 	if (drive->driver == NULL)
-		ide_init_module(IDE_DRIVER_MODULE);
+		ide_driver_module();
 #ifdef CONFIG_KMOD
 	if (drive->driver == NULL) {
 		if (drive->media == ide_disk)
@@ -1881,9 +1898,9 @@
 	if (drive->driver != NULL && DRIVER(drive)->cleanup(drive))
 		goto abort;
 	strncpy(drive->driver_req, driver, 9);
-	ide_init_module(IDE_DRIVER_MODULE);
+	ide_driver_module();
 	drive->driver_req[0] = 0;
-	ide_init_module(IDE_DRIVER_MODULE);
+	ide_driver_module();
 	if (DRIVER(drive) && !strcmp(DRIVER(drive)->name, driver))
 		return 0;
 abort:
@@ -1897,6 +1914,35 @@
 };
 #endif
 
+/*
+ * Note that we only release the standard ports,
+ * and do not even try to handle any extra ports
+ * allocated for weird IDE interface chipsets.
+ */
+void hwif_unregister (ide_hwif_t *hwif)
+{
+	if (hwif->io_ports[IDE_DATA_OFFSET])
+		ide_release_region(hwif->io_ports[IDE_DATA_OFFSET], 1);
+	if (hwif->io_ports[IDE_ERROR_OFFSET])
+		ide_release_region(hwif->io_ports[IDE_ERROR_OFFSET], 1);
+	if (hwif->io_ports[IDE_NSECTOR_OFFSET])
+		ide_release_region(hwif->io_ports[IDE_NSECTOR_OFFSET], 1);
+	if (hwif->io_ports[IDE_SECTOR_OFFSET])
+		ide_release_region(hwif->io_ports[IDE_SECTOR_OFFSET], 1);
+	if (hwif->io_ports[IDE_LCYL_OFFSET])
+		ide_release_region(hwif->io_ports[IDE_LCYL_OFFSET], 1);
+	if (hwif->io_ports[IDE_HCYL_OFFSET])
+		ide_release_region(hwif->io_ports[IDE_HCYL_OFFSET], 1);
+	if (hwif->io_ports[IDE_SELECT_OFFSET])
+		ide_release_region(hwif->io_ports[IDE_SELECT_OFFSET], 1);
+	if (hwif->io_ports[IDE_STATUS_OFFSET])
+		ide_release_region(hwif->io_ports[IDE_STATUS_OFFSET], 1);
+	if (hwif->io_ports[IDE_CONTROL_OFFSET])
+		ide_release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
+	if (hwif->io_ports[IDE_IRQ_OFFSET])
+		ide_release_region(hwif->io_ports[IDE_IRQ_OFFSET], 1);
+}
+
 void ide_unregister (unsigned int index)
 {
 	struct gendisk *gd, **gdp;
@@ -1967,9 +2013,7 @@
 	 * and do not even try to handle any extra ports
 	 * allocated for weird IDE interface chipsets.
 	 */
-	ide_release_region(hwif->io_ports[IDE_DATA_OFFSET], 8);
-	if (hwif->io_ports[IDE_CONTROL_OFFSET])
-		ide_release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
+	hwif_unregister(hwif);
 
 	/*
 	 * Remove us from the hwgroup, and free
@@ -2036,23 +2080,28 @@
 			kfree (gd->flags);
 		kfree(gd);
 	}
-	old_hwif = *hwif;
+	old_hwif		= *hwif;
 	init_hwif_data (index);	/* restore hwif data to pristine status */
-	hwif->hwgroup = old_hwif.hwgroup;
-	hwif->tuneproc = old_hwif.tuneproc;
-	hwif->resetproc = old_hwif.resetproc;
-	hwif->dmaproc = old_hwif.dmaproc;
-	hwif->dma_base = old_hwif.dma_base;
-	hwif->dma_extra = old_hwif.dma_extra;
-	hwif->config_data = old_hwif.config_data;
-	hwif->select_data = old_hwif.select_data;
-	hwif->irq = old_hwif.irq;
-	hwif->major = old_hwif.major;
-	hwif->proc = old_hwif.proc;
-	hwif->udma_four = old_hwif.udma_four;
-	hwif->chipset = old_hwif.chipset;
-	hwif->pci_dev = old_hwif.pci_dev;
-	hwif->pci_devid = old_hwif.pci_devid;
+	hwif->hwgroup		= old_hwif.hwgroup;
+	hwif->tuneproc		= old_hwif.tuneproc;
+	hwif->selectproc	= old_hwif.selectproc;
+	hwif->resetproc		= old_hwif.resetproc;
+	hwif->dmaproc		= old_hwif.dmaproc;
+	hwif->dma_base		= old_hwif.dma_base;
+	hwif->dma_extra		= old_hwif.dma_extra;
+	hwif->config_data	= old_hwif.config_data;
+	hwif->select_data	= old_hwif.select_data;
+	hwif->proc		= old_hwif.proc;
+	hwif->irq		= old_hwif.irq;
+	hwif->major		= old_hwif.major;
+	hwif->chipset		= old_hwif.chipset;
+	hwif->autodma		= old_hwif.autodma;
+	hwif->udma_four		= old_hwif.udma_four;
+#ifdef CONFIG_BLK_DEV_IDEPCI
+	hwif->pci_dev		= old_hwif.pci_dev;
+	hwif->pci_devid		= old_hwif.pci_devid;
+#endif /* CONFIG_BLK_DEV_IDEPCI */
+
 abort:
 	restore_flags(flags);	/* all CPUs */
 }
@@ -2087,6 +2136,7 @@
 		}
 	}
 	hw->irq = irq;
+	hw->dma = NO_DMA;
 	hw->ack_intr = ack_intr;
 }
 
@@ -2126,11 +2176,11 @@
 	hwif->noprobe = 0;
 
 	if (!initializing) {
-		ide_init_module(IDE_PROBE_MODULE);
+		ide_probe_module();
 #ifdef CONFIG_PROC_FS
 		create_proc_ide_interfaces();
 #endif
-		ide_init_module(IDE_DRIVER_MODULE);
+		ide_driver_module();
 	}
 
 	if (hwifp)
@@ -2750,7 +2800,7 @@
 	if (!strcmp(s, "ide=doubler")) {
 		extern int ide_doubler;
 
-		printk("ide: Enabled support for IDE doublers\n");
+		printk(" : Enabled support for IDE doublers\n");
 		ide_doubler = 1;
 		return 0;
 	}
@@ -2759,12 +2809,14 @@
 #ifdef CONFIG_BLK_DEV_IDEPCI
 	if (!strcmp(s, "ide=reverse")) {
 		ide_scan_direction = 1;
-		printk("ide: Enabled support for IDE inverse scan order.\n");
+		printk(" : Enabled support for IDE inverse scan order.\n");
 		return 0;
 	}
 #endif /* CONFIG_BLK_DEV_IDEPCI */
 
+#ifndef CONFIG_BLK_DEV_IDEPCI
 	init_ide_data ();
+#endif /* CONFIG_BLK_DEV_IDEPCI */
 
 	/*
 	 * Look for drive options:  "hdx="
@@ -3176,7 +3228,7 @@
 #if defined(__mc68000__) || defined(CONFIG_APUS)
 	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
 		ide_get_lock(&ide_lock, NULL, NULL);	/* for atari only */
-		disable_irq(ide_hwifs[0].irq);
+		disable_irq(ide_hwifs[0].irq);	/* disable_irq_nosync ?? */
 	}
 #endif /* __mc68000__ || CONFIG_APUS */
 
@@ -3293,10 +3345,6 @@
 {
 	unsigned int unit, index, i;
 
-	for (index = 0; index < MAX_HWIFS; ++index)
-		if (ide_hwifs[index].present) goto search;
-	ide_init_module(IDE_PROBE_MODULE);
-search:
 	for (index = 0, i = 0; index < MAX_HWIFS; ++index) {
 		ide_hwif_t *hwif = &ide_hwifs[index];
 		if (!hwif->present)
@@ -3327,8 +3375,16 @@
 	setup_driver_defaults(drive);
 	restore_flags(flags);		/* all CPUs */
 	if (drive->autotune != 2) {
-		if (driver->supports_dma && HWIF(drive)->dmaproc != NULL)
+		if (driver->supports_dma && HWIF(drive)->dmaproc != NULL) {
+			/*
+			 * Force DMAing for the beginning of the check.
+			 * Some chipsets appear to do interesting things,
+			 * if not checked and cleared.
+			 *   PARANOIA!!!
+			 */
+			(void) (HWIF(drive)->dmaproc(ide_dma_off_quietly, drive));
 			(void) (HWIF(drive)->dmaproc(ide_dma_check, drive));
+		}
 		drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap);
 		drive->nice1 = 1;
 	}
@@ -3400,6 +3456,7 @@
 /*
  * Probe module
  */
+EXPORT_SYMBOL(ide_probe);
 EXPORT_SYMBOL(drive_is_flashcard);
 EXPORT_SYMBOL(ide_timer_expiry);
 EXPORT_SYMBOL(ide_intr);
@@ -3474,7 +3531,7 @@
 EXPORT_SYMBOL(ide_register);
 EXPORT_SYMBOL(ide_unregister);
 EXPORT_SYMBOL(ide_setup_ports);
-
+EXPORT_SYMBOL(hwif_unregister);
 EXPORT_SYMBOL(get_info_ptr);
 EXPORT_SYMBOL(current_capacity);
 
@@ -3539,13 +3596,9 @@
 {
 	int index;
 
-	for (index = 0; index < MAX_HWIFS; ++index) {
+	for (index = 0; index < MAX_HWIFS; ++index)
 		ide_unregister(index);
-#ifdef CONFIG_BLK_DEV_IDEDMA
-		if (ide_hwifs[index].dma_base)
-			(void) ide_release_dma(&ide_hwifs[index]);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-	}
+
 #ifdef CONFIG_PROC_FS
 	proc_ide_destroy();
 #endif
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ide_modes.h linux/drivers/block/ide_modes.h
--- v2.3.47/linux/drivers/block/ide_modes.h	Wed Aug 18 16:43:30 1999
+++ linux/drivers/block/ide_modes.h	Sat Feb 26 20:46:00 2000
@@ -1,10 +1,11 @@
-#ifndef _IDE_MODES_H
-#define _IDE_MODES_H
 /*
  *  linux/drivers/block/ide_modes.h
  *
  *  Copyright (C) 1996  Linus Torvalds, Igor Abramov, and Mark Lord
  */
+
+#ifndef _IDE_MODES_H
+#define _IDE_MODES_H
 
 #include <linux/config.h>
 
diff -u --recursive --new-file v2.3.47/linux/drivers/block/linear.c linux/drivers/block/linear.c
--- v2.3.47/linux/drivers/block/linear.c	Thu Feb 10 17:11:07 2000
+++ linux/drivers/block/linear.c	Wed Feb 23 09:13:52 2000
@@ -121,14 +121,15 @@
 	return 0;
 }
 
-static int linear_make_request (mddev_t *mddev, int rw, struct buffer_head * bh)
+static int linear_make_request (request_queue_t *q, mddev_t *mddev,
+			int rw, struct buffer_head * bh)
 {
         linear_conf_t *conf = mddev_to_conf(mddev);
         struct linear_hash *hash;
         dev_info_t *tmp_dev;
         long block;
 
-	block = bh->b_blocknr * (bh->b_size >> 10);
+	block = bh->b_rsector >> 1;
 	hash = conf->hash_table + (block / conf->smallest->size);
   
 	if (block >= (hash->dev0->size + hash->dev0->offset)) {
@@ -149,8 +150,7 @@
 	bh->b_rdev = tmp_dev->dev;
 	bh->b_rsector = (block - tmp_dev->offset) << 1;
 
-	generic_make_request(rw, bh);
-	return 0;
+	return 1;
 }
 
 static int linear_status (char *page, mddev_t *mddev)
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v2.3.47/linux/drivers/block/ll_rw_blk.c	Sun Feb 20 21:12:38 2000
+++ linux/drivers/block/ll_rw_blk.c	Fri Feb 25 10:28:13 2000
@@ -952,96 +952,122 @@
 	bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
 }
 
-void generic_make_request(int rw, struct buffer_head * bh)
+static inline void buffer_IO_error(struct buffer_head * bh)
 {
-	request_queue_t * q;
-	unsigned long flags;
+	mark_buffer_clean(bh);
+	/*
+	 * b_end_io has to clear the BH_Uptodate bitflag in the error case!
+	 */
+	bh->b_end_io(bh, 0);
+}
 
-	q = blk_get_queue(bh->b_rdev);
+int generic_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
+{
+	unsigned long flags;
+	int ret;
 
+	/*
+	 * Resolve the mapping until finished. (drivers are
+	 * still free to implement/resolve their own stacking
+	 * by explicitly returning 0)
+	 */
+
+	while (q->make_request_fn) {
+		ret = q->make_request_fn(q, rw, bh);
+		if (ret > 0) {
+			q = blk_get_queue(bh->b_rdev);
+			continue;
+		}
+		return ret;
+	}
+	/*
+	 * Does the block device want us to queue
+	 * the IO request? (normal case)
+	 */
 	__make_request(q, rw, bh);
-
 	spin_lock_irqsave(&io_request_lock,flags);
 	if (q && !q->plugged)
 		(q->request_fn)(q);
 	spin_unlock_irqrestore(&io_request_lock,flags);
-}
 
+	return 0;
+}
 
 /* This function can be used to request a number of buffers from a block
    device. Currently the only restriction is that all buffers must belong to
    the same device */
 
-static void __ll_rw_block(int rw, int nr, struct buffer_head * bh[],int haslock)
+static void __ll_rw_block(int rw, int nr, struct buffer_head * bhs[],
+								int haslock)
 {
+	struct buffer_head *bh;
+	request_queue_t *q;
 	unsigned int major;
 	int correct_size;
-	request_queue_t *q;
 	int i;
 
-	major = MAJOR(bh[0]->b_dev);
-	q = blk_get_queue(bh[0]->b_dev);
+	major = MAJOR(bhs[0]->b_dev);
+	q = blk_get_queue(bhs[0]->b_dev);
 	if (!q) {
 		printk(KERN_ERR
 	"ll_rw_block: Trying to read nonexistent block-device %s (%ld)\n",
-		kdevname(bh[0]->b_dev), bh[0]->b_blocknr);
+		kdevname(bhs[0]->b_dev), bhs[0]->b_blocknr);
 		goto sorry;
 	}
 
 	/* Determine correct block size for this device. */
 	correct_size = BLOCK_SIZE;
 	if (blksize_size[major]) {
-		i = blksize_size[major][MINOR(bh[0]->b_dev)];
+		i = blksize_size[major][MINOR(bhs[0]->b_dev)];
 		if (i)
 			correct_size = i;
 	}
 
 	/* Verify requested block sizes. */
 	for (i = 0; i < nr; i++) {
-		if (bh[i]->b_size != correct_size) {
+		bh = bhs[i];
+		if (bh->b_size != correct_size) {
 			printk(KERN_NOTICE "ll_rw_block: device %s: "
 			       "only %d-char blocks implemented (%u)\n",
-			       kdevname(bh[0]->b_dev),
-			       correct_size, bh[i]->b_size);
+			       kdevname(bhs[0]->b_dev),
+			       correct_size, bh->b_size);
 			goto sorry;
 		}
 	}
 
-	if ((rw & WRITE) && is_read_only(bh[0]->b_dev)) {
+	if ((rw & WRITE) && is_read_only(bhs[0]->b_dev)) {
 		printk(KERN_NOTICE "Can't write to read-only device %s\n",
-		       kdevname(bh[0]->b_dev));
+		       kdevname(bhs[0]->b_dev));
 		goto sorry;
 	}
 
 	for (i = 0; i < nr; i++) {
+		bh = bhs[i];
+
 		/* Only one thread can actually submit the I/O. */
 		if (haslock) {
-			if (!buffer_locked(bh[i]))
+			if (!buffer_locked(bh))
 				BUG();
 		} else {
-			if (test_and_set_bit(BH_Lock, &bh[i]->b_state))
+			if (test_and_set_bit(BH_Lock, &bh->b_state))
 				continue;
 		}
-		set_bit(BH_Req, &bh[i]->b_state);
+		set_bit(BH_Req, &bh->b_state);
 
-		if (q->make_request_fn)
-			q->make_request_fn(rw, bh[i]);
-		else {
-			bh[i]->b_rdev = bh[i]->b_dev;
-			bh[i]->b_rsector = bh[i]->b_blocknr*(bh[i]->b_size>>9);
+		/*
+		 * First step, 'identity mapping' - RAID or LVM might
+		 * further remap this.
+		 */
+		bh->b_rdev = bh->b_dev;
+		bh->b_rsector = bh->b_blocknr * (bh->b_size>>9);
 
-			generic_make_request(rw, bh[i]);
-		}
+		generic_make_request(q, rw, bh);
 	}
-
 	return;
 
 sorry:
-	for (i = 0; i < nr; i++) {
-		mark_buffer_clean(bh[i]); /* remeber to refile it */
-		clear_bit(BH_Uptodate, &bh[i]->b_state);
-		bh[i]->b_end_io(bh[i], 0);
-	}
+	for (i = 0; i < nr; i++)
+		buffer_IO_error(bhs[i]);
 	return;
 }
 
@@ -1176,9 +1202,8 @@
 #ifdef CONFIG_BLK_DEV_FD
 	floppy_init();
 #else
-#if !defined (__mc68000__) && !defined(CONFIG_PPC) && !defined(__sparc__)\
-    && !defined(CONFIG_APUS) && !defined(__sh__) && !defined(__ia64__)
-	outb_p(0xc, 0x3f2);	/* XXX do something with the floppy controller?? */
+#if defined(__i386__)	/* Do we even need this? */
+	outb_p(0xc, 0x3f2);
 #endif
 #endif
 #ifdef CONFIG_CDU31A
diff -u --recursive --new-file v2.3.47/linux/drivers/block/lvm.c linux/drivers/block/lvm.c
--- v2.3.47/linux/drivers/block/lvm.c	Sun Feb 20 21:12:38 2000
+++ linux/drivers/block/lvm.c	Wed Feb 23 09:13:52 2000
@@ -192,7 +192,7 @@
 static void lvm_dummy_device_request(request_queue_t *);
 #define	DEVICE_REQUEST	lvm_dummy_device_request
 
-static void lvm_make_request_fn(int, struct buffer_head*);
+static int lvm_make_request_fn(request_queue_t *, int, struct buffer_head*);
 
 static int lvm_blk_ioctl(struct inode *, struct file *, uint, ulong);
 static int lvm_blk_open(struct inode *, struct file *);
@@ -1292,14 +1292,14 @@
  */
 static int lvm_map(struct buffer_head *bh, int rw)
 {
-	int minor = MINOR(bh->b_dev);
+	int minor = MINOR(bh->b_rdev);
 	int ret = 0;
 	ulong index;
 	ulong pe_start;
 	ulong size = bh->b_size >> 9;
-	ulong rsector_tmp = bh->b_blocknr * size;
+	ulong rsector_tmp = bh->b_rsector;
 	ulong rsector_sav;
-	kdev_t rdev_tmp = bh->b_dev;
+	kdev_t rdev_tmp = bh->b_rdev;
 	kdev_t rdev_sav;
 	lv_t *lv = vg[VG_BLK(minor)]->lv[LV_BLK(minor)];
 
@@ -1513,11 +1513,10 @@
 /*
  * make request function
  */
-static void lvm_make_request_fn(int rw, struct buffer_head *bh)
+static int lvm_make_request_fn(request_queue_t *q, int rw, struct buffer_head *bh)
 {
 	lvm_map(bh, rw);
-	if (bh->b_rdev != MD_MAJOR) generic_make_request(rw, bh); 
-	return;
+	return 1;
 }
 
 
diff -u --recursive --new-file v2.3.47/linux/drivers/block/macide.c linux/drivers/block/macide.c
--- v2.3.47/linux/drivers/block/macide.c	Tue Sep  7 12:14:06 1999
+++ linux/drivers/block/macide.c	Sat Feb 26 20:32:14 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/macide.c -- Macintosh IDE Driver
+ *  linux/drivers/ide/macide.c -- Macintosh IDE Driver
  *
  *     Copyright (C) 1998 by Michael Schmitz
  *
@@ -43,7 +43,7 @@
 #define MAC_HD_STATUS	0x1c		/* see status-bits */
 #define MAC_HD_CONTROL	0x38		/* control/altstatus */
 
-static int macide_offsets[IDE_NR_PORTS] = {
+static int __init macide_offsets[IDE_NR_PORTS] = {
     MAC_HD_DATA, MAC_HD_ERROR, MAC_HD_NSECTOR, MAC_HD_SECTOR, MAC_HD_LCYL,
     MAC_HD_HCYL, MAC_HD_SELECT, MAC_HD_STATUS, MAC_HD_CONTROL
 };
@@ -84,7 +84,7 @@
      *  Probe for a Macintosh IDE interface
      */
 
-void macide_init(void)
+void __init macide_init(void)
 {
 	hw_regs_t hw;
 	int index = -1;
diff -u --recursive --new-file v2.3.47/linux/drivers/block/md.c linux/drivers/block/md.c
--- v2.3.47/linux/drivers/block/md.c	Sun Feb 20 21:12:38 2000
+++ linux/drivers/block/md.c	Wed Feb 23 09:13:52 2000
@@ -75,16 +75,16 @@
 
 static struct gendisk md_gendisk=
 {
-	MD_MAJOR,
-	"md",
-	0,
-	1,
-	md_hd_struct,
-	md_size,
-	MAX_MD_DEVS,
-	NULL,
-	NULL,
-	&md_fops,
+	major: MD_MAJOR,
+	major_name: "md",
+	minor_shift: 0,
+	max_p: 1,
+	part: md_hd_struct,
+	sizes: md_size,
+	nr_real: MAX_MD_DEVS,
+	real_devices: NULL,
+	next: NULL,
+	fops: &md_fops,
 };
 
 void md_plug_device (request_queue_t *mdqueue, kdev_t dev)
@@ -178,17 +178,16 @@
 	return;
 }
 
-void md_make_request (int rw, struct buffer_head * bh)
+static int md_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
 {
-	mddev_t *mddev = kdev_to_mddev(bh->b_dev);
+	mddev_t *mddev = kdev_to_mddev(bh->b_rdev);
 
-	if (!mddev || !mddev->pers)
-		bh->b_end_io(bh, 0);
+	if (mddev && mddev->pers)
+		return mddev->pers->make_request(q, mddev, rw, bh);
 	else {
-		if ((rw == READ || rw == READA) && buffer_uptodate(bh))
-			bh->b_end_io(bh, 1);
-		else
-			mddev->pers->make_request(mddev, rw, bh);
+		mark_buffer_clean(bh);
+		bh->b_end_io(bh, 0);
+		return -1;
 	}
 }
 
@@ -234,28 +233,6 @@
 	return mddev;
 }
 
-static void free_mddev (mddev_t *mddev)
-{
-	if (!mddev) {
-		MD_BUG();
-		return;
-	}
-
-	/*
-	 * Make sure nobody else is using this mddev
-	 * (careful, we rely on the global kernel lock here)
-	 */
-	while (md_atomic_read(&mddev->resync_sem.count) != 1)
-		schedule();
-	while (md_atomic_read(&mddev->recovery_sem.count) != 1)
-		schedule();
-
-	del_mddev_mapping(mddev, MKDEV(MD_MAJOR, mdidx(mddev)));
-	md_list_del(&mddev->all_mddevs);
-	MD_INIT_LIST_HEAD(&mddev->all_mddevs);
-	kfree(mddev);
-}
-
 struct gendisk * find_gendisk (kdev_t dev)
 {
 	struct gendisk *tmp = gendisk_head;
@@ -757,6 +734,32 @@
 		MD_BUG();
 }
 
+static void free_mddev (mddev_t *mddev)
+{
+	if (!mddev) {
+		MD_BUG();
+		return;
+	}
+
+	export_array(mddev);
+	md_size[mdidx(mddev)] = 0;
+	md_hd_struct[mdidx(mddev)].nr_sects = 0;
+
+	/*
+	 * Make sure nobody else is using this mddev
+	 * (careful, we rely on the global kernel lock here)
+	 */
+	while (md_atomic_read(&mddev->resync_sem.count) != 1)
+		schedule();
+	while (md_atomic_read(&mddev->recovery_sem.count) != 1)
+		schedule();
+
+	del_mddev_mapping(mddev, MKDEV(MD_MAJOR, mdidx(mddev)));
+	md_list_del(&mddev->all_mddevs);
+	MD_INIT_LIST_HEAD(&mddev->all_mddevs);
+	kfree(mddev);
+}
+
 #undef BAD_CSUM
 #undef BAD_MAGIC
 #undef OUT_OF_MEM
@@ -1723,13 +1726,7 @@
 		printk (STILL_MOUNTED, mdidx(mddev));
 		OUT(-EBUSY);
 	}
-  
-	/*
-	 * complain if it's already stopped
-	 */
-	if (!mddev->nb_dev)
-		OUT(-ENXIO);
-
+ 
 	if (mddev->pers) {
 		/*
 		 * It is safe to call stop here, it only frees private
@@ -1796,9 +1793,6 @@
 	 * Free resources if final stop
 	 */
 	if (!ro) {
-		export_array(mddev);
-		md_size[mdidx(mddev)] = 0;
-		md_hd_struct[mdidx(mddev)].nr_sects = 0;
 		free_mddev(mddev);
 
 		printk (KERN_INFO "md%d stopped.\n", mdidx(mddev));
@@ -3279,15 +3273,15 @@
 {
 	int i;
 
-	blksize_size[MD_MAJOR] = md_blocksizes;
-	max_readahead[MD_MAJOR] = md_maxreadahead;
-
 	for(i = 0; i < MAX_MD_DEVS; i++) {
 		md_blocksizes[i] = 1024;
+		md_size[i] = 0;
 		md_maxreadahead[i] = MD_READAHEAD;
 		register_disk(&md_gendisk, MKDEV(MAJOR_NR,i), 1, &md_fops, 0);
-
 	}
+	blksize_size[MD_MAJOR] = md_blocksizes;
+	blk_size[MAJOR_NR] = md_size;
+	max_readahead[MD_MAJOR] = md_maxreadahead;
 
 	printk("md.c: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t));
 
diff -u --recursive --new-file v2.3.47/linux/drivers/block/ns87415.c linux/drivers/block/ns87415.c
--- v2.3.47/linux/drivers/block/ns87415.c	Fri Jan 28 15:09:07 2000
+++ linux/drivers/block/ns87415.c	Sat Feb 26 20:32:14 2000
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/block/ns87415.c	Version 1.00  December 7, 1997
+ * linux/drivers/block/ns87415.c		Version 1.00  December 7, 1997
  *
  * Copyright (C) 1997-1998  Mark Lord
  * Copyright (C) 1998       Eddie C. Dost  (ecd@skynet.be)
diff -u --recursive --new-file v2.3.47/linux/drivers/block/opti621.c linux/drivers/block/opti621.c
--- v2.3.47/linux/drivers/block/opti621.c	Thu May 13 11:04:54 1999
+++ linux/drivers/block/opti621.c	Sat Feb 26 20:32:14 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/opti621.c       Version 0.6  Jan 02, 1999
+ *  linux/drivers/block/opti621.c		Version 0.6	Jan 02, 1999
  *
  *  Copyright (C) 1996-1998  Linus Torvalds & authors (see below)
  */
diff -u --recursive --new-file v2.3.47/linux/drivers/block/pdc202xx.c linux/drivers/block/pdc202xx.c
--- v2.3.47/linux/drivers/block/pdc202xx.c	Fri Jan 21 18:19:16 2000
+++ linux/drivers/block/pdc202xx.c	Sat Feb 26 20:32:14 2000
@@ -1,7 +1,7 @@
 /*
- *  linux/drivers/block/pdc202xx.c	Version 0.28	Dec. 13, 1999
+ *  linux/drivers/block/pdc202xx.c	Version 0.29	Feb. 10, 2000
  *
- *  Copyright (C) 1998-99	Andre Hedrick (andre@suse.com)
+ *  Copyright (C) 1998-2000	Andre Hedrick (andre@suse.com)
  *  May be copied or modified under the terms of the GNU General Public License
  *
  *  Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this
@@ -14,7 +14,7 @@
  *  8 are UDMA supported and 4 are limited to DMA mode 2 multi-word.
  *  The 8/4 ratio is a BIOS code limit by promise.
  *
- *  UNLESS you enable "CONFIG_PDC202XX_FORCE_BURST_BIT"
+ *  UNLESS you enable "CONFIG_PDC202XX_BURST"
  *
  *  There is only one BIOS in the three contollers.
  *
@@ -100,6 +100,61 @@
 #define PDC202XX_DEBUG_DRIVE_INFO		0
 #define PDC202XX_DECODE_REGISTER_INFO		0
 
+#define DISPLAY_PDC202XX_TIMINGS
+#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static int pdc202xx_get_info(char *, char **, off_t, int);
+extern int (*pdc202xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+extern char *ide_media_verbose(ide_drive_t *);
+static struct pci_dev *bmide_dev;
+
+static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count)
+{
+	char *p = buffer;
+
+	u32 bibma = bmide_dev->resource[4].start;
+	u8 c0 = 0, c1 = 0;
+
+        /*
+         * at that point bibma+0x2 et bibma+0xa are byte registers
+         * to investigate:
+         */
+	c0 = inb_p((unsigned short)bibma + 0x02);
+	c1 = inb_p((unsigned short)bibma + 0x0a);
+
+	switch(bmide_dev->device) {	
+		case PCI_DEVICE_ID_PROMISE_20262:
+			p += sprintf(p, "\n                                PDC20262 Chipset.\n");
+			break;
+		case PCI_DEVICE_ID_PROMISE_20246:
+			p += sprintf(p, "\n                                PDC20246 Chipset.\n");
+			break;
+		default:
+			p += sprintf(p, "\n                                PDC202XX Chipset.\n");
+			break;
+	}
+
+	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+	p += sprintf(p, "                %sabled                         %sabled\n",
+			(c0&0x80) ? "dis" : " en",
+			(c1&0x80) ? "dis" : " en");
+	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
+	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
+			(c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
+			(c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
+
+	p += sprintf(p, "UDMA\n");
+	p += sprintf(p, "DMA\n");
+	p += sprintf(p, "PIO\n");
+
+	return p-buffer;	/* => must be less than 4k! */
+}
+#endif  /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+byte pdc202xx_proc = 0;
+
 extern char *ide_xfer_verbose (byte xfer_rate);
 
 /* A Register */
@@ -620,15 +675,15 @@
 		(primary_mode & 1) ? "MASTER" : "PCI",
 		(secondary_mode & 1) ? "MASTER" : "PCI" );
 
-#ifdef CONFIG_PDC202XX_FORCE_BURST_BIT
+#ifdef CONFIG_PDC202XX_BURST
 	if (!(udma_speed_flag & 1)) {
 		printk("%s: FORCING BURST BIT 0x%02x -> 0x%02x ", name, udma_speed_flag, (udma_speed_flag|1));
 		outb(udma_speed_flag|1, high_16 + 0x001f);
 		printk("%sCTIVE\n", (inb(high_16 + 0x001f) & 1) ? "A" : "INA");
 	}
-#endif /* CONFIG_PDC202XX_FORCE_BURST_BIT */
+#endif /* CONFIG_PDC202XX_BURST */
 
-#ifdef CONFIG_PDC202XX_FORCE_MASTER_MODE
+#ifdef CONFIG_PDC202XX_MASTER
 	if (!(primary_mode & 1)) {
 		printk("%s: FORCING PRIMARY MODE BIT 0x%02x -> 0x%02x ",
 			name, primary_mode, (primary_mode|1));
@@ -642,7 +697,14 @@
 		outb(secondary_mode|1, high_16 + 0x001b);
 		printk("%s\n", (inb(high_16 + 0x001b) & 1) ? "MASTER" : "PCI");
 	}
-#endif /* CONFIG_PDC202XX_FORCE_MASTER_MODE */
+#endif /* CONFIG_PDC202XX_MASTER */
+
+#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
+        pdc202xx_proc = 1;
+        bmide_dev = dev;
+        pdc202xx_display_info = &pdc202xx_get_info;
+#endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */
+
 	return dev->irq;
 }
 
diff -u --recursive --new-file v2.3.47/linux/drivers/block/pdc4030.c linux/drivers/block/pdc4030.c
--- v2.3.47/linux/drivers/block/pdc4030.c	Thu Nov 18 20:25:37 1999
+++ linux/drivers/block/pdc4030.c	Sat Feb 26 20:32:14 2000
@@ -1,5 +1,5 @@
 /*  -*- linux-c -*-
- *  linux/drivers/block/pdc4030.c	Version 0.90  May 27, 1999
+ *  linux/drivers/ide/pdc4030.c		Version 0.90  May 27, 1999
  *
  *  Copyright (C) 1995-1999  Linus Torvalds & authors (see below)
  */
diff -u --recursive --new-file v2.3.47/linux/drivers/block/pdc4030.h linux/drivers/block/pdc4030.h
--- v2.3.47/linux/drivers/block/pdc4030.h	Sun Nov 30 13:48:47 1997
+++ linux/drivers/block/pdc4030.h	Sat Feb 26 20:32:14 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/pdc4030.h
+ *  linux/drivers/ide/pdc4030.h
  *
  *  Copyright (C) 1995-1998  Linus Torvalds & authors
  */
diff -u --recursive --new-file v2.3.47/linux/drivers/block/piix.c linux/drivers/block/piix.c
--- v2.3.47/linux/drivers/block/piix.c	Fri Jan 28 15:09:07 2000
+++ linux/drivers/block/piix.c	Sat Feb 26 20:32:14 2000
@@ -1,8 +1,8 @@
 /*
- * linux/drivers/block/piix.c	Version 0.28	Dec. 13, 1999
+ * linux/drivers/block/piix.c		Version 0.30	Feb. 26, 2000
  *
  *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
- *  Copyright (C) 1998-1999 Andre Hedrick (andre@suse.com)
+ *  Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com)
  *  May be copied or modified under the terms of the GNU General Public License
  *
  *  PIO mode setting function for Intel chipsets.  
@@ -49,13 +49,33 @@
  * pci_read_config_word(HWIF(drive)->pci_dev, 0x44, &reg44);
  * pci_read_config_word(HWIF(drive)->pci_dev, 0x48, &reg48);
  * pci_read_config_word(HWIF(drive)->pci_dev, 0x4a, &reg4a);
+ * pci_read_config_word(HWIF(drive)->pci_dev, 0x54, &reg54);
+ *
+ * 00:1f.1 IDE interface: Intel Corporation:
+ *                          Unknown device 2411 (rev 01) (prog-if 80 [Master])
+ *         Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop-
+ *                          ParErr- Stepping- SERR- FastB2B-
+ *         Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-
+ *                          <TAbort- <MAbort- >SERR- <PERR-
+ *         Latency: 0 set
+ *         Region 4: I/O ports at ffa0
+ * 00: 86 80 11 24 05 00 80 02 01 80 01 01 00 00 00 00
+ * 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 20: a1 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 40: 07 a3 03 a3 00 00 00 00 05 00 02 02 00 00 00 00
+ * 50: 00 00 00 00 11 04 00 00 00 00 00 00 00 00 00 00
+ * 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * f0: 00 00 00 00 00 00 00 00 3a 0f 00 00 00 00 00 00
  *
- * #if 0
- * int err;
- * err = ide_config_drive_speed(drive, speed);
- * (void) ide_config_drive_speed(drive, speed);
- * #else
- * #endif
  */
 
 #include <linux/config.h>
@@ -86,16 +106,88 @@
 
 static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
 {
-	/* int rc; */
-	int piix_who = ((bmide_dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) ||
-			(bmide_dev->device == PCI_DEVICE_ID_INTEL_82801AB_1) ||
-			(bmide_dev->device == PCI_DEVICE_ID_INTEL_82371AB)) ? 4 : 3;
 	char *p = buffer;
-	p += sprintf(p, "\n                                Intel PIIX%d Chipset.\n", piix_who);
-	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n\n");
+	u32 bibma = bmide_dev->resource[4].start;
+        u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0;
+	u8  c0 = 0, c1 = 0;
+	u8  reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0, reg54 = 0;
+
+	pci_read_config_word(bmide_dev, 0x40, &reg40);
+	pci_read_config_word(bmide_dev, 0x42, &reg42);
+	pci_read_config_byte(bmide_dev, 0x44, &reg44);
+	pci_read_config_byte(bmide_dev, 0x48, &reg48);
+	pci_read_config_byte(bmide_dev, 0x4a, &reg4a);
+	pci_read_config_byte(bmide_dev, 0x4b, &reg4b);
+	pci_read_config_byte(bmide_dev, 0x54, &reg54);
+
+	psitre = (reg40 & 0x4000) ? 1 : 0;
+	ssitre = (reg42 & 0x4000) ? 1 : 0;
+
+        /*
+         * at that point bibma+0x2 et bibma+0xa are byte registers
+         * to investigate:
+         */
+	c0 = inb_p((unsigned short)bibma + 0x02);
+	c1 = inb_p((unsigned short)bibma + 0x0a);
+
+	switch(bmide_dev->device) {
+		case PCI_DEVICE_ID_INTEL_82372FB_1:
+		case PCI_DEVICE_ID_INTEL_82801AA_1:
+			p += sprintf(p, "\n                                Intel PIIX4 Ultra 66 Chipset.\n");
+			break;
+		case PCI_DEVICE_ID_INTEL_82801AB_1:
+		case PCI_DEVICE_ID_INTEL_82371AB:
+			p += sprintf(p, "\n                                Intel PIIX4 Ultra 33 Chipset.\n");
+			break;
+		case PCI_DEVICE_ID_INTEL_82371SB_1:
+			p += sprintf(p, "\n                                Intel PIIX3 Chipset.\n");
+			break;
+		case PCI_DEVICE_ID_INTEL_82371FB_1:
+		case PCI_DEVICE_ID_INTEL_82371FB_0:
+		default:
+			p += sprintf(p, "\n                                Intel PIIX Chipset.\n");
+			break;
+	}
+	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+	p += sprintf(p, "                %sabled                         %sabled\n",
+			(c0&0x80) ? "dis" : " en",
+			(c1&0x80) ? "dis" : " en");
 	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
-	p += sprintf(p, "\n");
-	p += sprintf(p, "\n");
+	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
+			(c0&0x20) ? "yes" : "no ",
+			(c0&0x40) ? "yes" : "no ",
+			(c1&0x20) ? "yes" : "no ",
+			(c1&0x40) ? "yes" : "no " );
+	p += sprintf(p, "UDMA enabled:   %s              %s             %s               %s\n",
+			(reg48&0x01) ? "yes" : "no ",
+			(reg48&0x02) ? "yes" : "no ",
+			(reg48&0x04) ? "yes" : "no ",
+			(reg48&0x08) ? "yes" : "no " );
+	p += sprintf(p, "UDMA enabled:   %s                %s               %s                 %s\n",
+			((reg54&0x11) && (reg4a&0x02)) ? "4" :
+			((reg54&0x11) && (reg4a&0x01)) ? "3" :
+			(reg4a&0x02) ? "2" :
+			(reg4a&0x01) ? "1" :
+			(reg4a&0x00) ? "0" : "X",
+			((reg54&0x22) && (reg4a&0x20)) ? "4" :
+			((reg54&0x22) && (reg4a&0x10)) ? "3" :
+			(reg4a&0x20) ? "2" :
+			(reg4a&0x10) ? "1" :
+			(reg4a&0x00) ? "0" : "X",
+			((reg54&0x44) && (reg4b&0x02)) ? "4" :
+			((reg54&0x44) && (reg4b&0x01)) ? "3" :
+			(reg4b&0x02) ? "2" :
+			(reg4b&0x01) ? "1" :
+			(reg4b&0x00) ? "0" : "X",
+			((reg54&0x88) && (reg4b&0x20)) ? "4" :
+			((reg54&0x88) && (reg4b&0x10)) ? "3" :
+			(reg4b&0x20) ? "2" :
+			(reg4b&0x10) ? "1" :
+			(reg4b&0x00) ? "0" : "X");
+
+	p += sprintf(p, "UDMA\n");
+	p += sprintf(p, "DMA\n");
+	p += sprintf(p, "PIO\n");
 
 /*
  *	FIXME.... Add configuration junk data....blah blah......
@@ -113,7 +205,6 @@
 
 extern char *ide_xfer_verbose (byte xfer_rate);
 
-#ifdef CONFIG_BLK_DEV_PIIX_TUNING
 /*
  *
  */
@@ -143,7 +234,6 @@
 			return 0;
 	}
 }
-#endif /* CONFIG_BLK_DEV_PIIX_TUNING */
 
 /*
  *  Based on settings done by AMI BIOS
@@ -191,8 +281,6 @@
 	restore_flags(flags);
 }
 
-#ifdef CONFIG_BLK_DEV_PIIX_TUNING
-
 static int piix_config_drive_for_dma (ide_drive_t *drive)
 {
 	struct hd_driveid *id	= drive->id;
@@ -205,12 +293,15 @@
 
 	byte maslave		= hwif->channel ? 0x42 : 0x40;
 	byte udma_66		= ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0;
-	int ultra		= ((dev->device == PCI_DEVICE_ID_INTEL_82371AB) ||
+	int ultra66		= ((dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) ||
+				   (dev->device == PCI_DEVICE_ID_INTEL_82372FB_1)) ? 1 : 0;
+	int ultra		= ((ultra66) ||
+				   (dev->device == PCI_DEVICE_ID_INTEL_82371AB) ||
 				   (dev->device == PCI_DEVICE_ID_INTEL_82801AB_1)) ? 1 : 0;
-	int ultra66		= (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) ? 1 : 0; 
 	int drive_number	= ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
 	int a_speed		= 2 << (drive_number * 4);
 	int u_flag		= 1 << drive_number;
+	int v_flag		= 0x10 << drive_number;
 	int u_speed		= 0;
 
 	pci_read_config_word(dev, maslave, &reg4042);
@@ -245,10 +336,6 @@
 		speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
 	}
 
-	/*
-	 * This is !@#$% ugly and stupid.............
-	 * But ugly harware generates ugly code.........
-	 */
 	if (speed >= XFER_UDMA_0) {
 		if (!(reg48 & u_flag))
 			pci_write_config_word(dev, 0x48, reg48|u_flag);
@@ -256,10 +343,12 @@
 			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
 			pci_write_config_word(dev, 0x4a, reg4a|u_speed);
 		}
-		if ((speed > XFER_UDMA_2) && (!(reg54 & u_flag))) {
-			pci_write_config_word(dev, 0x54, reg54|u_flag);
+		if (speed > XFER_UDMA_2) {
+			if (!(reg54 & v_flag)) {
+				pci_write_config_word(dev, 0x54, reg54|v_flag);
+			}
 		} else {
-			pci_write_config_word(dev, 0x54, reg54 & ~u_flag);
+			pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
 		}
 	}
 
@@ -268,8 +357,8 @@
 			pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
 		if (reg4a & a_speed)
 			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
-		if (reg54 & u_flag)
-			pci_write_config_word(dev, 0x54, reg54 & ~u_flag);
+		if (reg54 & v_flag)
+			pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
 	}
 
 	piix_tune_drive(drive, piix_dma_2_pio(speed));
@@ -277,8 +366,7 @@
 	(void) ide_config_drive_speed(drive, speed);
 
 #if PIIX_DEBUG_DRIVE_INFO
-	printk("%s: %s drive%d ", drive->name, ide_xfer_verbose(speed), drive_number);
-	printk("\n");
+	printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive_number);
 #endif /* PIIX_DEBUG_DRIVE_INFO */
 
 	return ((int)	((id->dma_ultra >> 11) & 3) ? ide_dma_on :
@@ -299,16 +387,13 @@
 	/* Other cases are done by generic IDE-DMA code. */
 	return ide_dmaproc(func, drive);
 }
-#endif /* CONFIG_BLK_DEV_PIIX_TUNING */
 
 unsigned int __init pci_init_piix (struct pci_dev *dev, const char *name)
 {
 #if defined(DISPLAY_PIIX_TIMINGS) && defined(CONFIG_PROC_FS)
-	if (!piix_proc) {
-		piix_proc = 1;
-		bmide_dev = dev;
-		piix_display_info = &piix_get_info;
-	}
+	piix_proc = 1;
+	bmide_dev = dev;
+	piix_display_info = &piix_get_info;
 #endif /* DISPLAY_PIIX_TIMINGS && CONFIG_PROC_FS */
 	return 0;
 }
@@ -325,7 +410,7 @@
 
 	pci_read_config_byte(hwif->pci_dev, 0x54, &reg54h);
 	pci_read_config_byte(hwif->pci_dev, 0x55, &reg55h);
-	ata66 = (reg54h & mask) ? 0 : 1;
+	ata66 = (reg54h & mask) ? 1 : 0;
 
 	return ata66;
 }
@@ -335,9 +420,9 @@
 	hwif->tuneproc = &piix_tune_drive;
 
 	if (hwif->dma_base) {
-#ifdef CONFIG_BLK_DEV_PIIX_TUNING
+#ifdef CONFIG_PIIX_TUNING
 		hwif->dmaproc = &piix_dmaproc;
-#endif /* CONFIG_BLK_DEV_PIIX_TUNING */
+#endif /* CONFIG_PIIX_TUNING */
 		hwif->drives[0].autotune = 0;
 		hwif->drives[1].autotune = 0;
 	} else {
diff -u --recursive --new-file v2.3.47/linux/drivers/block/qd6580.c linux/drivers/block/qd6580.c
--- v2.3.47/linux/drivers/block/qd6580.c	Thu May 13 11:04:54 1999
+++ linux/drivers/block/qd6580.c	Sat Feb 26 20:32:14 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/qd6580.c       Version 0.02  Feb 09, 1996
+ *  linux/drivers/block/qd6580.c		Version 0.02	Feb 09, 1996
  *
  *  Copyright (C) 1996  Linus Torvalds & author (see below)
  */
@@ -60,7 +60,7 @@
 	restore_flags(flags);	/* all CPUs */
 }
 
-void init_qd6580 (void)
+void __init init_qd6580 (void)
 {
 	ide_hwifs[0].chipset = ide_qd6580;
 	ide_hwifs[1].chipset = ide_qd6580;
diff -u --recursive --new-file v2.3.47/linux/drivers/block/raid0.c linux/drivers/block/raid0.c
--- v2.3.47/linux/drivers/block/raid0.c	Thu Feb 10 17:11:07 2000
+++ linux/drivers/block/raid0.c	Wed Feb 23 09:13:52 2000
@@ -223,23 +223,23 @@
  * Of course, those facts may not be valid anymore (and surely won't...)
  * Hey guys, there's some work out there ;-)
  */
-static int raid0_make_request (mddev_t *mddev, int rw, struct buffer_head * bh)
+static int raid0_make_request (request_queue_t *q, mddev_t *mddev,
+					int rw, struct buffer_head * bh)
 {
-	unsigned long size = bh->b_size >> 10;
+	int blk_in_chunk, chunksize_bits, chunk, chunk_size;
 	raid0_conf_t *conf = mddev_to_conf(mddev);
 	struct raid0_hash *hash;
 	struct strip_zone *zone;
 	mdk_rdev_t *tmp_dev;
-	int blk_in_chunk, chunksize_bits, chunk, chunk_size;
 	long block, rblock;
 
 	chunk_size = mddev->param.chunk_size >> 10;
 	chunksize_bits = ffz(~chunk_size);
-	block = bh->b_blocknr * size;
+	block = bh->b_rsector >> 1;
 	hash = conf->hash_table + block / conf->smallest->size;
 
 	/* Sanity check */
-	if (chunk_size < (block % chunk_size) + size)
+	if (chunk_size < (block % chunk_size) + (bh->b_size >> 10))
 		goto bad_map;
  
 	if (!hash)
@@ -261,20 +261,19 @@
 	rblock = (chunk << chunksize_bits) + blk_in_chunk + zone->dev_offset;
  
 	/*
-	 * Important, at this point we are not guaranteed to be the only
-	 * CPU modifying b_rdev and b_rsector! Only __make_request() later
-	 * on serializes the IO. So in 2.4 we must never write temporary
-	 * values to bh->b_rdev, like 2.2 and 2.0 did.
+	 * The new BH_Lock semantics in ll_rw_blk.c guarantee that this
+	 * is the only IO operation happening on this bh.
 	 */
 	bh->b_rdev = tmp_dev->dev;
 	bh->b_rsector = rblock << 1;
 
-	generic_make_request(rw, bh);
-
-	return 0;
+	/*
+	 * Let the main block layer submit the IO and resolve recursion:
+	 */
+	return 1;
 
 bad_map:
-	printk ("raid0_make_request bug: can't convert block across chunks or bigger than %dk %ld %ld\n", chunk_size, bh->b_rsector, size);
+	printk ("raid0_make_request bug: can't convert block across chunks or bigger than %dk %ld %d\n", chunk_size, bh->b_rsector, bh->b_size >> 10);
 	return -1;
 bad_hash:
 	printk("raid0_make_request bug: hash==NULL for block %ld\n", block);
diff -u --recursive --new-file v2.3.47/linux/drivers/block/rapide.c linux/drivers/block/rapide.c
--- v2.3.47/linux/drivers/block/rapide.c	Thu Jun 17 01:11:35 1999
+++ linux/drivers/block/rapide.c	Sat Feb 26 20:32:14 2000
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/drivers/block/ide-rapide.c
+ * linux/drivers/block/rapide.c
  *
  * Copyright (c) 1996-1998 Russell King.
  *
@@ -16,7 +16,7 @@
 
 #include <asm/ecard.h>
 
-static const card_ids rapide_cids[] = {
+static const card_ids __init rapide_cids[] = {
 	{ MANU_YELLOWSTONE, PROD_YELLOWSTONE_RAPIDE32 },
 	{ 0xffff, 0xffff }
 };
@@ -43,7 +43,7 @@
 	return ide_register_hw(&hw, NULL);
 }
 
-int rapide_init(void)
+int __init rapide_init(void)
 {
 	int i;
 
diff -u --recursive --new-file v2.3.47/linux/drivers/block/rz1000.c linux/drivers/block/rz1000.c
--- v2.3.47/linux/drivers/block/rz1000.c	Mon Oct  4 15:49:29 1999
+++ linux/drivers/block/rz1000.c	Sat Feb 26 20:32:14 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/rz1000.c	Version 0.05  December 8, 1997
+ *  linux/drivers/block/rz1000.c		Version 0.05	December 8, 1997
  *
  *  Copyright (C) 1995-1998  Linus Torvalds & author (see below)
  */
diff -u --recursive --new-file v2.3.47/linux/drivers/block/sis5513.c linux/drivers/block/sis5513.c
--- v2.3.47/linux/drivers/block/sis5513.c	Fri Jan 21 18:19:16 2000
+++ linux/drivers/block/sis5513.c	Sat Feb 26 20:32:14 2000
@@ -1,7 +1,7 @@
 /*
- * linux/drivers/block/sis5513.c	Version 0.08	Dec. 13, 1999
+ * linux/drivers/block/sis5513.c		Version 0.09	Feb. 10, 2000
  *
- * Copyright (C) 1999	Andre Hedrick (andre@suse.com)
+ * Copyright (C) 1999-2000	Andre Hedrick (andre@suse.com)
  * May be copied or modified under the terms of the GNU General Public License
  *
  * Thanks to SIS Taiwan for direct support and hardware.
@@ -50,6 +50,7 @@
 	{ "SiS540",	PCI_DEVICE_ID_SI_540,	SIS5513_FLAG_ATA_66, },
 	{ "SiS620",	PCI_DEVICE_ID_SI_620,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
 	{ "SiS630",	PCI_DEVICE_ID_SI_630,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS5591",	PCI_DEVICE_ID_SI_5591,	SIS5513_FLAG_ATA_33, },
 	{ "SiS5597",	PCI_DEVICE_ID_SI_5597,	SIS5513_FLAG_ATA_33, },
 	{ "SiS5600",	PCI_DEVICE_ID_SI_5600,	SIS5513_FLAG_ATA_33, },
 	{ "SiS5511",	PCI_DEVICE_ID_SI_5511,	SIS5513_FLAG_ATA_16, },
@@ -233,8 +234,10 @@
 	byte			drive_pci, test1, test2, mask;
 	int			err;
 
+	unsigned long dma_base	= hwif->dma_base;
+	byte unit		= (drive->select.b.unit & 0x01);
 	byte speed		= 0x00, unmask = 0xE0, four_two = 0x00;
-	int drive_number	= ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
+	int drive_number	= ((hwif->channel ? 2 : 0) + unit);
 	byte udma_66		= ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0;
 
 	if (host_dev) {
@@ -314,6 +317,7 @@
 		return ((int) ide_dma_off_quietly);
 	}
 
+	outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
 	err = ide_config_drive_speed(drive, speed);
 
 #if SIS5513_DEBUG_DRIVE_INFO
@@ -532,6 +536,7 @@
 			case PCI_DEVICE_ID_SI_630:
 			case PCI_DEVICE_ID_SI_5600:
 			case PCI_DEVICE_ID_SI_5597:
+			case PCI_DEVICE_ID_SI_5591:
 				hwif->autodma = 1;
 				hwif->dmaproc = &sis5513_dmaproc;
 				break;
diff -u --recursive --new-file v2.3.47/linux/drivers/block/sl82c105.c linux/drivers/block/sl82c105.c
--- v2.3.47/linux/drivers/block/sl82c105.c	Mon Dec 20 18:48:21 1999
+++ linux/drivers/block/sl82c105.c	Sat Feb 26 20:32:14 2000
@@ -1,5 +1,5 @@
 /*
- * drivers/block/sl82c105.c
+ * linux/drivers/block/sl82c105.c
  *
  * SL82C105/Winbond 553 IDE driver
  *
diff -u --recursive --new-file v2.3.47/linux/drivers/block/trm290.c linux/drivers/block/trm290.c
--- v2.3.47/linux/drivers/block/trm290.c	Fri Jan 28 15:09:07 2000
+++ linux/drivers/block/trm290.c	Sat Feb 26 20:32:14 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/trm290.c	Version 1.01  December 5, 1997
+ *  linux/drivers/block/trm290.c		Version 1.01	December 5, 1997
  *
  *  Copyright (c) 1997-1998  Mark Lord
  *  May be copied or modified under the terms of the GNU General Public License
diff -u --recursive --new-file v2.3.47/linux/drivers/block/umc8672.c linux/drivers/block/umc8672.c
--- v2.3.47/linux/drivers/block/umc8672.c	Thu May 13 11:04:54 1999
+++ linux/drivers/block/umc8672.c	Sat Feb 26 20:32:14 2000
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/umc8672.c	Version 0.05  Jul 31, 1996
+ *  linux/drivers/block/umc8672.c		Version 0.05	Jul 31, 1996
  *
  *  Copyright (C) 1995-1996  Linus Torvalds & author (see below)
  */
@@ -76,7 +76,7 @@
 	outb_p (wert,0x109);
 }
 
-static byte in_umc (char port)
+static inline byte in_umc (char port)
 {
 	outb_p (port,0x108);
 	return inb_p (0x109);
@@ -125,7 +125,7 @@
 	restore_flags(flags);	/* all CPUs */
 }
 
-void init_umc8672 (void)	/* called from ide.c */
+void __init init_umc8672 (void)	/* called from ide.c */
 {
 	unsigned long flags;
 
diff -u --recursive --new-file v2.3.47/linux/drivers/block/via82cxxx.c linux/drivers/block/via82cxxx.c
--- v2.3.47/linux/drivers/block/via82cxxx.c	Fri Jan 21 18:19:16 2000
+++ linux/drivers/block/via82cxxx.c	Sat Feb 26 20:32:14 2000
@@ -1,9 +1,10 @@
 /*
- * linux/drivers/block/via82cxxx.c	Version 0.06	Dec. 13, 1999
+ * linux/drivers/block/via82cxxx.c	Version 0.07	Feb. 10, 2000
  *
- *  Copyright (C) 1998-99 Michel Aubry, Maintainer
- *  Copyright (C) 1999 Jeff Garzik, MVP4 Support (jgarzik@mandrakesoft.com)
- *  Copyright (C) 1998-99 Andre Hedrick (andre@suse.com)
+ *  Copyright (C) 1998-99	Michel Aubry, Maintainer
+ *  Copyright (C) 1999		Jeff Garzik, MVP4 Support
+ *					(jgarzik@mandrakesoft.com)
+ *  Copyright (C) 1998-2000	Andre Hedrick (andre@suse.com)
  *  May be copied or modified under the terms of the GNU General Public License
  *
  *  The VIA MVP-4 is reported OK with UDMA.
@@ -473,12 +474,6 @@
 		!(newfifo & 0x03)		? "1" :
 		(!(newfifo & 0x02)		? "3/4" :
 		(newfifo & 0x01)		? "1/4" : "1/2"));
-
-#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
-	via_proc = 1;
-	bmide_dev = hwif->pci_dev;
-	via_display_info = &via_get_info;
-#endif /* DISPLAY_VIA_TIMINGS &&  CONFIG_PROC_FS*/
 	return 0;
 }
 
@@ -530,6 +525,12 @@
 		printk("\n");
 	}
 
+#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
+	via_proc = 1;
+	bmide_dev = dev;
+	via_display_info = &via_get_info;
+#endif /* DISPLAY_VIA_TIMINGS &&  CONFIG_PROC_FS*/
+
 	return 0;
 }
 
@@ -555,7 +556,7 @@
 }
 
 /*
- *  ide_dmacapable_via82c568(ide_hwif_t *, unsigned long)
+ *  ide_dmacapable_via82cxxx(ide_hwif_t *, unsigned long)
  *  checks if channel "channel" of if hwif is dma
  *  capable or not, according to kernel command line,
  *  and the new fifo settings.
diff -u --recursive --new-file v2.3.47/linux/drivers/char/Config.in linux/drivers/char/Config.in
--- v2.3.47/linux/drivers/char/Config.in	Wed Feb 16 17:03:51 2000
+++ linux/drivers/char/Config.in	Sat Feb 26 20:23:28 2000
@@ -122,7 +122,8 @@
 
 tristate '/dev/nvram support' CONFIG_NVRAM
 tristate 'Enhanced Real Time Clock Support' CONFIG_RTC
-if [ "$CONFIG_ALPHA_BOOK1" = "y" ]; then
+bool 'EFI Real Time Clock Services' CONFIG_EFI_RTC
+if [ "$CONFIG_OBSOLETE" = "y" -a "$CONFIG_ALPHA_BOOK1" = "y" ]; then
    bool 'Tadpole ANA H8 Support'  CONFIG_H8
 fi
 
diff -u --recursive --new-file v2.3.47/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.3.47/linux/drivers/char/Makefile	Sun Feb 20 21:12:38 2000
+++ linux/drivers/char/Makefile	Sat Feb 26 20:23:31 2000
@@ -61,6 +61,16 @@
   SERIAL   =
 endif
 
+ifeq ($(CONFIG_DECSTATION),y)
+  KEYBD    =
+  SERIAL   =
+endif
+
+ifeq ($(CONFIG_BAGET_MIPS),y)
+  KEYBD    =
+  SERIAL   =
+endif
+
 ifneq ($(CONFIG_SUN_SERIAL),)
   SERIAL   =
 endif
@@ -148,13 +158,17 @@
 obj-$(CONFIG_PC110_PAD) += pc110pad.o
 obj-$(CONFIG_WDT) += wdt.o
 obj-$(CONFIG_RTC) += rtc.o
+obj-$(CONFIG_EFI_RTC) += efirtc.o
 ifeq ($(CONFIG_PPC),)
   obj-$(CONFIG_NVRAM) += nvram.o
 endif
-obj-$(CONFIG_I810_RNG) += i810_rng.o
 
 obj-$(CONFIG_VIDEO_DEV) += videodev.o
 
+obj-$(CONFIG_21825_WATCHDOG) += wdt285.o
+obj-$(CONFIG_977_WATCHDOG) += wdt977.o
+obj-$(CONFIG_DS1620) += ds1620.o
+
 #
 # for external dependencies in arm/config.in and video/config.in
 #
@@ -195,7 +209,7 @@
 L_I2C = y
 else
   ifeq ($(CONFIG_I2C_PARPORT),m)
-    M_I2C = y
+    L_I2C = m
   endif
 endif
 
@@ -262,6 +276,13 @@
 
 # set when a framegrabber implements i2c support
 obj-$(L_I2C) += i2c-old.o
+
+ifeq ($(CONFIG_DZ),y)
+  L_OBJS += dz.o
+endif
+
+obj-$(CONFIG_NWBUTTON) += nwbutton.o
+obj-$(CONFIG_NWFLASH) += nwflash.o
 
 ifeq ($(CONFIG_DRM),y)
   SUB_DIRS += drm
diff -u --recursive --new-file v2.3.47/linux/drivers/char/agp/agpgart_be.c linux/drivers/char/agp/agpgart_be.c
--- v2.3.47/linux/drivers/char/agp/agpgart_be.c	Thu Feb 10 17:11:07 2000
+++ linux/drivers/char/agp/agpgart_be.c	Mon Feb 21 11:19:00 2000
@@ -1397,8 +1397,6 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 
 	return 0;
-	
-	(void) pdev; /* unused */
 }
 
 #endif /* CONFIG_AGP_SIS */
diff -u --recursive --new-file v2.3.47/linux/drivers/char/ds1620.c linux/drivers/char/ds1620.c
--- v2.3.47/linux/drivers/char/ds1620.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/ds1620.c	Thu Feb 24 22:56:47 2000
@@ -0,0 +1,436 @@
+/*
+ * linux/drivers/char/ds1620.c: Dallas Semiconductors DS1620
+ *   thermometer driver (as used in the Rebel.com NetWinder)
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/smp_lock.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/capability.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/therm.h>
+
+#ifdef CONFIG_PROC_FS
+/* define for /proc interface */
+#define THERM_USE_PROC
+#endif
+
+/* Definitions for DS1620 chip */
+#define THERM_START_CONVERT	0xee
+#define THERM_RESET		0xaf
+#define THERM_READ_CONFIG	0xac
+#define THERM_READ_TEMP		0xaa
+#define THERM_READ_TL		0xa2
+#define THERM_READ_TH		0xa1
+#define THERM_WRITE_CONFIG	0x0c
+#define THERM_WRITE_TL		0x02
+#define THERM_WRITE_TH		0x01
+
+#define CFG_CPU			2
+#define CFG_1SHOT		1
+
+static const char *fan_state[] = { "off", "on", "on (hardwired)" };
+
+/*
+ * Start of NetWinder specifics
+ *  Note!  We have to hold the gpio lock with IRQs disabled over the
+ *  whole of our transaction to the Dallas chip, since there is a
+ *  chance that the WaveArtist driver could touch these bits to
+ *  enable or disable the speaker.
+ */
+extern spinlock_t gpio_lock;
+extern unsigned int system_rev;
+
+static inline void netwinder_ds1620_set_clk(int clk)
+{
+	gpio_modify_op(GPIO_DSCLK, clk ? GPIO_DSCLK : 0);
+}
+
+static inline void netwinder_ds1620_set_data(int dat)
+{
+	gpio_modify_op(GPIO_DATA, dat ? GPIO_DATA : 0);
+}
+
+static inline int netwinder_ds1620_get_data(void)
+{
+	return gpio_read() & GPIO_DATA;
+}
+
+static inline void netwinder_ds1620_set_data_dir(int dir)
+{
+	gpio_modify_io(GPIO_DATA, dir ? GPIO_DATA : 0);
+}
+
+static inline void netwinder_ds1620_reset(void)
+{
+	cpld_modify(CPLD_DS_ENABLE, 0);
+	cpld_modify(CPLD_DS_ENABLE, CPLD_DS_ENABLE);
+}
+
+static inline void netwinder_lock(unsigned long *flags)
+{
+	spin_lock_irqsave(&gpio_lock, *flags);
+}
+
+static inline void netwinder_unlock(unsigned long *flags)
+{
+	spin_unlock_irqrestore(&gpio_lock, *flags);
+}
+
+static inline void netwinder_set_fan(int i)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+	gpio_modify_op(GPIO_FAN, i ? GPIO_FAN : 0);
+	spin_unlock_irqrestore(&gpio_lock, flags);
+}
+
+static inline int netwinder_get_fan(void)
+{
+	if ((system_rev & 0xf000) == 0x4000)
+		return FAN_ALWAYS_ON;
+
+	return (gpio_read() & GPIO_FAN) ? FAN_ON : FAN_OFF;
+}
+
+/*
+ * End of NetWinder specifics
+ */
+
+static void ds1620_send_bits(int nr, int value)
+{
+	int i;
+
+	for (i = 0; i < nr; i++) {
+		netwinder_ds1620_set_data(value & 1);
+		netwinder_ds1620_set_clk(0);
+		udelay(1);
+		netwinder_ds1620_set_clk(1);
+		udelay(1);
+
+		value >>= 1;
+	}
+}
+
+static unsigned int ds1620_recv_bits(int nr)
+{
+	unsigned int value = 0, mask = 1;
+	int i;
+
+	netwinder_ds1620_set_data(0);
+
+	for (i = 0; i < nr; i++) {
+		netwinder_ds1620_set_clk(0);
+		udelay(1);
+
+		if (netwinder_ds1620_get_data())
+			value |= mask;
+
+		mask <<= 1;
+
+		netwinder_ds1620_set_clk(1);
+		udelay(1);
+	}
+
+	return value;
+}
+
+static void ds1620_out(int cmd, int bits, int value)
+{
+	unsigned long flags;
+
+	netwinder_lock(&flags);
+	netwinder_ds1620_set_clk(1);
+	netwinder_ds1620_set_data_dir(0);
+	netwinder_ds1620_reset();
+
+	udelay(1);
+
+	ds1620_send_bits(8, cmd);
+	if (bits)
+		ds1620_send_bits(bits, value);
+
+	udelay(1);
+
+	netwinder_ds1620_reset();
+	netwinder_unlock(&flags);
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(2);
+}
+
+static unsigned int ds1620_in(int cmd, int bits)
+{
+	unsigned long flags;
+	unsigned int value;
+
+	netwinder_lock(&flags);
+	netwinder_ds1620_set_clk(1);
+	netwinder_ds1620_set_data_dir(0);
+	netwinder_ds1620_reset();
+
+	udelay(1);
+
+	ds1620_send_bits(8, cmd);
+
+	netwinder_ds1620_set_data_dir(1);
+	value = ds1620_recv_bits(bits);
+
+	netwinder_ds1620_reset();
+	netwinder_unlock(&flags);
+
+	return value;
+}
+
+static int cvt_9_to_int(unsigned int val)
+{
+	if (val & 0x100)
+		val |= 0xfffffe00;
+
+	return val;
+}
+
+static void ds1620_write_state(struct therm *therm)
+{
+	ds1620_out(THERM_WRITE_CONFIG, 8, CFG_CPU);
+	ds1620_out(THERM_WRITE_TL, 9, therm->lo);
+	ds1620_out(THERM_WRITE_TH, 9, therm->hi);
+	ds1620_out(THERM_START_CONVERT, 0, 0);
+}
+
+static void ds1620_read_state(struct therm *therm)
+{
+	therm->lo = cvt_9_to_int(ds1620_in(THERM_READ_TL, 9));
+	therm->hi = cvt_9_to_int(ds1620_in(THERM_READ_TH, 9));
+}
+
+static ssize_t
+ds1620_read(struct file *file, char *buf, size_t count, loff_t *ptr)
+{
+	signed int cur_temp;
+	signed char cur_temp_degF;
+
+	/* Can't seek (pread) on this device */
+	if (ptr != &file->f_pos)
+		return -ESPIPE;
+
+	cur_temp = cvt_9_to_int(ds1620_in(THERM_READ_TEMP, 9)) >> 1;
+
+	/* convert to Fahrenheit, as per wdt.c */
+	cur_temp_degF = (cur_temp * 9) / 5 + 32;
+
+	if (copy_to_user(buf, &cur_temp_degF, 1))
+		return -EFAULT;
+
+	return 1;
+}
+
+static int
+ds1620_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct therm therm;
+	int i;
+
+	switch(cmd) {
+	case CMD_SET_THERMOSTATE:
+	case CMD_SET_THERMOSTATE2:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		if (cmd == CMD_SET_THERMOSTATE) {
+			if (get_user(therm.hi, (int *)arg))
+				return -EFAULT;
+			therm.lo = therm.hi - 3;
+		} else {
+			if (copy_from_user(&therm, (void *)arg, sizeof(therm)))
+				return -EFAULT;
+		}
+
+		therm.lo <<= 1;
+		therm.hi <<= 1;
+
+		ds1620_write_state(&therm);
+		break;
+
+	case CMD_GET_THERMOSTATE:
+	case CMD_GET_THERMOSTATE2:
+		ds1620_read_state(&therm);
+
+		therm.lo >>= 1;
+		therm.hi >>= 1;
+
+		if (cmd == CMD_GET_THERMOSTATE) {
+			if (put_user(therm.hi, (int *)arg))
+				return -EFAULT;
+		} else {
+			if (copy_to_user((void *)arg, &therm, sizeof(therm)))
+				return -EFAULT;
+		}
+		break;
+
+	case CMD_GET_TEMPERATURE:
+	case CMD_GET_TEMPERATURE2:
+		i = cvt_9_to_int(ds1620_in(THERM_READ_TEMP, 9));
+
+		if (cmd == CMD_GET_TEMPERATURE)
+			i >>= 1;
+
+		return put_user(i, (int *)arg) ? -EFAULT : 0;
+
+	case CMD_GET_STATUS:
+		i = ds1620_in(THERM_READ_CONFIG, 8) & 0xe3;
+
+		return put_user(i, (int *)arg) ? -EFAULT : 0;
+
+	case CMD_GET_FAN:
+		i = netwinder_get_fan();
+
+		return put_user(i, (int *)arg) ? -EFAULT : 0;
+
+	case CMD_SET_FAN:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		if (get_user(i, (int *)arg))
+			return -EFAULT;
+
+		netwinder_set_fan(i);
+		break;
+		
+	default:
+		return -ENOIOCTLCMD;
+	}
+
+	return 0;
+}
+
+static int
+ds1620_open(struct inode *inode, struct file *file)
+{
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+static int
+ds1620_release(struct inode *inode, struct file *file)
+{
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+#ifdef THERM_USE_PROC
+static int
+proc_therm_ds1620_read(char *buf, char **start, off_t offset,
+		       int len, int *eof, void *unused)
+{
+	struct therm th;
+	int temp;
+
+	ds1620_read_state(&th);
+	temp =  cvt_9_to_int(ds1620_in(THERM_READ_TEMP, 9));
+
+	len = sprintf(buf, "Thermostat: HI %i.%i, LOW %i.%i; "
+		      "temperature: %i.%i C, fan %s\n",
+		      th.hi >> 1, th.hi & 1 ? 5 : 0,
+		      th.lo >> 1, th.lo & 1 ? 5 : 0,
+		      temp  >> 1, temp  & 1 ? 5 : 0,
+		      fan_state[netwinder_get_fan()]);
+
+	return len;
+}
+
+static struct proc_dir_entry *proc_therm_ds1620;
+#endif
+
+static struct file_operations ds1620_fops = {
+	NULL,			/* lseek		*/
+	ds1620_read,		/* read			*/
+	NULL,			/* write		*/
+	NULL,			/* readdir		*/
+	NULL,			/* select		*/
+	ds1620_ioctl,		/* ioctl		*/
+	NULL,			/* mmap			*/
+	ds1620_open,		/* open			*/
+	NULL,			/* flush		*/
+	ds1620_release,		/* release		*/
+	NULL,			/* fsync		*/
+	NULL,			/* fasync		*/
+};
+
+static struct miscdevice ds1620_miscdev = {
+	TEMP_MINOR,
+	"temp",
+	&ds1620_fops
+};
+
+int __init ds1620_init(void)
+{
+	int ret;
+	struct therm th, th_start;
+
+	if (!machine_is_netwinder())
+		return -ENODEV;
+
+	ds1620_out(THERM_RESET, 0, 0);
+	ds1620_out(THERM_WRITE_CONFIG, 8, CFG_CPU);
+	ds1620_out(THERM_START_CONVERT, 0, 0);
+
+	/*
+	 * Trigger the fan to start by setting
+	 * temperature high point low.  This kicks
+	 * the fan into action.
+	 */
+	ds1620_read_state(&th);
+	th_start.lo = 0;
+	th_start.hi = 1;
+	ds1620_write_state(&th_start);
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(2*HZ);
+
+	ds1620_write_state(&th);
+
+	ret = misc_register(&ds1620_miscdev);
+	if (ret < 0)
+		return ret;
+
+#ifdef THERM_USE_PROC
+	proc_therm_ds1620 = create_proc_entry("therm", 0, 0);
+	if (proc_therm_ds1620)
+		proc_therm_ds1620->read_proc = proc_therm_ds1620_read;
+	else
+		printk(KERN_ERR "therm: unable to register /proc/therm\n");
+#endif
+
+	ds1620_read_state(&th);
+	ret = cvt_9_to_int(ds1620_in(THERM_READ_TEMP, 9));
+
+	printk(KERN_INFO "Thermostat: high %i.%i, low %i.%i, "
+	       "current %i.%i C, fan %s.\n",
+	       th.hi >> 1, th.hi & 1 ? 5 : 0,
+	       th.lo >> 1, th.lo & 1 ? 5 : 0,
+	       ret   >> 1, ret   & 1 ? 5 : 0,
+	       fan_state[netwinder_get_fan()]);
+
+	return 0;
+}
+
+void __exit ds1620_exit(void)
+{
+#ifdef THERM_USE_PROC
+	remove_proc_entry("therm", NULL);
+#endif
+	misc_deregister(&ds1620_miscdev);
+}
+
+module_init(ds1620_init);
+module_exit(ds1620_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/char/dz.c linux/drivers/char/dz.c
--- v2.3.47/linux/drivers/char/dz.c	Wed Feb 16 17:03:51 2000
+++ linux/drivers/char/dz.c	Fri Feb 25 10:26:42 2000
@@ -14,6 +14,9 @@
  *    after patches by harald to irq code.  
  * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout
  *            field from "current" - somewhere between 2.1.121 and 2.1.131
+ *  
+ * Parts (C) 1999 David Airlie, airlied@linux.ie 
+ * [07-SEP-99] Bugfixes 
  */
 
 #define DEBUG_DZ 1
@@ -26,7 +29,6 @@
 #define MOD_DEC_USE_COUNT
 #endif
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/init.h> 
@@ -74,7 +76,7 @@
 
 DECLARE_TASK_QUEUE(tq_serial);
 
-extern struct wait_queue *keypress_wait;
+extern wait_queue_head_t keypress_wait; 
 static struct dz_serial *lines[4];
 static unsigned char tmp_buffer[256];
 
@@ -131,9 +133,13 @@
 
 static void dz_stop (struct tty_struct *tty)
 {
-  struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+  struct dz_serial *info; 
   unsigned short mask, tmp;
 
+  if (tty==0) 
+    return; 
+ 
+  info = (struct dz_serial *)tty->driver_data; 
          
   mask = 1 << info->line;
   tmp = dz_in (info, DZ_TCR);       /* read the TX flag */
@@ -1040,7 +1046,7 @@
   }
 
   if (--info->count < 0) {
-    printk("rs_close: bad serial port count for ttys%d: %d\n",
+    printk("ds_close: bad serial port count for ttys%d: %d\n",
 	   info->line, info->count);
     info->count = 0;
   }
@@ -1127,7 +1133,7 @@
  */
 static int block_til_ready (struct tty_struct *tty, struct file *filp, struct dz_serial *info)
 {
-  struct wait_queue wait = { current, NULL };
+  DECLARE_WAITQUEUE(wait, current); 
   int retval;
   int do_clocal = 0;
 
@@ -1339,9 +1345,9 @@
     panic("Couldn't register callout driver\n");
   save_flags(flags); cli();
  
-  i = 0;
-  for (info = &multi[i]; i < DZ_NB_PORT;  i++) 
+  for (i=0; i < DZ_NB_PORT;  i++)  
     {
+      info = &multi[i]; 
       lines[i] = info;
     info->magic = SERIAL_MAGIC;
 
@@ -1364,8 +1370,8 @@
     info->tqueue_hangup.data = info;
     info->callout_termios = callout_driver.init_termios;
     info->normal_termios = serial_driver.init_termios;
-    info->open_wait = 0;
-    info->close_wait = 0;
+    init_waitqueue_head(&info->open_wait); 
+    init_waitqueue_head(&info->close_wait); 
 
     /* If we are pointing to address zero then punt - not correctly
        set up in setup.c to handle this. */
@@ -1400,7 +1406,7 @@
 #ifdef CONFIG_SERIAL_CONSOLE
 static void dz_console_put_char (unsigned char ch)
 {
-  long flags;
+  unsigned long flags;
   int  loops = 2500;
   unsigned short tmp = ch;
   /* this code sends stuff out to serial device - spinning its
@@ -1414,7 +1420,7 @@
   
 
   /* spin our wheels */
-  while (((dz_in(dz_console,DZ_TCR) & DZ_TRDY) != DZ_TRDY) &&  loops--)
+  while (((dz_in(dz_console,DZ_CSR) & DZ_TRDY) != DZ_TRDY) &&  loops--)
     ;
   
   /* Actually transmit the character. */
@@ -1533,38 +1539,6 @@
 	dz_console->cflags |= DZ_CS8;
 	dz_console->cflags |= DZ_PARENB;
 	dz_out (dz_console, DZ_LPR, dz_console->cflags);
-
-
-	mask = 1 << dz_console->line;
-	tmp = dz_in (dz_console, DZ_TCR);       /* read the TX flag */
-	if (!(tmp & mask)) {
-	  tmp |= mask;                   /* set the TX flag */
-	  dz_out (dz_console, DZ_TCR, tmp); 
-	}
-	
-
-	/* TOFIX: force to console line */
-	dz_console = &multi[CONSOLE_LINE];
-    	if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100)) 
-	dz_console->port = KN01_DZ11_BASE;
-       	else 
-       		dz_console->port = KN02_DZ11_BASE; 
-	dz_console->line = CONSOLE_LINE;
-
-	dz_out(dz_console, DZ_CSR, DZ_CLR);
-	while ((tmp = dz_in(dz_console,DZ_CSR)) & DZ_CLR)
-	  ;
-
-	/* enable scanning */
-	dz_out(dz_console, DZ_CSR, DZ_MSE); 
-
-        /*  Set up flags... */
-	dz_console->cflags = 0;
-	dz_console->cflags |= DZ_B9600;
-	dz_console->cflags |= DZ_CS8;
-	dz_console->cflags |= DZ_PARENB;
-	dz_out (dz_console, DZ_LPR, dz_console->cflags);
-
 
 	mask = 1 << dz_console->line;
 	tmp = dz_in (dz_console, DZ_TCR);       /* read the TX flag */
diff -u --recursive --new-file v2.3.47/linux/drivers/char/dz.h linux/drivers/char/dz.h
--- v2.3.47/linux/drivers/char/dz.h	Fri Jun 25 17:39:14 1999
+++ linux/drivers/char/dz.h	Fri Feb 25 10:26:42 2000
@@ -158,8 +158,8 @@
   struct tq_struct        tqueue_hangup;
   struct termios          normal_termios;
   struct termios          callout_termios;
-  struct wait_queue       *open_wait;
-  struct wait_queue       *close_wait;
+  wait_queue_head_t       open_wait;
+  wait_queue_head_t       close_wait;
 
   long                    session;             /* Session of opening process */
   long                    pgrp;                /* pgrp of opening process */
@@ -188,7 +188,7 @@
  * memory if large numbers of serial ports are open.
  */
 static unsigned char *tmp_buf;
-static struct semaphore tmp_buf_sem = MUTEX;
+static DECLARE_MUTEX(tmp_buf_sem);
 
 static char *dz_name = "DECstation DZ serial driver version ";
 static char *dz_version = "1.02";
diff -u --recursive --new-file v2.3.47/linux/drivers/char/efirtc.c linux/drivers/char/efirtc.c
--- v2.3.47/linux/drivers/char/efirtc.c	Thu Feb 10 17:11:07 2000
+++ linux/drivers/char/efirtc.c	Thu Feb 24 10:14:29 2000
@@ -334,6 +334,7 @@
         if (len<0) len = 0;
         return len;
 }
+
 static int __init 
 efi_rtc_init(void)
 {
@@ -345,6 +346,7 @@
 
 	return 0;
 }
+
 static int __exit
 efi_rtc_exit(void)
 {
diff -u --recursive --new-file v2.3.47/linux/drivers/char/h8.c linux/drivers/char/h8.c
--- v2.3.47/linux/drivers/char/h8.c	Sun Feb 20 21:12:38 2000
+++ linux/drivers/char/h8.c	Thu Feb 24 09:13:46 2000
@@ -6,6 +6,8 @@
  *
  * Fixes:
  *	June 1999, AV	added releasing /proc/driver/h8
+ *	Feb  2000, Borislav Deianov
+ *			changed queues to use list.h instead of lists.h
  */
 
 #include <linux/config.h>
@@ -23,7 +25,7 @@
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
 #include <linux/miscdevice.h>
-#include <linux/lists.h>
+#include <linux/list.h>
 #include <linux/ioport.h>
 #include <linux/poll.h>
 #include <linux/init.h>
@@ -52,18 +54,13 @@
 /*
  * Forward declarations.
  */
-int          h8_init(void);
+static int   h8_init(void);
 int          h8_display_blank(void);
 int          h8_display_unblank(void);
 
 static void  h8_intr(int irq, void *dev_id, struct pt_regs *regs);
 
-#ifdef CONFIG_PROC_FS
 static int   h8_get_info(char *, char **, off_t, int);
-#else
-static int   h8_get_info(char *, char **, off_t, int) {}
-#error "Somebody needs to learn C. Badly."
-#endif
 
 /*
  * Support Routines.
@@ -141,7 +138,9 @@
 unsigned int h8_index = -1;
 unsigned int h8_enabled = 0;
 
-queue_head_t h8_actq, h8_cmdq, h8_freeq;
+LIST_HEAD(h8_actq);
+LIST_HEAD(h8_cmdq);
+LIST_HEAD(h8_freeq);
 
 /* 
  * Globals used in thermal control of Alphabook1.
@@ -170,7 +169,7 @@
 static void h8_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	u_char	stat_reg, data_reg;
-	h8_cmd_q_t *qp = (h8_cmd_q_t *)QUEUE_FIRST(&h8_actq, link);
+	h8_cmd_q_t *qp = list_entry(h8_actq.next, h8_cmd_q_t, link);
 
 	stat_reg = H8_GET_STATUS;
 	data_reg = H8_READ_DATA;
@@ -260,7 +259,7 @@
 	        return;
 	    } else if (data_reg == H8_SYNC_BYTE) {
 	        h8_state = H8_IDLE;
-		if (!QUEUE_IS_EMPTY(&h8_actq, link))
+		if (!list_empty(&h8_actq))
 		    h8_send_next_cmd_byte();
 	    } else {
 	        Dprintk ("h8_intr: resync unknown data 0x%x \n", data_reg);
@@ -276,10 +275,10 @@
 		/* If command reception finished. */
 		if (qp->cnt == qp->nrsp) {
 		    h8_state = H8_IDLE;
-		    QUEUE_REMOVE(&h8_actq, qp, link);
+		    list_del(&qp->link);
 		    h8_cmd_done (qp);
 		    /* More commands to send over? */
-		    if (!QUEUE_IS_EMPTY(&h8_cmdq, link))
+		    if (!list_empty(&h8_cmdq))
 		        h8_start_new_cmd();
 		}
 		return;
@@ -317,9 +316,6 @@
         misc_register(&h8_device);
         request_region(h8_base, 8, "h8");
 
-	QUEUE_INIT(&h8_actq, link, h8_cmd_q_t *);
-	QUEUE_INIT(&h8_cmdq, link, h8_cmd_q_t *);
-	QUEUE_INIT(&h8_freeq, link, h8_cmd_q_t *);
 	h8_alloc_queues();
 
 	h8_hw_init();
@@ -364,9 +360,9 @@
 	return;
 }
 
-#ifdef CONFIG_PROC_FS
 static int h8_get_info(char *buf, char **start, off_t fpos, int length)
 {
+#ifdef CONFIG_PROC_FS
         char *p;
 
         if (!h8_enabled)
@@ -387,8 +383,10 @@
 		     );
 
         return p - buf;
-}
+#else
+	return 0;
 #endif
+}
 
 /* Called from console driver -- must make sure h8_enabled. */
 int h8_display_blank(void)
@@ -440,7 +438,7 @@
         save_flags(flags); cli();
         for (i = 0; i < H8_Q_ALLOC_AMOUNT; i++) {
                 /* place each at front of freeq */
-                QUEUE_ENTER(&h8_freeq, &qp[i], link, h8_cmd_q_t *);
+                list_add(&qp[i].link, &h8_freeq);
         }
         restore_flags(flags);
         return (1);
@@ -458,15 +456,15 @@
 
         /* get cmd buf */
 	save_flags(flags); cli();
-        while (QUEUE_IS_EMPTY(&h8_freeq, link)) {
+        while (list_empty(&h8_freeq)) {
                 Dprintk("H8: need to allocate more cmd buffers\n");
                 restore_flags(flags);
                 h8_alloc_queues();
                 save_flags(flags); cli();
         }
         /* get first element from queue */
-        qp = (h8_cmd_q_t *)QUEUE_FIRST(&h8_freeq, link);
-        QUEUE_REMOVE(&h8_freeq, qp, link);
+        qp = list_entry(h8_freeq.next, h8_cmd_q_t, link);
+        list_del(&qp->link);
 
         restore_flags(flags);
 
@@ -479,7 +477,8 @@
         /* queue it at the end of the cmd queue */
         save_flags(flags); cli();
 
-        QUEUE_ENTER(&h8_cmdq, qp, link, h8_cmd_q_t *);
+        /* XXX this actually puts it at the start of cmd queue, bug? */
+        list_add(&qp->link, &h8_cmdq);
 
         restore_flags(flags);
 
@@ -500,13 +499,13 @@
                 return;
         }
 
-        if (!QUEUE_IS_EMPTY(&h8_actq, link)) {
+        if (!list_empty(&h8_actq)) {
                 Dprintk("h8_start_new_cmd: inconsistency: IDLE with non-empty active queue!\n");
                 restore_flags(flags);
                 return;
         }
 
-        if (QUEUE_IS_EMPTY(&h8_cmdq, link)) {
+        if (list_empty(&h8_cmdq)) {
                 Dprintk("h8_start_new_cmd: no command to dequeue\n");
                 restore_flags(flags);
                 return;
@@ -515,9 +514,10 @@
          * Take first command off of the command queue and put
          * it on the active queue.
          */
-        qp = (h8_cmd_q_t *) QUEUE_FIRST(&h8_cmdq, link);
-        QUEUE_REMOVE(&h8_cmdq, qp, link);
-        QUEUE_ENTER(&h8_actq, qp, link, h8_cmd_q_t *);
+        qp = list_entry(h8_cmdq.next, h8_cmd_q_t, link);
+        list_del(&qp->link);
+        /* XXX should this go to the end of the active queue? */
+        list_add(&qp->link, &h8_actq);
         h8_state = H8_XMIT;
         if (h8_debug & 0x1)
                 Dprintk("h8_start_new_cmd: Starting a command\n");
@@ -532,7 +532,7 @@
 void
 h8_send_next_cmd_byte(void)
 {
-        h8_cmd_q_t      *qp = (h8_cmd_q_t *)QUEUE_FIRST(&h8_actq, link);
+        h8_cmd_q_t      *qp = list_entry(h8_actq.next, h8_cmd_q_t, link);
         int cnt;
 
         cnt = qp->cnt;
@@ -689,7 +689,7 @@
 	    if (h8_debug & 0x40000) 
 	        printk("H8: Sync command done - byte returned was 0x%x\n", 
 		       qp->rcvbuf[0]);
-	    QUEUE_ENTER(&h8_freeq, qp, link, h8_cmd_q_t *);
+	    list_add(&qp->link, &h8_freeq);
 	    break;
 
 	case H8_RD_SN:
@@ -697,7 +697,7 @@
 	    printk("H8: read Ethernet address: command done - address: %x - %x - %x - %x - %x - %x \n", 
 		   qp->rcvbuf[0], qp->rcvbuf[1], qp->rcvbuf[2],
 		   qp->rcvbuf[3], qp->rcvbuf[4], qp->rcvbuf[5]);
-	    QUEUE_ENTER(&h8_freeq, qp, link, h8_cmd_q_t *);
+	    list_add(&qp->link, &h8_freeq);
 	    break;
 
 	case H8_RD_HW_VER:
@@ -705,13 +705,13 @@
 	case H8_RD_MAX_TEMP:
 	    printk("H8: Max recorded CPU temp %d, Sys temp %d\n",
 		   qp->rcvbuf[0], qp->rcvbuf[1]);
-	    QUEUE_ENTER(&h8_freeq, qp, link, h8_cmd_q_t *);
+	    list_add(&qp->link, &h8_freeq);
 	    break;
 
 	case H8_RD_MIN_TEMP:
 	    printk("H8: Min recorded CPU temp %d, Sys temp %d\n",
 		   qp->rcvbuf[0], qp->rcvbuf[1]);
-	    QUEUE_ENTER(&h8_freeq, qp, link, h8_cmd_q_t *);
+	    list_add(&qp->link, &h8_freeq);
 	    break;
 
 	case H8_RD_CURR_TEMP:
@@ -719,7 +719,7 @@
 	    xx.byte[0] = qp->rcvbuf[0];
 	    xx.byte[1] = qp->rcvbuf[1];
 	    wake_up(&h8_sync_wait); 
-	    QUEUE_ENTER(&h8_freeq, qp, link, h8_cmd_q_t *); 
+	    list_add(&qp->link, &h8_freeq);
 	    break;
 
 	case H8_RD_SYS_VARIENT:
@@ -740,7 +740,7 @@
 	    xx.byte[0] = qp->rcvbuf[1];
 	    h8_sync_channel |= H8_GET_EXT_STATUS;
 	    wake_up(&h8_sync_wait); 
-	    QUEUE_ENTER(&h8_freeq, qp, link, h8_cmd_q_t *); 
+	    list_add(&qp->link, &h8_freeq);
 	    break;
 
 	case H8_RD_USER_CFG:
@@ -755,7 +755,7 @@
 	case H8_RD_INT_BATT_STATUS:
 	    printk("H8: Read int batt status cmd done - returned was %x %x %x\n",
 		   qp->rcvbuf[0], qp->rcvbuf[1], qp->rcvbuf[2]);
-	    QUEUE_ENTER(&h8_freeq, qp, link, h8_cmd_q_t *);
+	    list_add(&qp->link, &h8_freeq);
 	    break;
 
 	case H8_RD_EXT_BATT_STATUS:
@@ -767,7 +767,7 @@
 	        printk("H8: Device control cmd done - byte returned was 0x%x\n",
 		       qp->rcvbuf[0]);
 	    }
-	    QUEUE_ENTER(&h8_freeq, qp, link, h8_cmd_q_t *);
+	    list_add(&qp->link, &h8_freeq);
 	    break;
 
 	case H8_CTL_TFT_BRT_DC:
@@ -788,7 +788,7 @@
 	        XDprintk("H8: ctl upper thermal thresh cmd done - returned was %d\n",
 		       qp->rcvbuf[0]);
 	    }
-	    QUEUE_ENTER(&h8_freeq, qp, link, h8_cmd_q_t *);
+	    list_add(&qp->link, &h8_freeq);
 	    break;
 
 	case H8_CTL_LOWER_TEMP:
diff -u --recursive --new-file v2.3.47/linux/drivers/char/h8.h linux/drivers/char/h8.h
--- v2.3.47/linux/drivers/char/h8.h	Wed Jun 24 14:30:09 1998
+++ linux/drivers/char/h8.h	Thu Feb 24 09:13:46 2000
@@ -229,7 +229,7 @@
  * H8 command buffers
  */
 typedef struct h8_cmd_q {
-        DLNODE(struct h8_cmd_q) link; /* double linked list */
+        struct list_head link;          /* double linked list */
         int             ncmd;           /* number of bytes in command */
         int             nrsp;           /* number of bytes in response */
         int             cnt;            /* number of bytes sent/received */
@@ -237,10 +237,6 @@
         u_char          cmdbuf[H8_MAX_CMD_SIZE]; /* buffer to store command */
         u_char          rcvbuf[H8_MAX_CMD_SIZE]; /* buffer to store response */
 } h8_cmd_q_t;
-
-typedef struct __queue_head {
-	DLNODE(struct h8_cmd_q) link;
-} queue_head_t;
 
 union   intr_buf {
         u_char  byte[2];
diff -u --recursive --new-file v2.3.47/linux/drivers/char/lp.c linux/drivers/char/lp.c
--- v2.3.47/linux/drivers/char/lp.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/char/lp.c	Thu Feb 24 10:30:25 2000
@@ -783,12 +783,12 @@
 		return -EIO;
 	}
 
+	devfs_handle = devfs_mk_dir (NULL, "printers", 0, NULL);
+
 	if (parport_register_driver (&lp_driver)) {
 		printk ("lp: unable to register with parport\n");
 		return -EIO;
 	}
-
-	devfs_handle = devfs_mk_dir (NULL, "printers", 0, NULL);
 
 	if (!lp_count) {
 		printk (KERN_INFO "lp: driver loaded but no devices found\n");
diff -u --recursive --new-file v2.3.47/linux/drivers/char/mem.c linux/drivers/char/mem.c
--- v2.3.47/linux/drivers/char/mem.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/char/mem.c	Sat Feb 26 20:24:58 2000
@@ -5,6 +5,7 @@
  *
  *  Added devfs support. 
  *    Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
+ *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
  */
 
 #include <linux/config.h>
@@ -285,7 +286,7 @@
 	return do_write_mem(file, (void*)p, p, buf, count, ppos);
 }
 
-#if !defined(CONFIG_PPC) && !defined(__mc68000__)
+#if !defined(__mc68000__)
 static ssize_t read_port(struct file * file, char * buf,
 			 size_t count, loff_t *ppos)
 {
@@ -434,7 +435,7 @@
 static int mmap_zero(struct file * file, struct vm_area_struct * vma)
 {
 	if (vma->vm_flags & VM_SHARED)
-		return -EINVAL;
+		return map_zero_setup(vma);
 	if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;
 	return 0;
@@ -514,7 +515,7 @@
 	write:		write_null,
 };
 
-#if !defined(CONFIG_PPC) && !defined(__mc68000__)
+#if !defined(__mc68000__)
 static struct file_operations port_fops = {
 	llseek:		memory_lseek,
 	read:		read_port,
@@ -548,7 +549,7 @@
 		case 3:
 			filp->f_op = &null_fops;
 			break;
-#if !defined(CONFIG_PPC) && !defined(__mc68000__)
+#if !defined(__mc68000__)
 		case 4:
 			filp->f_op = &port_fops;
 			break;
diff -u --recursive --new-file v2.3.47/linux/drivers/char/misc.c linux/drivers/char/misc.c
--- v2.3.47/linux/drivers/char/misc.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/char/misc.c	Fri Feb 25 10:26:42 2000
@@ -209,6 +209,9 @@
 #if defined(CONFIG_SUN_MOSTEK_RTC)
 	rtc_sun_init();
 #endif
+#ifdef CONFIG_SGI_DS1286
+	ds1286_init();
+#endif
 #ifdef CONFIG_ATARI_DSP56K
 	dsp56k_init();
 #endif
@@ -221,7 +224,7 @@
 #ifdef CONFIG_SGI_NEWPORT_GFX
 	gfx_register ();
 #endif
-#ifdef CONFIG_SGI
+#ifdef CONFIG_SGI_IP22
 	streamable_init ();
 #endif
 #ifdef CONFIG_SGI_NEWPORT_GFX
diff -u --recursive --new-file v2.3.47/linux/drivers/char/nwbutton.c linux/drivers/char/nwbutton.c
--- v2.3.47/linux/drivers/char/nwbutton.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/nwbutton.c	Thu Feb 24 22:56:47 2000
@@ -0,0 +1,276 @@
+/*
+ * 	NetWinder Button Driver-
+ *	Copyright (C) Alex Holden <alex@linuxhacker.org> 1998, 1999.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#define __NWBUTTON_C		/* Tell the header file who we are */
+#include "nwbutton.h"
+
+static int button_press_count = 0;	/* The count of button presses */
+static struct timer_list button_timer;	/* Times for the end of a sequence */ 
+static DECLARE_WAIT_QUEUE_HEAD(button_wait_queue); /* Used for blocking read */
+static char button_output_buffer[32];	/* Stores data to write out of device */
+static int bcount = 0;			/* The number of bytes in the buffer */
+static int bdelay = BUTTON_DELAY;	/* The delay, in jiffies */
+static struct button_callback button_callback_list[32]; /* The callback list */
+static int callback_count = 0;		/* The number of callbacks registered */
+static int reboot_count = NUM_PRESSES_REBOOT; /* Number of presses to reboot */
+
+/*
+ * This function is called by other drivers to register a callback function
+ * to be called when a particular number of button presses occurs.
+ * The callback list is a static array of 32 entries (I somehow doubt many
+ * people are ever going to want to register more than 32 different actions
+ * to be performed by the kernel on different numbers of button presses ;).
+ * However, if an attempt to register a 33rd entry (perhaps a stuck loop
+ * somewhere registering the same entry over and over?) it will fail to
+ * do so and return -ENOMEM. If an attempt is made to register a null pointer,
+ * it will fail to do so and return -EINVAL.
+ * Because callbacks can be unregistered at random the list can become
+ * fragmented, so we need to search through the list until we find the first
+ * free entry.
+ */
+
+int button_add_callback (void (*callback) (void), int count)
+{
+	int lp = 0;
+	if (callback_count == 32) {
+		return -ENOMEM;
+	}
+	if (!callback) {
+		return -EINVAL;
+	}
+	callback_count++;
+	for (; (button_callback_list [lp].callback); lp++);
+	button_callback_list [lp].callback = callback;
+	button_callback_list [lp].count = count;
+	return 0;
+}
+
+/*
+ * This function is called by other drivers to deregister a callback function.
+ * If you attempt to unregister a callback which does not exist, it will fail
+ * with -EINVAL. If there is more than one entry with the same address,
+ * because it searches the list from end to beginning, it will unregister the
+ * last one to be registered first (FILO- First In Last Out).
+ * Note that this is not neccessarily true if the entries are not submitted
+ * at the same time, because another driver could have unregistered a callback
+ * between the submissions creating a gap earlier in the list, which would
+ * be filled first at submission time.
+ */
+
+int button_del_callback (void (*callback) (void))
+{
+	int lp = 31;
+	if (!callback) {
+		return -EINVAL;
+	}
+	while (lp >= 0) {
+		if ((button_callback_list [lp].callback) == callback) {
+			button_callback_list [lp].callback = NULL;
+			button_callback_list [lp].count = 0;
+			callback_count--;
+			return 0;
+		};
+		lp--;
+	};
+	return -EINVAL;
+}
+
+/*
+ * This function is called by button_sequence_finished to search through the
+ * list of callback functions, and call any of them whose count argument
+ * matches the current count of button presses. It starts at the beginning
+ * of the list and works up to the end. It will refuse to follow a null
+ * pointer (which should never happen anyway).
+ */
+
+static void button_consume_callbacks (int bpcount)
+{
+	int lp = 0;
+	for (; lp <= 31; lp++) {
+		if ((button_callback_list [lp].count) == bpcount) {
+			if (button_callback_list [lp].callback) {
+				button_callback_list[lp].callback();
+			}
+		}
+	}
+}
+
+/* 
+ * This function is called when the button_timer times out.
+ * ie. When you don't press the button for bdelay jiffies, this is taken to
+ * mean you have ended the sequence of key presses, and this function is
+ * called to wind things up (write the press_count out to /dev/button, call
+ * any matching registered function callbacks, initiate reboot, etc.).
+ */
+
+static void button_sequence_finished (unsigned long parameters)
+{
+#ifdef CONFIG_NWBUTTON_REBOOT		/* Reboot using button is enabled */
+	if (button_press_count == reboot_count) {
+		kill_proc (1, SIGINT, 1);	/* Ask init to reboot us */
+	}
+#endif /* CONFIG_NWBUTTON_REBOOT */
+	button_consume_callbacks (button_press_count);
+	bcount = sprintf (button_output_buffer, "%d\n", button_press_count);
+	button_press_count = 0;		/* Reset the button press counter */
+	wake_up_interruptible (&button_wait_queue);
+}
+
+/* 
+ *  This handler is called when the orange button is pressed (GPIO 10 of the
+ *  SuperIO chip, which maps to logical IRQ 26). If the press_count is 0,
+ *  this is the first press, so it starts a timer and increments the counter.
+ *  If it is higher than 0, it deletes the old timer, starts a new one, and
+ *  increments the counter.
+ */ 
+
+static void button_handler (int irq, void *dev_id, struct pt_regs *regs)
+{
+	if (button_press_count) {
+		del_timer (&button_timer);
+	}
+	button_press_count++;
+	init_timer (&button_timer);
+	button_timer.function = button_sequence_finished;
+	button_timer.expires = (jiffies + bdelay);
+	add_timer (&button_timer);
+}
+
+/*
+ * This function is called when a user space program attempts to read
+ * /dev/nwbutton. It puts the device to sleep on the wait queue until
+ * button_sequence_finished writes some data to the buffer and flushes
+ * the queue, at which point it writes the data out to the device and
+ * returns the number of characters it has written. This function is
+ * reentrant, so that many processes can be attempting to read from the
+ * device at any one time.
+ */
+
+static int button_read (struct file *filp, char *buffer,
+			size_t count, loff_t *ppos)
+{
+	interruptible_sleep_on (&button_wait_queue);
+	return (copy_to_user (buffer, &button_output_buffer, bcount))
+		 ? -EFAULT : bcount;
+}
+
+/*
+ * This function is called when a user space process attempts to open the
+ * device. If the driver is compiled into the kernel it does nothing but
+ * succeed, but if it is compiled in as a module it also increments the
+ * module usage count to prevent the module from being removed whilst a
+ * process has the device open.
+ */
+
+static int button_open (struct inode *inode, struct file *filp)
+{
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+/*
+ * This function is called when a user space process attempts to close the
+ * device. If the driver is compiled into the kernel it does nothing at all,
+ * but if it is compiled in as a module it also decrements the module usage
+ * count so that it will be possible to unload the module again once all the
+ * user processes have closed the device.
+ */
+
+static int button_release (struct inode *inode, struct file *filp)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+/* 
+ * This structure is the file operations structure, which specifies what
+ * callbacks functions the kernel should call when a user mode process
+ * attempts to perform these operations on the device.
+ */
+
+static struct file_operations button_fops = {
+	NULL,		/* lseek */
+	button_read,
+	NULL,		/* write */
+	NULL,		/* readdir */
+	NULL,		/* select */
+	NULL,		/* ioctl */
+	NULL,		/* mmap */
+	button_open,
+	NULL,		/* flush */
+	button_release,
+};
+
+/* 
+ * This structure is the misc device structure, which specifies the minor
+ * device number (158 in this case), the name of the device (for /proc/misc),
+ * and the address of the above file operations structure.
+ */
+
+static struct miscdevice button_misc_device = {
+	BUTTON_MINOR,
+	"nwbutton",
+	&button_fops,
+};
+
+/*
+ * This function is called to initialise the driver, either from misc.c at
+ * bootup if the driver is compiled into the kernel, or from init_module
+ * below at module insert time. It attempts to register the device node
+ * and the IRQ and fails with a warning message if either fails, though
+ * neither ever should because the device number and IRQ are unique to
+ * this driver.
+ */
+
+static int __init nwbutton_init(void)
+{
+	if (!machine_is_netwinder())
+		return -ENODEV;
+
+	printk (KERN_INFO "NetWinder Button Driver Version %s (C) Alex Holden "
+			"<alex@linuxhacker.org> 1998.\n", VERSION);
+
+	if (misc_register (&button_misc_device)) {
+		printk (KERN_WARNING "nwbutton: Couldn't register device 10, "
+				"%d.\n", BUTTON_MINOR);
+		return -EBUSY;
+	}
+
+	if (request_irq (IRQ_NETWINDER_BUTTON, button_handler, SA_INTERRUPT,
+			"nwbutton", NULL)) {
+		printk (KERN_WARNING "nwbutton: IRQ %d is not free.\n",
+				IRQ_NETWINDER_BUTTON);
+		misc_deregister (&button_misc_device);
+		return -EIO;
+	}
+	return 0;
+}
+
+static void __exit nwbutton_exit (void) 
+{
+	free_irq (IRQ_NETWINDER_BUTTON, NULL);
+	misc_deregister (&button_misc_device);
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(nwbutton_init);
+module_exit(nwbutton_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/char/nwbutton.h linux/drivers/char/nwbutton.h
--- v2.3.47/linux/drivers/char/nwbutton.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/nwbutton.h	Thu Feb 24 22:56:47 2000
@@ -0,0 +1,48 @@
+#ifndef __NWBUTTON_H
+#define __NWBUTTON_H
+
+/*
+ * 	NetWinder Button Driver-
+ *	Copyright (C) Alex Holden <alex@linuxhacker.org> 1998, 1999.
+ */
+
+#ifdef __NWBUTTON_C	/* Actually compiling the driver itself */
+
+/* Various defines: */
+
+#define NUM_PRESSES_REBOOT 2	/* How many presses to activate shutdown */
+#define BUTTON_DELAY 30 	/* How many jiffies for sequence to end */
+#define VERSION "0.3"		/* Driver version number */
+#define BUTTON_MINOR 158	/* Major 10, Minor 158, /dev/nwbutton */
+
+/* Structure definitions: */
+
+struct button_callback {
+	void (*callback) (void);
+	int count;
+};
+
+/* Function prototypes: */
+
+static void button_sequence_finished (unsigned long parameters);
+static void button_handler (int irq, void *dev_id, struct pt_regs *regs);
+static int button_read (struct file *filp, char *buffer,
+			size_t count, loff_t *ppos);
+static int button_open (struct inode *inode, struct file *filp);
+static int button_release (struct inode *inode, struct file *filp);
+int button_init (void);
+int button_add_callback (void (*callback) (void), int count);
+int button_del_callback (void (*callback) (void));
+static void button_consume_callbacks (int bpcount);
+#ifdef MODULE
+int init_module (void);
+void cleanup_module (void);
+#endif /* MODULE */
+
+#else /* Not compiling the driver itself */
+
+extern int button_add_callback (void (*callback) (void), int count);
+extern int button_del_callback (void (*callback) (void));
+
+#endif /* __NWBUTTON_C */
+#endif /* __NWBUTTON_H */
diff -u --recursive --new-file v2.3.47/linux/drivers/char/nwflash.c linux/drivers/char/nwflash.c
--- v2.3.47/linux/drivers/char/nwflash.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/nwflash.c	Thu Feb 24 22:56:47 2000
@@ -0,0 +1,708 @@
+/*
+ * Flash memory interface rev.5 driver for the Intel
+ * Flash chips used on the NetWinder.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+
+#include <asm/dec21285.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+/*****************************************************************************/
+#include <asm/nwflash.h>
+
+//#define MINIKERNEL 1          //export flash write, erase routines for MiniKernel
+
+#ifndef MINIKERNEL
+#define MSTATIC static
+#else
+#define MSTATIC
+#endif
+
+#define	NWFLASH_VERSION "6.2"
+
+MSTATIC void kick_open(void);
+MSTATIC int get_flash_id(void);
+MSTATIC int erase_block(int nBlock);
+MSTATIC int write_block(unsigned long p, const char *buf, int count);
+static int open_flash(struct inode *inodep, struct file *filep);
+static int release_flash(struct inode *inodep, struct file *filep);
+static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg);
+static ssize_t flash_read(struct file *file, char *buf, size_t count, loff_t * ppos);
+static ssize_t flash_write(struct file *file, const char *buf, size_t count, loff_t * ppos);
+static long long flash_llseek(struct file *file, long long offset, int orig);
+
+#define KFLASH_SIZE	1024*1024	//1 Meg
+#define KFLASH_SIZE4	4*1024*1024	//4 Meg
+#define KFLASH_ID	0x89A6		//Intel flash
+#define KFLASH_ID4	0xB0D4		//Intel flash 4Meg
+
+static int flashdebug = 0;	//if set - we will display progress msgs
+
+static int gbWriteEnable = 0;
+static int gbWriteBase64Enable = 0;
+MSTATIC int gbFlashSize = KFLASH_SIZE;
+
+extern spinlock_t gpio_lock;
+
+static struct file_operations flash_fops =
+{
+	flash_llseek,		/* llseek			 */
+	flash_read,		/* read				 */
+	flash_write,		/* write			 */
+	NULL,			/* no special readdir            */
+	NULL,			/* no special select             */
+	flash_ioctl,
+	NULL,			/* no special mmap               */
+	open_flash,
+	NULL,			/* no special flush		 */
+	release_flash,
+	NULL,			/* no special fsync              */
+	NULL,			/* no special fasync             */
+	NULL,			/* no special check_media_change */
+	NULL			/* no special revaldate          */
+};
+
+static struct miscdevice flash_miscdev =
+{
+	FLASH_MINOR,
+	"nwflash",
+	&flash_fops
+};
+
+/*
+ * the delay routine - it is often required to let the flash "breeze"...
+ */
+void flash_wait(int timeout)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule_timeout(timeout);
+}
+
+MSTATIC int get_flash_id(void)
+{
+	volatile unsigned int c1, c2;
+
+	/*
+	 * try to get flash chip ID
+	 */
+	kick_open();
+	c2 = inb(0x80);
+	*(unsigned char *) (FLASH_BASE + 0x8000) = 0x90;
+	udelay(15);
+	c1 = *(unsigned char *) FLASH_BASE;
+	c2 = inb(0x80);
+
+	/*
+	 * on 4 Meg flash the second byte is actually at offset 2...
+	 */
+	if (c1 == 0xB0)
+		c2 = *(unsigned char *) (FLASH_BASE + 2);
+	else
+		c2 = *(unsigned char *) (FLASH_BASE + 1);
+
+	c2 += (c1 << 8);
+
+	/*
+	 * set it back to read mode
+	 */
+	*(unsigned char *) (FLASH_BASE + 0x8000) = 0xFF;
+
+	if (c2 == KFLASH_ID4)
+		gbFlashSize = KFLASH_SIZE4;
+
+	return c2;
+}
+
+static int open_flash(struct inode *inodep, struct file *filep)
+{
+	int id;
+
+	id = get_flash_id();
+	if ((id != KFLASH_ID) && (id != KFLASH_ID4)) {
+		printk("Flash: incorrect ID 0x%04X.\n", id);
+		return -ENXIO;
+	}
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+
+static int release_flash(struct inode *inodep, struct file *filep)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+
+static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg)
+{
+//      printk("Flash_ioctl: cmd = 0x%X.\n",cmd);
+
+	switch (cmd) {
+	case CMD_WRITE_DISABLE:
+		gbWriteBase64Enable = 0;
+		gbWriteEnable = 0;
+		break;
+
+	case CMD_WRITE_ENABLE:
+		gbWriteEnable = 1;
+		break;
+
+	case CMD_WRITE_BASE64K_ENABLE:
+		gbWriteBase64Enable = 1;
+		break;
+
+	default:
+		gbWriteBase64Enable = 0;
+		gbWriteEnable = 0;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+
+static ssize_t flash_read(struct file *file, char *buf, size_t count, loff_t * ppos)
+{
+	unsigned long p = file->f_pos;
+	int read;
+
+	if (flashdebug)
+		printk("Flash_dev: flash_read: offset=0x%X, buffer=0x%X, count=0x%X.\n",
+		       (unsigned int) p, (unsigned int) buf, count);
+
+
+	if (count < 0)
+		return -EINVAL;
+
+	if (count > gbFlashSize - p)
+		count = gbFlashSize - p;
+
+	/*
+	 * flash virtual address
+	 */
+	p += FLASH_BASE;
+
+	read = 0;
+
+	if (copy_to_user(buf, (void *) p, count))
+		return -EFAULT;
+	read += count;
+	file->f_pos += read;
+	return read;
+}
+
+static ssize_t flash_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
+{
+	unsigned long p = file->f_pos;
+	int written;
+	int nBlock, temp, rc;
+	int i, j;
+
+
+	if (flashdebug)
+		printk("Flash_dev: flash_write: offset=0x%X, buffer=0x%X, count=0x%X.\n",
+		       (unsigned int) p, (unsigned int) buf, count);
+
+	if (!gbWriteEnable)
+		return -EINVAL;
+
+	if (p < 64 * 1024 && (!gbWriteBase64Enable))
+		return -EINVAL;
+
+	if (count < 0)
+		return -EINVAL;
+
+	/*
+	 * if write size to big - error!
+	 */
+	if (count > gbFlashSize - p)
+		return -EINVAL;
+
+
+	if (verify_area(VERIFY_READ, buf, count))
+		return -EFAULT;
+
+
+	written = 0;
+
+	leds_event(led_claim);
+	leds_event(led_green_on);
+
+	nBlock = (int) p >> 16;	//block # of 64K bytes
+
+	/*
+	 * # of 64K blocks to erase and write
+	 */
+	temp = ((int) (p + count) >> 16) - nBlock + 1;
+
+	/*
+	 * write ends at exactly 64k boundry?
+	 */
+	if (((int) (p + count) & 0xFFFF) == 0)
+		temp -= 1;
+
+	if (flashdebug)
+		printk("FlashWrite: writing %d block(s) starting at %d.\n", temp, nBlock);
+
+	for (; temp; temp--, nBlock++) {
+		if (flashdebug)
+			printk("FlashWrite: erasing block %d.\n", nBlock);
+
+		/*
+		 * first we have to erase the block(s), where we will write...
+		 */
+		i = 0;
+		j = 0;
+	  RetryBlock:
+		do {
+			rc = erase_block(nBlock);
+			i++;
+		} while (rc && i < 10);
+
+		if (rc) {
+			if (flashdebug)
+				printk("FlashWrite: erase error %X. Aborting...\n", rc);
+
+			break;
+		}
+		if (flashdebug)
+			printk("FlashWrite: writing offset %X, from buf %X, bytes left %X.\n",
+			       (unsigned int) p, (unsigned int) buf, count - written);
+
+		/*
+		 * write_block will limit write to space left in this block
+		 */
+		rc = write_block(p, buf, count - written);
+		j++;
+
+		/*
+		 * if somehow write verify failed? Can't happen??
+		 */
+		if (!rc) {
+			/*
+			 * retry up to 10 times
+			 */
+			if (j < 10)
+				goto RetryBlock;
+			else
+				/*
+				 * else quit with error...
+				 */
+				rc = -1;
+
+		}
+		if (rc < 0) {
+			if (flashdebug)
+				printk("FlashWrite: write error %X. Aborting...\n", rc);
+			break;
+		}
+		p += rc;
+		buf += rc;
+		written += rc;
+		file->f_pos += rc;
+
+		if (flashdebug)
+			printk("FlashWrite: written 0x%X bytes OK.\n", written);
+	}
+
+	/*
+	 * restore reg on exit
+	 */
+	leds_event(led_release);
+
+	return written;
+}
+
+
+/*
+ * The memory devices use the full 32/64 bits of the offset, and so we cannot
+ * check against negative addresses: they are ok. The return value is weird,
+ * though, in that case (0).
+ *
+ * also note that seeking relative to the "end of file" isn't supported:
+ * it has no meaning, so it returns -EINVAL.
+ */
+static long long flash_llseek(struct file *file, long long offset, int orig)
+{
+	if (flashdebug)
+		printk("Flash_dev: flash_lseek, offset=0x%X, orig=0x%X.\n",
+		       (unsigned int) offset, (unsigned int) orig);
+
+	switch (orig) {
+	case 0:
+		if (offset < 0)
+			return -EINVAL;
+
+		if ((unsigned int) offset > gbFlashSize)
+			return -EINVAL;
+
+		file->f_pos = (unsigned int) offset;
+		return file->f_pos;
+	case 1:
+		if ((file->f_pos + offset) > gbFlashSize)
+			return -EINVAL;
+		if ((file->f_pos + offset) < 0)
+			return -EINVAL;
+		file->f_pos += offset;
+		return file->f_pos;
+	default:
+		return -EINVAL;
+	}
+}
+
+
+/*
+ * assume that main Write routine did the parameter checking...
+ * so just go ahead and erase, what requested!
+ */
+
+MSTATIC int erase_block(int nBlock)
+{
+	volatile unsigned int c1;
+	volatile unsigned char *pWritePtr;
+	int temp, temp1;
+
+	/*
+	 * orange LED == erase
+	 */
+	leds_event(led_amber_on);
+
+	/*
+	 * reset footbridge to the correct offset 0 (...0..3)
+	 */
+	*CSR_ROMWRITEREG = 0;
+
+	/*
+	 * dummy ROM read
+	 */
+	c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
+
+	kick_open();
+	/*
+	 * reset status if old errors
+	 */
+	*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
+
+	/*
+	 * erase a block...
+	 * aim at the middle of a current block...
+	 */
+	pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + 0x8000 + (nBlock << 16)));
+	/*
+	 * dummy read
+	 */
+	c1 = *pWritePtr;
+
+	kick_open();
+	/*
+	 * erase
+	 */
+	*(volatile unsigned char *) pWritePtr = 0x20;
+
+	/*
+	 * confirm
+	 */
+	*(volatile unsigned char *) pWritePtr = 0xD0;
+
+	/*
+	 * wait 10 ms
+	 */
+	flash_wait(HZ / 100);
+
+	/*
+	 * wait while erasing in process (up to 10 sec)
+	 */
+	temp = jiffies + 10 * HZ;
+	c1 = 0;
+	while (!(c1 & 0x80) && time_before(jiffies, temp)) {
+		flash_wait(HZ / 100);
+		/*
+		 * read any address
+		 */
+		c1 = *(volatile unsigned char *) (pWritePtr);
+		//              printk("Flash_erase: status=%X.\n",c1);
+	}
+
+	/*
+	 * set flash for normal read access
+	 */
+	kick_open();
+//      *(volatile unsigned char*)(FLASH_BASE+0x8000) = 0xFF;
+	*(volatile unsigned char *) pWritePtr = 0xFF;	//back to normal operation
+
+	/*
+	 * check if erase errors were reported
+	 */
+	if (c1 & 0x20) {
+		if (flashdebug)
+			printk("Flash_erase: err at %X.\n", (unsigned int) pWritePtr);
+		/*
+		 * reset error
+		 */
+		*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
+
+		return -2;
+	}
+
+	/*
+	 * just to make sure - verify if erased OK...
+	 */
+	flash_wait(HZ / 100);
+
+	pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + (nBlock << 16)));
+
+	for (temp = 0; temp < 16 * 1024; temp++, pWritePtr += 4) {
+		if ((temp1 = *(volatile unsigned int *) pWritePtr) != 0xFFFFFFFF) {
+			if (flashdebug)
+				printk("Flash_erase: verify err at %X = %X.\n",
+				       (unsigned int) pWritePtr, temp1);
+			return -1;
+		}
+	}
+
+	return 0;
+
+}
+
+/*
+ * write_block will limit number of bytes written to the space in this block
+ */
+MSTATIC int write_block(unsigned long p, const char *buf, int count)
+{
+	volatile unsigned int c1;
+	volatile unsigned int c2;
+	unsigned char *pWritePtr;
+	unsigned int uAddress;
+	unsigned int offset;
+	unsigned int timeout;
+	unsigned int timeout1;
+
+	/*
+	 * red LED == write
+	 */
+	leds_event(led_amber_off);
+	leds_event(led_red_on);
+
+	pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
+
+	/*
+	 * check if write will end in this block....
+	 */
+	offset = p & 0xFFFF;
+
+	if (offset + count > 0x10000)
+		count = 0x10000 - offset;
+
+	/*
+	 * wait up to 30 sec for this block
+	 */
+	timeout = jiffies + 30 * HZ;
+
+	for (offset = 0; offset < count; offset++, pWritePtr++) {
+		uAddress = (unsigned int) pWritePtr;
+		uAddress &= 0xFFFFFFFC;
+		if (__get_user(c2, buf + offset))
+			return -EFAULT;
+
+	  WriteRetry:
+	  	/*
+	  	 * dummy read
+	  	 */
+		c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
+
+		/*
+		 * kick open the write gate
+		 */
+		kick_open();
+
+		/*
+		 * program footbridge to the correct offset...0..3
+		 */
+		*CSR_ROMWRITEREG = (unsigned int) pWritePtr & 3;
+
+		/*
+		 * write cmd
+		 */
+		*(volatile unsigned char *) (uAddress) = 0x40;
+
+		/*
+		 * data to write
+		 */
+		*(volatile unsigned char *) (uAddress) = c2;
+
+		/*
+		 * get status
+		 */
+		*(volatile unsigned char *) (FLASH_BASE + 0x10000) = 0x70;
+
+		c1 = 0;
+
+		/*
+		 * wait up to 1 sec for this byte
+		 */
+		timeout1 = jiffies + 1 * HZ;
+
+		/*
+		 * while not ready...
+		 */
+		while (!(c1 & 0x80) && time_before(jiffies, timeout1))
+			c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
+
+		/*
+		 * if timeout getting status
+		 */
+		if (time_after_eq(jiffies, timeout1)) {
+			kick_open();
+			/*
+			 * reset err
+			 */
+			*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
+
+			goto WriteRetry;
+		}
+		/*
+		 * switch on read access, as a default flash operation mode
+		 */
+		kick_open();
+		/*
+		 * read access
+		 */
+		*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0xFF;
+
+		/*
+		 * if hardware reports an error writing, and not timeout - 
+		 * reset the chip and retry
+		 */
+		if (c1 & 0x10) {
+			kick_open();
+			/*
+			 * reset err
+			 */
+			*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
+
+			/*
+			 * before timeout?
+			 */
+			if (time_before(jiffies, timeout)) {
+				if (flashdebug)
+					printk("FlashWrite: Retrying write (addr=0x%X)...\n",
+					       (unsigned int) pWritePtr - FLASH_BASE);
+
+				/*
+				 * no LED == waiting
+				 */
+				leds_event(led_amber_off);
+				/*
+				 * wait couple ms
+				 */
+				flash_wait(HZ / 100);
+				/*
+				 * red LED == write
+				 */
+				leds_event(led_red_on);
+
+				goto WriteRetry;
+			} else {
+				printk("Timeout in flash write! (addr=0x%X) Aborting...\n",
+				 (unsigned int) pWritePtr - FLASH_BASE);
+				/*
+				 * return error -2
+				 */
+				return -2;
+
+			}
+		}
+	}
+
+	/*
+	 * green LED == read/verify
+	 */
+	leds_event(led_amber_off);
+	leds_event(led_green_on);
+
+	flash_wait(HZ / 100);
+
+	pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
+
+	for (offset = 0; offset < count; offset++) {
+		char c, c1;
+		if (__get_user(c, buf))
+			return -EFAULT;
+		buf++;
+		if ((c1 = *pWritePtr++) != c) {
+			if (flashdebug)
+				printk("flash write verify error at 0x%X! (%02X!=%02X) Retrying...\n",
+				       (unsigned int) pWritePtr, c1, c);
+			return 0;
+		}
+	}
+
+	return count;
+}
+
+
+MSTATIC void kick_open(void)
+{
+	unsigned long flags;
+
+	/*
+	 * we want to write a bit pattern XXX1 to Xilinx to enable
+	 * the write gate, which will be open for about the next 2ms.
+	 */
+	spin_lock_irqsave(&gpio_lock, flags);
+	cpld_modify(1, 1);
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	/*
+	 * let the ISA bus to catch on...
+	 */
+	udelay(25);
+}
+
+MSTATIC int __init nwflash_init(void)
+{
+	int ret = -ENODEV;
+
+	if (machine_is_netwinder()) {
+		int id;
+
+		id = get_flash_id();
+		printk("Flash ROM driver v.%s, flash device ID 0x%04X, size %d Mb.\n",
+		       NWFLASH_VERSION, id, gbFlashSize / (1024 * 1024));
+
+		misc_register(&flash_miscdev);
+
+		ret = 0;
+	}
+
+	return ret;
+}
+
+MSTATIC void __exit nwflash_exit(void)
+{
+	misc_deregister(&flash_miscdev);
+}
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_PARM(flashdebug, "i");
+
+module_init(nwflash_init);
+module_exit(nwflash_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/char/raw.c linux/drivers/char/raw.c
--- v2.3.47/linux/drivers/char/raw.c	Thu Feb 10 17:11:08 2000
+++ linux/drivers/char/raw.c	Thu Feb 24 10:30:25 2000
@@ -197,7 +197,12 @@
 			raw_device_bindings[minor] = 
 				bdget(kdev_t_to_nr(MKDEV(rq.block_major, rq.block_minor)));
 		} else {
-			kdev_t dev=to_kdev_t(raw_device_bindings[minor]->bd_dev);
+			kdev_t dev;
+			if (!raw_device_bindings[minor]) {
+				err = -ENODEV;
+				break;
+			}
+			dev = to_kdev_t(raw_device_bindings[minor]->bd_dev);
 			rq.block_major = MAJOR(dev);
 			rq.block_minor = MINOR(dev);
 			err = copy_to_user((void *) arg, &rq, sizeof(rq));
diff -u --recursive --new-file v2.3.47/linux/drivers/char/rtc.c linux/drivers/char/rtc.c
--- v2.3.47/linux/drivers/char/rtc.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/char/rtc.c	Tue Feb 22 22:39:33 2000
@@ -36,9 +36,11 @@
  *	1.09b	Jeff Garzik: Modularize, init cleanup
  *	1.09c	Jeff Garzik: SMP cleanup
  *	1.10    Paul Barton-Davis: add support for async I/O
+ *	1.10a	Andrea Arcangeli: Alpha updates
+ *	1.10b	Andrew Morton: SMP lock fix
  */
 
-#define RTC_VERSION		"1.10"
+#define RTC_VERSION		"1.10b"
 
 #define RTC_IRQ 	8	/* Can't see this changing soon.	*/
 #define RTC_IO_EXTENT	0x10	/* Only really two ports, but...	*/
@@ -378,7 +380,7 @@
 		if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
 		    || RTC_ALWAYS_BCD) {
 			if (yrs > 169) {
-				restore_flags(flags);
+				spin_unlock_irqrestore(&rtc_lock, flags);
 				return -EINVAL;
 			}
 			if (yrs >= 100)
@@ -704,7 +706,9 @@
 	free_irq (rtc_irq, &rtc_port);
 #else
 	release_region (RTC_PORT (0), RTC_IO_EXTENT);
+#ifndef __alpha__
 	free_irq (RTC_IRQ, NULL);
+#endif
 #endif /* __sparc__ */
 }
 
diff -u --recursive --new-file v2.3.47/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v2.3.47/linux/drivers/char/serial.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/char/serial.c	Fri Feb 25 10:26:42 2000
@@ -4183,6 +4183,16 @@
 	{	PCI_VENDOR_ID_ROCKWELL, 0x1004,
 		0x1048, 0x1500, 
 		SPCI_FL_BASE1, 1, 115200 },
+#ifdef CONFIG_DDB5074
+	/*
+	 * NEC Vrc-5074 (Nile 4) builtin UART.
+	 * Conditionally compiled in since this is a motherboard device.
+	 */
+	{	PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NILE4,
+		PCI_ANY_ID, PCI_ANY_ID,
+		SPCI_FL_BASE0, 1, 520833,
+		64, 3, NULL, 0x300 },
+#endif
 	/* Generic serial board */
 	{	0, 0,
 		0, 0,
diff -u --recursive --new-file v2.3.47/linux/drivers/char/vino.c linux/drivers/char/vino.c
--- v2.3.47/linux/drivers/char/vino.c	Tue Aug 31 17:29:13 1999
+++ linux/drivers/char/vino.c	Fri Feb 25 10:26:42 2000
@@ -1,4 +1,4 @@
-/* $Id: vino.c,v 1.4 1999/02/09 23:59:36 ulfc Exp $
+/* $Id: vino.c,v 1.5 1999/10/09 00:01:14 ralf Exp $
  * drivers/char/vino.c
  *
  * (incomplete) Driver for the Vino Video input system found in SGI Indys.
diff -u --recursive --new-file v2.3.47/linux/drivers/char/vt.c linux/drivers/char/vt.c
--- v2.3.47/linux/drivers/char/vt.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/char/vt.c	Fri Feb 25 10:26:42 2000
@@ -62,7 +62,7 @@
  */
 unsigned char keyboard_type = KB_101;
 
-#if !defined(__alpha__) && !defined(__arm__)
+#if !defined(__alpha__) && !defined(__mips__) && !defined(__arm__)
 asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on);
 #endif
 
@@ -90,7 +90,7 @@
  */
 
 #if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \
-    || (defined(__mips__) && !defined(CONFIG_SGI)) \
+    || (defined(__mips__) && !defined(CONFIG_SGI_IP22)) \
     || (defined(__arm__) && defined(CONFIG_HOST_FOOTBRIDGE))
 
 static void
@@ -473,7 +473,7 @@
 		ucval = keyboard_type;
 		goto setchar;
 
-#if !defined(__alpha__) && !defined(__arm__)
+#if !defined(__alpha__) && !defined(__mips__) && !defined(__arm__)
 		/*
 		 * These cannot be implemented on any machine that implements
 		 * ioperm() in user level (such as Alpha PCs).
diff -u --recursive --new-file v2.3.47/linux/drivers/char/wdt285.c linux/drivers/char/wdt285.c
--- v2.3.47/linux/drivers/char/wdt285.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/wdt285.c	Thu Feb 24 22:56:47 2000
@@ -0,0 +1,204 @@
+/*
+ *	Intel 21285 watchdog driver
+ *	Copyright (c) Phil Blundell <pb@nexus.co.uk>, 1998
+ *
+ *	based on
+ *
+ *	SoftDog	0.05:	A Software Watchdog Device
+ *
+ *	(c) Copyright 1996 Alan Cox <alan@cymru.net>, All Rights Reserved.
+ *				http://www.cymru.net
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *	
+ */
+ 
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/hardware.h>
+#include <asm/system.h>
+#include <asm/dec21285.h>
+
+/*
+ * Define this to stop the watchdog actually rebooting the machine.
+ */
+#undef ONLY_TESTING
+
+#define TIMER_MARGIN	60		/* (secs) Default is 1 minute */
+
+#define FCLK	(50*1000*1000)		/* 50MHz */
+
+static int soft_margin = TIMER_MARGIN;	/* in seconds */
+static int timer_alive = 0;
+
+#ifdef ONLY_TESTING
+/*
+ *	If the timer expires..
+ */
+
+static void watchdog_fire(int irq, void *dev_id, struct pt_regs *regs)
+{
+	printk(KERN_CRIT "Watchdog: Would Reboot.\n");
+	*CSR_TIMER4_CNTL = 0;
+	*CSR_TIMER4_CLR = 0;
+}
+#endif
+
+static void watchdog_ping(void)
+{
+	/*
+	 *	Refresh the timer.
+	 */
+	*CSR_TIMER4_LOAD = soft_margin * (FCLK / 256);
+}
+
+/*
+ *	Allow only one person to hold it open
+ */
+ 
+static int watchdog_open(struct inode *inode, struct file *file)
+{
+	if(timer_alive)
+		return -EBUSY;
+	MOD_INC_USE_COUNT;
+	/*
+	 *	Ahead watchdog factor ten, Mr Sulu
+	 */
+	*CSR_TIMER4_CLR = 0;
+	watchdog_ping();
+	*CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD 
+		| TIMER_CNTL_DIV256;
+#ifdef ONLY_TESTING
+	request_irq(IRQ_TIMER4, watchdog_fire, 0, "watchdog", NULL);
+#else
+	*CSR_SA110_CNTL |= 1 << 13;
+#endif
+	timer_alive = 1;
+	return 0;
+}
+
+static int watchdog_release(struct inode *inode, struct file *file)
+{
+#ifdef ONLY_TESTING
+	free_irq(IRQ_TIMER4, NULL);
+	timer_alive = 0;
+	MOD_DEC_USE_COUNT;
+#else
+	/*
+	 *	It's irreversible!
+	 */
+#endif
+	return 0;
+}
+
+static ssize_t watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+	/*  Can't seek (pwrite) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	/*
+	 *	Refresh the timer.
+	 */
+	if(len)
+	{
+		watchdog_ping();
+		return 1;
+	}
+	return 0;
+}
+
+static int watchdog_ioctl(struct inode *inode, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+	int i;
+	static struct watchdog_info ident=
+	{
+		0,
+		0,
+		"Footbridge Watchdog"
+	};
+	switch(cmd)
+	{
+		default:
+			return -ENOIOCTLCMD;
+		case WDIOC_GETSUPPORT:
+			i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct watchdog_info));
+			if (i)
+				return i;
+			else
+				return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident));
+		case WDIOC_GETSTATUS:
+		case WDIOC_GETBOOTSTATUS:
+			return put_user(0,(int *)arg);
+		case WDIOC_KEEPALIVE:
+			watchdog_ping();
+			return 0;
+	}
+}
+
+static struct file_operations watchdog_fops=
+{
+	NULL,		/* Seek */
+	NULL,		/* Read */
+	watchdog_write,	/* Write */
+	NULL,		/* Readdir */
+	NULL,		/* Select */
+	watchdog_ioctl,	/* Ioctl */
+	NULL,		/* MMap */
+	watchdog_open,
+	NULL,		/* flush */
+	watchdog_release,
+	NULL,		
+	NULL		/* Fasync */
+};
+
+static struct miscdevice watchdog_miscdev=
+{
+	WATCHDOG_MINOR,
+	"watchdog",
+	&watchdog_fops
+};
+
+static int __init footbridge_watchdog_init(void)
+{
+	if (machine_is_netwinder())
+		return -ENODEV;
+
+	misc_register(&watchdog_miscdev);
+	printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n", 
+	       soft_margin);
+	if (machine_is_cats())
+		printk("Warning: Watchdog reset may not work on this machine.\n");
+	return 0;
+}
+
+static void __exit footbridge_watchdog_exit(void)
+{
+	misc_deregister(&watchdog_miscdev);
+}
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("Phil Blundell <pb@nexus.co.uk>");
+MODULE_DESCRIPTION("21285 watchdog driver");
+
+MODULE_PARM(soft_margin,"i");
+MODULE_PARM_DESC(soft_margin,"Watchdog timeout in seconds");
+
+module_init(footbridge_watchdog_init);
+module_exit(footbridge_watchdog_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/char/wdt977.c linux/drivers/char/wdt977.c
--- v2.3.47/linux/drivers/char/wdt977.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/wdt977.c	Thu Feb 24 22:56:47 2000
@@ -0,0 +1,204 @@
+/*
+ *	Wdt977	0.01:	A Watchdog Device for Netwinder W83977AF chip
+ *
+ *	(c) Copyright 1998 Rebel.com (Woody Suwalski <woody@netwinder.org>)
+ *
+ *			-----------------------
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ *			-----------------------
+ */
+ 
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+
+#define WATCHDOG_MINOR	130
+
+static	int timeout = 3;
+static	int timer_alive = 0;
+static	int testmode = 0;
+
+/*
+ *	Allow only one person to hold it open
+ */
+ 
+static int wdt977_open(struct inode *inode, struct file *file)
+{
+	if(timer_alive)
+		return -EBUSY;
+	MOD_INC_USE_COUNT;
+	timer_alive++;
+
+	//max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
+	if (timeout>255)
+	    timeout = 255;
+
+	printk(KERN_INFO "Watchdog: active, current timeout %d min.\n",timeout);
+
+	// unlock the SuperIO chip
+	outb(0x87,0x370); 
+	outb(0x87,0x370); 
+	
+	//select device Aux2 (device=8) and set watchdog regs F2, F3 and F4
+	//F2 has the timeout in minutes
+	//F3 could be set to the POWER LED blink (with GP17 set to PowerLed)
+	//   at timeout, and to reset timer on kbd/mouse activity (not now)
+	//F4 is used to just clear the TIMEOUT'ed state (bit 0)
+	
+	outb(0x07,0x370);
+	outb(0x08,0x371);
+	outb(0xF2,0x370);
+	outb(timeout,0x371);
+	outb(0xF3,0x370);
+	outb(0x00,0x371);	//another setting is 0E for kbd/mouse/LED
+	outb(0xF4,0x370);
+	outb(0x00,0x371);
+	
+	//at last select device Aux1 (dev=7) and set GP16 as a watchdog output
+	if (!testmode)
+	{
+		outb(0x07,0x370);
+		outb(0x07,0x371);
+		outb(0xE6,0x370);
+		outb(0x08,0x371);
+	}
+		
+	// lock the SuperIO chip
+	outb(0xAA,0x370); 
+
+	return 0;
+}
+
+static int wdt977_release(struct inode *inode, struct file *file)
+{
+	/*
+	 *	Shut off the timer.
+	 * 	Lock it in if it's a module and we defined ...NOWAYOUT
+	 */
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+
+	// unlock the SuperIO chip
+	outb(0x87,0x370); 
+	outb(0x87,0x370); 
+	
+	//select device Aux2 (device=8) and set watchdog regs F2,F3 and F4
+	//F3 is reset to its default state
+	//F4 can clear the TIMEOUT'ed state (bit 0) - back to default
+	//We can not use GP17 as a PowerLed, as we use its usage as a RedLed
+	
+	outb(0x07,0x370);
+	outb(0x08,0x371);
+	outb(0xF2,0x370);
+	outb(0xFF,0x371);
+	outb(0xF3,0x370);
+	outb(0x00,0x371);
+	outb(0xF4,0x370);
+	outb(0x00,0x371);
+	outb(0xF2,0x370);
+	outb(0x00,0x371);
+	
+	//at last select device Aux1 (dev=7) and set GP16 as a watchdog output
+	outb(0x07,0x370);
+	outb(0x07,0x371);
+	outb(0xE6,0x370);
+	outb(0x08,0x371);
+	
+	// lock the SuperIO chip
+	outb(0xAA,0x370);
+
+	MOD_DEC_USE_COUNT;
+	timer_alive=0;
+
+	printk(KERN_INFO "Watchdog: shutdown.\n");
+#endif
+	return 0;
+}
+
+static ssize_t wdt977_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+
+	//max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
+	if (timeout>255)
+	    timeout = 255;
+
+	/*
+	 *	Refresh the timer.
+	 */
+		
+	//we have a hw bug somewhere, so each 977 minute is actually only 30sec
+	//as such limit the max timeout to half of max of 255 minutes...
+//	if (timeout>126)
+//	    timeout = 126;
+	
+	// unlock the SuperIO chip
+	outb(0x87,0x370); 
+	outb(0x87,0x370); 
+	
+	//select device Aux2 (device=8) and kicks watchdog reg F2
+	//F2 has the timeout in minutes
+	
+	outb(0x07,0x370);
+	outb(0x08,0x371);
+	outb(0xF2,0x370);
+	outb(timeout,0x371);
+	
+	// lock the SuperIO chip
+	outb(0xAA,0x370); 
+	
+	return 1;
+}
+
+static struct file_operations wdt977_fops=
+{
+	NULL,		/* Seek */
+	NULL,		/* Read */
+	wdt977_write,	/* Write */
+	NULL,		/* Readdir */
+	NULL,		/* Select */
+	NULL,		/* Ioctl */
+	NULL,		/* MMap */
+	wdt977_open,
+	NULL,		/* flush */
+	wdt977_release,
+	NULL,		
+	NULL		/* Fasync */
+};
+
+static struct miscdevice wdt977_miscdev=
+{
+	WATCHDOG_MINOR,
+	"watchdog",
+	&wdt977_fops
+};
+
+static int __init nwwatchdog_init(void)
+{
+	if (!machine_is_netwinder())
+		return -ENODEV;
+
+	misc_register(&wdt977_miscdev);
+	printk(KERN_INFO "NetWinder Watchdog sleeping.\n");
+	return 0;
+}	
+
+static void __exit nwwatchdog_exit(void)
+{
+	misc_deregister(&wdt977_miscdev);
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(nwwatchdog_init);
+module_exit(nwwatchdog_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/i2c/i2c-core.c linux/drivers/i2c/i2c-core.c
--- v2.3.47/linux/drivers/i2c/i2c-core.c	Thu Feb 10 17:11:08 2000
+++ linux/drivers/i2c/i2c-core.c	Sat Feb 26 20:33:02 2000
@@ -101,10 +101,6 @@
 	read:		i2cproc_bus_read,
 };
 
-static struct inode_operations i2cproc_inode_operations = {
-	&i2cproc_operations
-};
-
 static int i2cproc_initialized = 0;
 
 #else /* undef CONFIG_PROC_FS */
@@ -163,7 +159,7 @@
 			       name);
 			return -ENOENT;
 		}
-		proc_entry->ops = &i2cproc_inode_operations;
+		proc_entry->proc_fops = &i2cproc_operations;
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27))
 		proc_entry->owner = THIS_MODULE;
 #else
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/avmb1/b1dma.c linux/drivers/isdn/avmb1/b1dma.c
--- v2.3.47/linux/drivers/isdn/avmb1/b1dma.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/avmb1/b1dma.c	Sat Feb 26 20:20:12 2000
@@ -1,11 +1,14 @@
 /*
- * $Id: b1dma.c,v 1.2 2000/01/25 14:44:47 calle Exp $
+ * $Id: b1dma.c,v 1.3 2000/02/26 01:00:53 keil Exp $
  * 
  * Common module for AVM B1 cards that support dma with AMCC
  * 
  * (c) Copyright 2000 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: b1dma.c,v $
+ * Revision 1.3  2000/02/26 01:00:53  keil
+ * changes from 2.3.47
+ *
  * Revision 1.2  2000/01/25 14:44:47  calle
  * typo in b1pciv4_detect().
  *
@@ -31,7 +34,7 @@
 #include "capicmd.h"
 #include "capiutil.h"
 
-static char *revision = "$Revision: 1.2 $";
+static char *revision = "$Revision: 1.3 $";
 
 /* ------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c
--- v2.3.47/linux/drivers/isdn/avmb1/capi.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/avmb1/capi.c	Sat Feb 26 20:20:12 2000
@@ -1,11 +1,14 @@
 /*
- * $Id: capi.c,v 1.22 1999/11/13 21:27:16 keil Exp $
+ * $Id: capi.c,v 1.23 2000/02/26 01:00:53 keil Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
  * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de)
  *
  * $Log: capi.c,v $
+ * Revision 1.23  2000/02/26 01:00:53  keil
+ * changes from 2.3.47
+ *
  * Revision 1.22  1999/11/13 21:27:16  keil
  * remove KERNELVERSION
  *
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/divert/divert_procfs.c linux/drivers/isdn/divert/divert_procfs.c
--- v2.3.47/linux/drivers/isdn/divert/divert_procfs.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/divert/divert_procfs.c	Sat Feb 26 20:33:02 2000
@@ -315,8 +315,6 @@
 	NULL			/* fsync */
 };
 
-struct inode_operations divert_file_inode_operations;
-
 /****************************/
 /* isdn subdir in /proc/net */
 /****************************/
@@ -342,9 +340,7 @@
 		remove_proc_entry("isdn", proc_net);
 		return (-1);
 	}
-	memset(&divert_file_inode_operations, 0, sizeof(struct inode_operations));
-	divert_file_inode_operations.default_file_ops = &isdn_fops;
-	isdn_divert_entry->ops = &divert_file_inode_operations;
+	isdn_divert_entry->proc_fops = &isdn_fops;
 #endif	/* CONFIG_PROC_FS */
 
 	return (0);
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/eicon/eicon_idi.c linux/drivers/isdn/eicon/eicon_idi.c
--- v2.3.47/linux/drivers/isdn/eicon/eicon_idi.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/eicon/eicon_idi.c	Sat Feb 26 20:20:12 2000
@@ -1,4 +1,4 @@
-/* $Id: eicon_idi.c,v 1.29 2000/01/23 21:21:23 armin Exp $
+/* $Id: eicon_idi.c,v 1.31 2000/02/22 16:26:40 armin Exp $
  *
  * ISDN lowlevel-module for Eicon active cards.
  *        IDI interface 
@@ -26,6 +26,13 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: eicon_idi.c,v $
+ * Revision 1.31  2000/02/22 16:26:40  armin
+ * Fixed membase error message.
+ * Fixed missing log buffer struct.
+ *
+ * Revision 1.30  2000/02/16 16:08:46  armin
+ * Fixed virtual channel handling of IDI.
+ *
  * Revision 1.29  2000/01/23 21:21:23  armin
  * Added new trace capability and some updates.
  * DIVA Server BRI now supports data for ISDNLOG.
@@ -149,7 +156,7 @@
 
 #undef EICON_FULL_SERVICE_OKTETT
 
-char *eicon_idi_revision = "$Revision: 1.29 $";
+char *eicon_idi_revision = "$Revision: 1.31 $";
 
 eicon_manifbuf *manbuf;
 
@@ -255,10 +262,10 @@
 }
 
 int
-idi_put_req(eicon_REQ *reqbuf, int rq, int signet)
+idi_put_req(eicon_REQ *reqbuf, int rq, int signet, int Ch)
 {
 	reqbuf->Req = rq;
-	reqbuf->ReqCh = 0;
+	reqbuf->ReqCh = Ch;
 	reqbuf->ReqId = 1;
 	reqbuf->XBuffer.length = 1;
 	reqbuf->XBuffer.P[0] = 0;
@@ -368,34 +375,34 @@
 			break;
 		case REMOVE:
 		case REMOVE|0x700:
-			idi_put_req(reqbuf, REMOVE, layer);
+			idi_put_req(reqbuf, REMOVE, layer, 0);
 			break;
 		case INDICATE_REQ:
-			idi_put_req(reqbuf, INDICATE_REQ, 0);
+			idi_put_req(reqbuf, INDICATE_REQ, 0, 0);
 			break;
 		case HANGUP:
-			idi_put_req(reqbuf, HANGUP, 0);
+			idi_put_req(reqbuf, HANGUP, 0, 0);
 			break;
 		case REJECT:
-			idi_put_req(reqbuf, REJECT, 0);
+			idi_put_req(reqbuf, REJECT, 0 ,0);
 			break;
 		case CALL_ALERT:
-			idi_put_req(reqbuf, CALL_ALERT, 0);
+			idi_put_req(reqbuf, CALL_ALERT, 0, 0);
 			break;
 		case CALL_RES:
 			idi_call_res_req(reqbuf, chan);
 			break;
 		case IDI_N_CONNECT|0x700:
-			idi_put_req(reqbuf, IDI_N_CONNECT, 1);
+			idi_put_req(reqbuf, IDI_N_CONNECT, 1, 0);
 			break;
 		case IDI_N_CONNECT_ACK|0x700:
-			idi_put_req(reqbuf, IDI_N_CONNECT_ACK, 1);
+			idi_put_req(reqbuf, IDI_N_CONNECT_ACK, 1, 0);
 			break;
 		case IDI_N_DISC|0x700:
-			idi_put_req(reqbuf, IDI_N_DISC, 1);
+			idi_put_req(reqbuf, IDI_N_DISC, 1, chan->e.IndCh);
 			break;
 		case IDI_N_DISC_ACK|0x700:
-			idi_put_req(reqbuf, IDI_N_DISC_ACK, 1);
+			idi_put_req(reqbuf, IDI_N_DISC_ACK, 1, chan->e.IndCh);
 			break;
 		default:
 			eicon_log(card, 1, "idi_req: Ch%d: Unknown request\n", chan->No);
@@ -813,6 +820,11 @@
 					message->osa[i] = buffer[pos++];
 				eicon_log(ccard, 2, "idi_inf: Ch%d: OSA=%s\n", chan->No, message->osa);
 				break;
+			case CAD:
+				pos += wlen;
+				eicon_log(ccard, 2, "idi_inf: Ch%d: Connected Address in ind, len:%x\n", 
+					chan->No, wlen);
+				break;
 			case BC:
 				if (wlen > sizeof(message->bc)) {
 					pos += wlen;
@@ -1206,7 +1218,7 @@
 	reqbuf = (eicon_REQ *)skb_put(skb, sizeof(eicon_t30_s) + sizeof(eicon_REQ));
 
 	reqbuf->Req = IDI_N_EDATA;
-	reqbuf->ReqCh = 0;
+	reqbuf->ReqCh = chan->e.IndCh;
 	reqbuf->ReqId = 1;
 
 	reqbuf->XBuffer.length = idi_fill_in_T30(chan, reqbuf->XBuffer.P);
@@ -2205,7 +2217,7 @@
 	reqbuf = (eicon_REQ *)skb_put(skb, 1 + len + sizeof(eicon_REQ));
 
 	reqbuf->Req = IDI_N_UDATA;
-	reqbuf->ReqCh = 0;
+	reqbuf->ReqCh = chan->e.IndCh;
 	reqbuf->ReqId = 1;
 
 	reqbuf->XBuffer.length = len + 1;
@@ -2322,7 +2334,7 @@
 		unsigned char data[1];
 	} *q;
 
-	if (!(p = kmalloc(buflen, GFP_KERNEL))) {
+	if (!(p = kmalloc(buflen, GFP_ATOMIC))) {
 		eicon_log(ccard, 1, "idi_err: Ch??: could not allocate trace buffer\n");
 		return;
 	}
@@ -2380,7 +2392,7 @@
 		return;
 	}
 	
-	if (ind->Ind != 8)
+	if ((ind->Ind != 8) && (ind->Ind != 0xc))
 		dlev = 144;
 	else
 		dlev = 128;
@@ -2634,6 +2646,7 @@
 				break; 
 			case IDI_N_CONNECT:
 				eicon_log(ccard, 16,"idi_ind: Ch%d: N_Connect\n", chan->No);
+				chan->e.IndCh = ind->IndCh;
 				if (chan->e.B2Id) idi_do_req(ccard, chan, IDI_N_CONNECT_ACK, 1);
 				if (chan->l2prot == ISDN_PROTO_L2_FAX) {
 					break;
@@ -2664,6 +2677,7 @@
 					idi_fax_hangup(ccard, chan);
 				}
 #endif
+				chan->e.IndCh = 0;
 				save_flags(flags);
 				cli();
 				chan->queued = 0;
@@ -2693,7 +2707,7 @@
 #endif
 				break; 
 			case IDI_N_DATA_ACK:
-				eicon_log(ccard, 16, "idi_ind: Ch%d: N_DATA_ACK\n", chan->No);
+				eicon_log(ccard, 128, "idi_ind: Ch%d: N_DATA_ACK\n", chan->No);
 				break;
 			case IDI_N_DATA:
 				skb_pull(skb, sizeof(eicon_IND) - 1);
@@ -2774,6 +2788,11 @@
 	} else {
 	/* Network layer */
 		switch(chan->e.Req & 0x0f) {
+			case IDI_N_CONNECT:
+				chan->e.IndCh = ack->RcCh;
+				eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
+					ack->RcId, ack->RcCh, ack->Reference);
+				break;
 			case IDI_N_MDATA:
 			case IDI_N_DATA:
 				if ((chan->e.Req & 0x0f) == IDI_N_DATA) {
@@ -2999,7 +3018,7 @@
 		        reqbuf->Req = IDI_N_DATA;
 			if (ack) reqbuf->Req |= N_D_BIT;
 		}	
-        	reqbuf->ReqCh = 0;
+        	reqbuf->ReqCh = chan->e.IndCh;
 	        reqbuf->ReqId = 1;
 		memcpy(&reqbuf->XBuffer.P, skb->data + offset, plen);
 		reqbuf->XBuffer.length = plen;
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/eicon/eicon_isa.c linux/drivers/isdn/eicon/eicon_isa.c
--- v2.3.47/linux/drivers/isdn/eicon/eicon_isa.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/eicon/eicon_isa.c	Sat Feb 26 20:20:12 2000
@@ -1,4 +1,4 @@
-/* $Id: eicon_isa.c,v 1.13 2000/01/23 21:21:23 armin Exp $
+/* $Id: eicon_isa.c,v 1.14 2000/02/22 16:26:40 armin Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  * Hardware-specific code for old ISA cards.
@@ -22,6 +22,10 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: eicon_isa.c,v $
+ * Revision 1.14  2000/02/22 16:26:40  armin
+ * Fixed membase error message.
+ * Fixed missing log buffer struct.
+ *
  * Revision 1.13  2000/01/23 21:21:23  armin
  * Added new trace capability and some updates.
  * DIVA Server BRI now supports data for ISDNLOG.
@@ -83,7 +87,7 @@
 #define release_shmem release_region
 #define request_shmem request_region
 
-char *eicon_isa_revision = "$Revision: 1.13 $";
+char *eicon_isa_revision = "$Revision: 1.14 $";
 
 #undef EICON_MCA_DEBUG
 
@@ -144,6 +148,9 @@
 	unsigned long amem;
 
 	if (!strlen(Id))
+		return -1;
+
+	if (Mem == -1)
 		return -1;
 
 	/* Check for valid membase address */
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/eicon/eicon_mod.c linux/drivers/isdn/eicon/eicon_mod.c
--- v2.3.47/linux/drivers/isdn/eicon/eicon_mod.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/eicon/eicon_mod.c	Sat Feb 26 20:20:12 2000
@@ -1,4 +1,4 @@
-/* $Id: eicon_mod.c,v 1.24 2000/01/23 21:21:23 armin Exp $
+/* $Id: eicon_mod.c,v 1.25 2000/02/22 16:26:40 armin Exp $
  *
  * ISDN lowlevel-module for Eicon active cards.
  * 
@@ -31,6 +31,10 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: eicon_mod.c,v $
+ * Revision 1.25  2000/02/22 16:26:40  armin
+ * Fixed membase error message.
+ * Fixed missing log buffer struct.
+ *
  * Revision 1.24  2000/01/23 21:21:23  armin
  * Added new trace capability and some updates.
  * DIVA Server BRI now supports data for ISDNLOG.
@@ -140,7 +144,7 @@
 static eicon_card *cards = (eicon_card *) NULL;   /* glob. var , contains
                                                      start of card-list   */
 
-static char *eicon_revision = "$Revision: 1.24 $";
+static char *eicon_revision = "$Revision: 1.25 $";
 
 extern char *eicon_pci_revision;
 extern char *eicon_isa_revision;
@@ -886,8 +890,10 @@
 	u_char *p;
 	struct sk_buff *skb;
 
-	if (!card)
-		return;
+	if (!card) {
+		if (!(card = cards))
+			return;
+	}
 
 	save_flags(flags);
 	cli();
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/avm_pci.c linux/drivers/isdn/hisax/avm_pci.c
--- v2.3.47/linux/drivers/isdn/hisax/avm_pci.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hisax/avm_pci.c	Sat Feb 26 20:20:12 2000
@@ -1,4 +1,4 @@
-/* $Id: avm_pci.c,v 1.14 1999/12/19 13:09:41 keil Exp $
+/* $Id: avm_pci.c,v 1.15 2000/02/26 00:35:12 keil Exp $
 
  * avm_pci.c    low level stuff for AVM Fritz!PCI and ISA PnP isdn cards
  *              Thanks to AVM, Berlin for informations
@@ -7,6 +7,9 @@
  *
  *
  * $Log: avm_pci.c,v $
+ * Revision 1.15  2000/02/26 00:35:12  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.14  1999/12/19 13:09:41  keil
  * changed TASK_INTERRUPTIBLE into TASK_UNINTERRUPTIBLE for
  * signal proof delays
@@ -63,7 +66,7 @@
 #include <linux/interrupt.h>
 
 extern const char *CardType[];
-static const char *avm_pci_rev = "$Revision: 1.14 $";
+static const char *avm_pci_rev = "$Revision: 1.15 $";
 
 #define  AVM_FRITZ_PCI		1
 #define  AVM_FRITZ_PNP		2
@@ -499,7 +502,7 @@
 				if (bcs->st->lli.l1writewakeup &&
 					(PACKET_NOACK != bcs->tx_skb->pkt_type))
 					bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hdlc.count);
-				dev_kfree_skb(bcs->tx_skb);
+				dev_kfree_skb_irq(bcs->tx_skb);
 				bcs->hw.hdlc.count = 0;
 				bcs->tx_skb = NULL;
 			}
@@ -626,7 +629,7 @@
 		discard_queue(&bcs->rqueue);
 		discard_queue(&bcs->squeue);
 		if (bcs->tx_skb) {
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			bcs->tx_skb = NULL;
 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 		}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c
--- v2.3.47/linux/drivers/isdn/hisax/config.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hisax/config.c	Sat Feb 26 20:20:12 2000
@@ -1,10 +1,13 @@
-/* $Id: config.c,v 2.43 2000/01/20 19:49:36 keil Exp $
+/* $Id: config.c,v 2.44 2000/02/26 00:35:12 keil Exp $
 
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
  *
  *
  * $Log: config.c,v $
+ * Revision 2.44  2000/02/26 00:35:12  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 2.43  2000/01/20 19:49:36  keil
  * Support teles 13.3c vendor version 2.1
  *
@@ -549,9 +552,9 @@
 
 	printk(KERN_INFO "HiSax: Linux Driver for passive ISDN cards\n");
 #ifdef MODULE
-	printk(KERN_INFO "HiSax: Version 3.3d (module)\n");
+	printk(KERN_INFO "HiSax: Version 3.3e (module)\n");
 #else
-	printk(KERN_INFO "HiSax: Version 3.3d (kernel)\n");
+	printk(KERN_INFO "HiSax: Version 3.3e (kernel)\n");
 #endif
 	strcpy(tmp, l1_revision);
 	printk(KERN_INFO "HiSax: Layer1 Revision %s\n", HiSax_getrev(tmp));
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/diva.c linux/drivers/isdn/hisax/diva.c
--- v2.3.47/linux/drivers/isdn/hisax/diva.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hisax/diva.c	Sat Feb 26 20:20:12 2000
@@ -1,4 +1,4 @@
-/* $Id: diva.c,v 1.18 1999/12/19 13:09:41 keil Exp $
+/* $Id: diva.c,v 1.19 2000/02/26 00:35:12 keil Exp $
 
  * diva.c     low level stuff for Eicon.Diehl Diva Family ISDN cards
  *
@@ -12,6 +12,9 @@
  *
  *
  * $Log: diva.c,v $
+ * Revision 1.19  2000/02/26 00:35:12  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.18  1999/12/19 13:09:41  keil
  * changed TASK_INTERRUPTIBLE into TASK_UNINTERRUPTIBLE for
  * signal proof delays
@@ -84,7 +87,7 @@
 
 extern const char *CardType[];
 
-const char *Diva_revision = "$Revision: 1.18 $";
+const char *Diva_revision = "$Revision: 1.19 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -585,7 +588,7 @@
 				if (bcs->st->lli.l1writewakeup &&
 					(PACKET_NOACK != bcs->tx_skb->pkt_type))
 					bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count);
-				dev_kfree_skb(bcs->tx_skb);
+				dev_kfree_skb_irq(bcs->tx_skb);
 				bcs->hw.hscx.count = 0; 
 				bcs->tx_skb = NULL;
 			}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/elsa_ser.c linux/drivers/isdn/hisax/elsa_ser.c
--- v2.3.47/linux/drivers/isdn/hisax/elsa_ser.c	Thu Nov 11 20:11:37 1999
+++ linux/drivers/isdn/hisax/elsa_ser.c	Sat Feb 26 20:20:12 2000
@@ -298,7 +298,7 @@
 				(PACKET_NOACK != bcs->tx_skb->pkt_type))
 					bcs->st->lli.l1writewakeup(bcs->st,
 						bcs->hw.hscx.count);
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			bcs->tx_skb = NULL;
 		}
 	}
@@ -442,13 +442,13 @@
 			bcs->hw.hscx.rcvbuf = NULL;
 		}
 		while ((skb = skb_dequeue(&bcs->rqueue))) {
-			dev_kfree_skb(skb);
+			dev_kfree_skb_any(skb);
 		}
 		while ((skb = skb_dequeue(&bcs->squeue))) {
-			dev_kfree_skb(skb);
+			dev_kfree_skb_any(skb);
 		}
 		if (bcs->tx_skb) {
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			bcs->tx_skb = NULL;
 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 		}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/hfc_2bds0.c linux/drivers/isdn/hisax/hfc_2bds0.c
--- v2.3.47/linux/drivers/isdn/hisax/hfc_2bds0.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hisax/hfc_2bds0.c	Sat Feb 26 20:20:12 2000
@@ -1,4 +1,4 @@
-/* $Id: hfc_2bds0.c,v 1.11 1999/12/23 15:09:32 keil Exp $
+/* $Id: hfc_2bds0.c,v 1.12 2000/02/26 00:35:12 keil Exp $
  *
  *  specific routines for CCD's HFC 2BDS0
  *
@@ -6,6 +6,9 @@
  *
  *
  * $Log: hfc_2bds0.c,v $
+ * Revision 1.12  2000/02/26 00:35:12  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.11  1999/12/23 15:09:32  keil
  * change email
  *
@@ -293,7 +296,7 @@
 			sti();
 			debugl1(cs, "RFIFO BUSY error");
 			printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel);
-			dev_kfree_skb(skb);
+			dev_kfree_skb_irq(skb);
 			skb = NULL;
 		} else {
 			cli();
@@ -309,7 +312,7 @@
 					bcs->channel, chksum, stat);
 			if (stat) {
 				debugl1(cs, "FIFO CRC error");
-				dev_kfree_skb(skb);
+				dev_kfree_skb_irq(skb);
 				skb = NULL;
 #ifdef ERROR_STATISTIC
 				bcs->err_crc++;
@@ -401,7 +404,7 @@
 		if (bcs->st->lli.l1writewakeup &&
 			(PACKET_NOACK != bcs->tx_skb->pkt_type))
 			bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len);
-		dev_kfree_skb(bcs->tx_skb);
+		dev_kfree_skb_any(bcs->tx_skb);
 		bcs->tx_skb = NULL;
 	}
 	WaitForBusy(cs);
@@ -603,7 +606,7 @@
 		discard_queue(&bcs->rqueue);
 		discard_queue(&bcs->squeue);
 		if (bcs->tx_skb) {
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			bcs->tx_skb = NULL;
 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 		}
@@ -751,7 +754,7 @@
 				sti();
 				debugl1(cs, "RFIFO D BUSY error");
 				printk(KERN_WARNING "HFC DFIFO channel BUSY Error\n");
-				dev_kfree_skb(skb);
+				dev_kfree_skb_irq(skb);
 				skb = NULL;
 #ifdef ERROR_STATISTIC
 				cs->err_rx++;
@@ -770,7 +773,7 @@
 						chksum, stat);
 				if (stat) {
 					debugl1(cs, "FIFO CRC error");
-					dev_kfree_skb(skb);
+					dev_kfree_skb_irq(skb);
 					skb = NULL;
 #ifdef ERROR_STATISTIC
 					cs->err_crc++;
@@ -870,7 +873,7 @@
 	cli();
 	WaitNoBusy(cs);
 	ReadReg(cs, HFCD_DATA, HFCD_FIFO | HFCD_F1_INC | HFCD_SEND);
-	dev_kfree_skb(cs->tx_skb);
+	dev_kfree_skb_any(cs->tx_skb);
 	cs->tx_skb = NULL;
 	sti();
 	WaitForBusy(cs);
@@ -1004,7 +1007,7 @@
 					}
 					goto afterXPR;
 				} else {
-					dev_kfree_skb(cs->tx_skb);
+					dev_kfree_skb_irq(cs->tx_skb);
 					cs->tx_cnt = 0;
 					cs->tx_skb = NULL;
 				}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/hfc_2bs0.c linux/drivers/isdn/hisax/hfc_2bs0.c
--- v2.3.47/linux/drivers/isdn/hisax/hfc_2bs0.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hisax/hfc_2bs0.c	Sat Feb 26 20:20:12 2000
@@ -1,4 +1,4 @@
-/* $Id: hfc_2bs0.c,v 1.12 1999/12/19 14:17:12 keil Exp $
+/* $Id: hfc_2bs0.c,v 1.13 2000/02/26 00:35:12 keil Exp $
 
  *  specific routines for CCD's HFC 2BS0
  *
@@ -6,6 +6,9 @@
  *
  *
  * $Log: hfc_2bs0.c,v $
+ * Revision 1.13  2000/02/26 00:35:12  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.12  1999/12/19 14:17:12  keil
  * fix compiler warning
  *
@@ -249,7 +252,7 @@
 		if (idx != count) {
 			debugl1(cs, "RFIFO BUSY error");
 			printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel);
-			dev_kfree_skb(skb);
+			dev_kfree_skb_any(skb);
 			if (bcs->mode != L1_MODE_TRANS) {
 			  WaitNoBusy(cs);
 			  stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
@@ -270,7 +273,7 @@
 			    bcs->channel, chksum, stat);
 		  if (stat) {
 		    debugl1(cs, "FIFO CRC error");
-		    dev_kfree_skb(skb);
+		    dev_kfree_skb_any(skb);
 		    skb = NULL;
 #ifdef ERROR_STATISTIC
 		    bcs->err_crc++;
@@ -359,7 +362,7 @@
 		bcs->tx_cnt -= count;
 		if (PACKET_NOACK == bcs->tx_skb->pkt_type)
 			count = -1;
-		dev_kfree_skb(bcs->tx_skb);
+		dev_kfree_skb_any(bcs->tx_skb);
 		bcs->tx_skb = NULL;
 		if (bcs->mode != L1_MODE_TRANS) {
 		  WaitForBusy(cs);
@@ -573,7 +576,7 @@
 		discard_queue(&bcs->rqueue);
 		discard_queue(&bcs->squeue);
 		if (bcs->tx_skb) {
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			bcs->tx_skb = NULL;
 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 		}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/hfc_pci.c linux/drivers/isdn/hisax/hfc_pci.c
--- v2.3.47/linux/drivers/isdn/hisax/hfc_pci.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hisax/hfc_pci.c	Sat Feb 26 20:20:12 2000
@@ -1,4 +1,4 @@
-/* $Id: hfc_pci.c,v 1.26 2000/02/09 20:22:55 werner Exp $
+/* $Id: hfc_pci.c,v 1.27 2000/02/26 00:35:12 keil Exp $
 
  * hfc_pci.c     low level driver for CCD´s hfc-pci based cards
  *
@@ -23,6 +23,9 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: hfc_pci.c,v $
+ * Revision 1.27  2000/02/26 00:35:12  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.26  2000/02/09 20:22:55  werner
  *
  * Updated PCI-ID table
@@ -126,7 +129,7 @@
 
 extern const char *CardType[];
 
-static const char *hfcpci_revision = "$Revision: 1.26 $";
+static const char *hfcpci_revision = "$Revision: 1.27 $";
 
 /* table entry in the PCI devices list */
 typedef struct {
@@ -636,7 +639,7 @@
 	df->f1 = new_f1;	/* next frame */
 	restore_flags(flags);
 
-	dev_kfree_skb(cs->tx_skb);
+	dev_kfree_skb_any(cs->tx_skb);
 	cs->tx_skb = NULL;
 	return;
 }
@@ -710,7 +713,7 @@
 				debugl1(cs, "hfcpci_fill_fifo_trans %d frame length %d discarded",
 					bcs->channel, bcs->tx_skb->len);
 
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			cli();
 			bcs->tx_skb = skb_dequeue(&bcs->squeue);	/* fetch next data */
 			sti();
@@ -778,7 +781,7 @@
 	bz->f1 = new_f1;	/* next frame */
 	restore_flags(flags);
 
-	dev_kfree_skb(bcs->tx_skb);
+	dev_kfree_skb_any(bcs->tx_skb);
 	bcs->tx_skb = NULL;
 	test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 	return;
@@ -1130,7 +1133,7 @@
 					}
 					goto afterXPR;
 				} else {
-					dev_kfree_skb(cs->tx_skb);
+					dev_kfree_skb_irq(cs->tx_skb);
 					cs->tx_cnt = 0;
 					cs->tx_skb = NULL;
 				}
@@ -1522,7 +1525,7 @@
 		discard_queue(&bcs->rqueue);
 		discard_queue(&bcs->squeue);
 		if (bcs->tx_skb) {
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			bcs->tx_skb = NULL;
 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 		}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/hfc_sx.c linux/drivers/isdn/hisax/hfc_sx.c
--- v2.3.47/linux/drivers/isdn/hisax/hfc_sx.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hisax/hfc_sx.c	Sat Feb 26 20:20:12 2000
@@ -1,4 +1,4 @@
-/* $Id: hfc_sx.c,v 1.3 2000/01/20 19:49:36 keil Exp $
+/* $Id: hfc_sx.c,v 1.4 2000/02/26 00:35:12 keil Exp $
 
  * hfc_sx.c     low level driver for CCD´s hfc-s+/sp based cards
  *
@@ -22,6 +22,9 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: hfc_sx.c,v $
+ * Revision 1.4  2000/02/26 00:35:12  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.3  2000/01/20 19:49:36  keil
  * Support teles 13.3c vendor version 2.1
  *
@@ -38,6 +41,7 @@
  *
  */
 
+#include <linux/config.h>
 #define __NO_VERSION__
 #include "hisax.h"
 #include "hfc_sx.h"
@@ -46,7 +50,7 @@
 
 extern const char *CardType[];
 
-static const char *hfcsx_revision = "$Revision: 1.3 $";
+static const char *hfcsx_revision = "$Revision: 1.4 $";
 
 /***************************************/
 /* IRQ-table for CCDs demo board       */
@@ -327,7 +331,7 @@
 	      Read_hfc(cs, HFCSX_FIF_DRD); /* CRC 1 */
 	      Read_hfc(cs, HFCSX_FIF_DRD); /* CRC 2 */
 	      if (Read_hfc(cs, HFCSX_FIF_DRD)) {
-		dev_kfree_skb(skb);
+		dev_kfree_skb_irq(skb);
 		if (cs->debug & L1_DEB_ISAC_FIFO)
 		  debugl1(cs, "hfcsx_read_fifo %d crc error", fifo);
 		skb = NULL;
@@ -600,7 +604,7 @@
 		return;
 
 	if (write_fifo(cs, cs->tx_skb, HFCSX_SEL_D_TX, 0)) {
-	  dev_kfree_skb(cs->tx_skb);
+	  dev_kfree_skb_any(cs->tx_skb);
 	  cs->tx_skb = NULL;
 	}
 	return;
@@ -633,7 +637,7 @@
 	  if (bcs->st->lli.l1writewakeup &&
 	      (PACKET_NOACK != bcs->tx_skb->pkt_type))
 	    bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len);
-	  dev_kfree_skb(bcs->tx_skb);
+	  dev_kfree_skb_any(bcs->tx_skb);
 	  bcs->tx_skb = NULL;
 	  test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 	}
@@ -777,7 +781,7 @@
 	      } else
 		HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", skb->len);
 	    }
-	    dev_kfree_skb(skb);
+	    dev_kfree_skb_any(skb);
 	  }
 	} while (--count && skb);
 
@@ -931,7 +935,7 @@
 					}
 					goto afterXPR;
 				} else {
-					dev_kfree_skb(cs->tx_skb);
+					dev_kfree_skb_irq(cs->tx_skb);
 					cs->tx_cnt = 0;
 					cs->tx_skb = NULL;
 				}
@@ -1305,7 +1309,7 @@
 		discard_queue(&bcs->rqueue);
 		discard_queue(&bcs->squeue);
 		if (bcs->tx_skb) {
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			bcs->tx_skb = NULL;
 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 		}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/hisax.h linux/drivers/isdn/hisax/hisax.h
--- v2.3.47/linux/drivers/isdn/hisax/hisax.h	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hisax/hisax.h	Sat Feb 26 20:20:12 2000
@@ -1,8 +1,11 @@
-/* $Id: hisax.h,v 2.40 2000/01/20 19:51:46 keil Exp $
+/* $Id: hisax.h,v 2.41 2000/02/26 00:35:13 keil Exp $
 
  *   Basic declarations, defines and prototypes
  *
  * $Log: hisax.h,v $
+ * Revision 2.41  2000/02/26 00:35:13  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 2.40  2000/01/20 19:51:46  keil
  * Fix AddTimer message
  * Change CONFIG defines
@@ -157,8 +160,9 @@
 #include <linux/isdnif.h>
 #include <linux/tty.h>
 #include <linux/serial_reg.h>
+#include <linux/netdevice.h>
 
-#undef ERROR_STATISTIC
+#define ERROR_STATISTIC
 
 #define REQUEST		0
 #define CONFIRM		1
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/hscx.c linux/drivers/isdn/hisax/hscx.c
--- v2.3.47/linux/drivers/isdn/hisax/hscx.c	Thu Nov 11 20:11:38 1999
+++ linux/drivers/isdn/hisax/hscx.c	Sat Feb 26 20:20:12 2000
@@ -1,4 +1,4 @@
-/* $Id: hscx.c,v 1.17 1999/07/01 08:11:41 keil Exp $
+/* $Id: hscx.c,v 1.18 2000/02/26 00:35:13 keil Exp $
 
  * hscx.c   HSCX specific routines
  *
@@ -6,6 +6,9 @@
  *
  *
  * $Log: hscx.c,v $
+ * Revision 1.18  2000/02/26 00:35:13  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.17  1999/07/01 08:11:41  keil
  * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel
  *
@@ -219,7 +222,7 @@
 		discard_queue(&bcs->rqueue);
 		discard_queue(&bcs->squeue);
 		if (bcs->tx_skb) {
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			bcs->tx_skb = NULL;
 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 		}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/hscx_irq.c linux/drivers/isdn/hisax/hscx_irq.c
--- v2.3.47/linux/drivers/isdn/hisax/hscx_irq.c	Thu Nov 11 20:11:38 1999
+++ linux/drivers/isdn/hisax/hscx_irq.c	Sat Feb 26 20:20:12 2000
@@ -1,4 +1,4 @@
-/* $Id: hscx_irq.c,v 1.13 1999/10/14 20:25:28 keil Exp $
+/* $Id: hscx_irq.c,v 1.14 2000/02/26 00:35:13 keil Exp $
 
  * hscx_irq.c     low level b-channel stuff for Siemens HSCX
  *
@@ -7,6 +7,9 @@
  * This is an include file for fast inline IRQ stuff
  *
  * $Log: hscx_irq.c,v $
+ * Revision 1.14  2000/02/26 00:35:13  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.13  1999/10/14 20:25:28  keil
  * add a statistic for error monitoring
  *
@@ -250,7 +253,7 @@
 				if (bcs->st->lli.l1writewakeup &&
 					(PACKET_NOACK != bcs->tx_skb->pkt_type))
 					bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count);
-				dev_kfree_skb(bcs->tx_skb);
+				dev_kfree_skb_irq(bcs->tx_skb);
 				bcs->hw.hscx.count = 0; 
 				bcs->tx_skb = NULL;
 			}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/isac.c linux/drivers/isdn/hisax/isac.c
--- v2.3.47/linux/drivers/isdn/hisax/isac.c	Thu Nov 11 20:11:38 1999
+++ linux/drivers/isdn/hisax/isac.c	Sat Feb 26 20:20:13 2000
@@ -1,4 +1,4 @@
-/* $Id: isac.c,v 1.24 1999/10/14 20:25:28 keil Exp $
+/* $Id: isac.c,v 1.25 2000/02/26 00:35:13 keil Exp $
 
  * isac.c   ISAC specific routines
  *
@@ -9,6 +9,9 @@
  *		../../../Documentation/isdn/HiSax.cert
  *
  * $Log: isac.c,v $
+ * Revision 1.25  2000/02/26 00:35:13  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.24  1999/10/14 20:25:28  keil
  * add a statistic for error monitoring
  *
@@ -338,7 +341,7 @@
 				isac_fill_fifo(cs);
 				goto afterXPR;
 			} else {
-				dev_kfree_skb(cs->tx_skb);
+				dev_kfree_skb_irq(cs->tx_skb);
 				cs->tx_cnt = 0;
 				cs->tx_skb = NULL;
 			}
@@ -627,7 +630,7 @@
 			discard_queue(&cs->rq);
 			discard_queue(&cs->sq);
 			if (cs->tx_skb) {
-				dev_kfree_skb(cs->tx_skb);
+				dev_kfree_skb_any(cs->tx_skb);
 				cs->tx_skb = NULL;
 			}
 			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
@@ -683,7 +686,7 @@
 			/* discard frame; reset transceiver */
 			test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags);
 			if (cs->tx_skb) {
-				dev_kfree_skb(cs->tx_skb);
+				dev_kfree_skb_any(cs->tx_skb);
 				cs->tx_cnt = 0;
 				cs->tx_skb = NULL;
 			} else {
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/isar.c linux/drivers/isdn/hisax/isar.c
--- v2.3.47/linux/drivers/isdn/hisax/isar.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hisax/isar.c	Sat Feb 26 20:20:13 2000
@@ -1,4 +1,4 @@
-/* $Id: isar.c,v 1.9 2000/01/20 19:47:45 keil Exp $
+/* $Id: isar.c,v 1.10 2000/02/26 00:35:13 keil Exp $
 
  * isar.c   ISAR (Siemens PSB 7110) specific routines
  *
@@ -6,6 +6,9 @@
  *
  *
  * $Log: isar.c,v $
+ * Revision 1.10  2000/02/26 00:35:13  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.9  2000/01/20 19:47:45  keil
  * Add Fax Class 1 support
  *
@@ -774,7 +777,7 @@
 					}
 				}
 			}
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			bcs->hw.isar.txcnt = 0; 
 			bcs->tx_skb = NULL;
 		}
@@ -1631,7 +1634,7 @@
 		discard_queue(&bcs->rqueue);
 		discard_queue(&bcs->squeue);
 		if (bcs->tx_skb) {
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			bcs->tx_skb = NULL;
 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 			if (bcs->cs->debug & L1_DEB_HSCX)
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/jade.c linux/drivers/isdn/hisax/jade.c
--- v2.3.47/linux/drivers/isdn/hisax/jade.c	Thu Nov 11 20:11:38 1999
+++ linux/drivers/isdn/hisax/jade.c	Sat Feb 26 20:20:13 2000
@@ -1,10 +1,13 @@
-/* $Id: jade.c,v 1.2 1999/07/01 08:07:57 keil Exp $
+/* $Id: jade.c,v 1.3 2000/02/26 00:35:13 keil Exp $
  *
  * jade.c   JADE stuff (derived from original hscx.c)
  *
  * Author   Roland Klabunde (R.Klabunde@Berkom.de)
  *
  * $Log: jade.c,v $
+ * Revision 1.3  2000/02/26 00:35:13  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.2  1999/07/01 08:07:57  keil
  * Initial version
  *
@@ -214,7 +217,7 @@
 	discard_queue(&bcs->rqueue);
 	discard_queue(&bcs->squeue);
 	if (bcs->tx_skb) {
-		dev_kfree_skb(bcs->tx_skb);
+		dev_kfree_skb_any(bcs->tx_skb);
 		bcs->tx_skb = NULL;
 		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 	}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/jade_irq.c linux/drivers/isdn/hisax/jade_irq.c
--- v2.3.47/linux/drivers/isdn/hisax/jade_irq.c	Thu Nov 11 20:11:38 1999
+++ linux/drivers/isdn/hisax/jade_irq.c	Sat Feb 26 20:20:13 2000
@@ -1,10 +1,13 @@
-/* $Id: jade_irq.c,v 1.2 1999/07/01 08:07:59 keil Exp $
+/* $Id: jade_irq.c,v 1.3 2000/02/26 00:35:13 keil Exp $
  *
  * jade_irq.c   Low level JADE IRQ stuff (derived from original hscx_irq.c)
  *
  * Author   Roland Klabunde (R.Klabunde@Berkom.de)
  *
  * $Log: jade_irq.c,v $
+ * Revision 1.3  2000/02/26 00:35:13  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.2  1999/07/01 08:07:59  keil
  * Initial version
  *
@@ -192,7 +195,7 @@
 				if (bcs->st->lli.l1writewakeup &&
 					(PACKET_NOACK != bcs->tx_skb->pkt_type))
 					bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count);
-				dev_kfree_skb(bcs->tx_skb);
+				dev_kfree_skb_irq(bcs->tx_skb);
 				bcs->hw.hscx.count = 0;
 				bcs->tx_skb = NULL;
 			}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/l3dss1.c linux/drivers/isdn/hisax/l3dss1.c
--- v2.3.47/linux/drivers/isdn/hisax/l3dss1.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hisax/l3dss1.c	Sat Feb 26 20:20:13 2000
@@ -1,4 +1,4 @@
-/* $Id: l3dss1.c,v 2.22 2000/01/20 19:44:20 keil Exp $
+/* $Id: l3dss1.c,v 2.23 2000/02/26 01:38:14 keil Exp $
 
  * EURO/DSS1 D-channel protocol
  *
@@ -13,6 +13,9 @@
  *              Fritz Elfert
  *
  * $Log: l3dss1.c,v $
+ * Revision 2.23  2000/02/26 01:38:14  keil
+ * Fixes for V.110 encoding LLC from Jens Jakobsen
+ *
  * Revision 2.22  2000/01/20 19:44:20  keil
  * Fixed uninitialiesed location
  * Fixed redirecting number IE in Setup
@@ -104,7 +107,7 @@
 #include <linux/config.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *dss1_revision = "$Revision: 2.22 $";
+const char *dss1_revision = "$Revision: 2.23 $";
 
 #define EXT_BEARER_CAPS 1
 
@@ -1045,7 +1048,8 @@
 EncodeASyncParams(u_char * p, u_char si2)
 {				// 7c 06 88  90 21 42 00 bb
 
-	p[0] = p[1] = 0;
+	p[0] = 0;
+	p[1] = 0x40;		// Intermediate rate: 16 kbit/s jj 2000.02.19
 	p[2] = 0x80;
 	if (si2 & 32)		// 7 data bits
 
@@ -1059,7 +1063,7 @@
 		p[2] += 96;
 	else			// 1 stop bit
 
-		p[2] = 32;
+		p[2] += 32;
 
 	if (si2 & 8)		// even parity
 
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/md5sums.asc linux/drivers/isdn/hisax/md5sums.asc
--- v2.3.47/linux/drivers/isdn/hisax/md5sums.asc	Thu Nov 11 20:11:38 1999
+++ linux/drivers/isdn/hisax/md5sums.asc	Sat Feb 26 20:20:13 2000
@@ -6,26 +6,26 @@
 # Eicon Technology Diva 2.01 PCI cards in the moment.
 # Read ../../../Documentation/isdn/HiSax.cert for more informations.
 # 
-3c2b1c96274cba97a8261d1cecc662b8  isac.c
-a9a15d069dbacb383cc24c238cb5ebbe  isdnl1.c
+3fb9c99465857a4c136ae2881f4e30ba  isac.c
+dd3955847bbf680b41233478fe521d88  isdnl1.c
 bb51bd223040b511c18f091da5ab6456  isdnl2.c
 b7aa7f97b2374967a4aca7c52991142c  isdnl3.c
 a23fbf8879c1432b04640b8b04bdf419  tei.c
-d7072dbbeeb7c4c45f3810ed13cf5545  callc.c
+ce248e56c2e1326012d0b25f92bbf99b  callc.c
 bf9605b36429898f7be6630034e83230  cert.c
-0e500813968adacaea2ef22c9cdd89eb  l3dss1.c
-2d748ced0eea375b21fe7ea91ca7917c  l3_1tr6.c
-d45fde1c90dda636ab134f2a51db435e  elsa.c
-0b5fb429f5bfe188fd42a5be01abbb14  diva.c
+6ce0a184127be1a44747e2017ed24ad9  l3dss1.c
+a3a570781f828b6d59e6b231653133de  l3_1tr6.c
+4aeba32c4c3480d2a6b9af34600b974f  elsa.c
+a296edc459b508bf0346c3132815a4db  diva.c
 # end of md5sums
 
 -----BEGIN PGP SIGNATURE-----
 Version: 2.6.3i
 Charset: noconv
 
-iQCVAwUBOCYF6jpxHvX/mS9tAQFnxQP/dpHyNjbo5BhFEZ8qIgpPJzoCgV+b2pB+
-h9Z/Q1jg8l23L/lP9dW00ogrKnKziVUUJqg+wWVEAA7BnNVr3aeyQKFTVuOnK5MC
-Oy0Z98p530vgOBiZ47elNfpefjhfD3duSSYNA4R9fEHVZB/atKFYvB5GDGmrwjIZ
-2f3g3kBP5Os=
-=zNnO
+iQCVAwUBOLcvXDpxHvX/mS9tAQGPWAP9Fg14RXcAwjCy4VeFoDBMOFpxllvG7xZR
+HQKENCYIzXKPb6I/IBUv3+BhL8Lnhjw8a2DXz6c6u+0nmUIFnzyt1BfzT70P9rKd
+BBN7f1KdIiQEmv0fZwd79Rz5PYvRDbY520bNTJZhorwqGI/qc3gGgHVtSR8OHhuS
+ZMQ1pb9W6jE=
+=CA5N
 -----END PGP SIGNATURE-----
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/netjet.c linux/drivers/isdn/hisax/netjet.c
--- v2.3.47/linux/drivers/isdn/hisax/netjet.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hisax/netjet.c	Sat Feb 26 20:20:13 2000
@@ -1,4 +1,4 @@
-/* $Id: netjet.c,v 1.17 1999/12/19 13:09:42 keil Exp $
+/* $Id: netjet.c,v 1.18 2000/02/26 00:35:13 keil Exp $
 
  * netjet.c     low level stuff for Traverse Technologie NETJet ISDN cards
  *
@@ -7,6 +7,9 @@
  * Thanks to Traverse Technologie Australia for documents and informations
  *
  * $Log: netjet.c,v $
+ * Revision 1.18  2000/02/26 00:35:13  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.17  1999/12/19 13:09:42  keil
  * changed TASK_INTERRUPTIBLE into TASK_UNINTERRUPTIBLE for
  * signal proof delays
@@ -85,7 +88,7 @@
 
 extern const char *CardType[];
 
-const char *NETjet_revision = "$Revision: 1.17 $";
+const char *NETjet_revision = "$Revision: 1.18 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -730,7 +733,7 @@
 				if (bcs->st->lli.l1writewakeup &&
 					(PACKET_NOACK != bcs->tx_skb->pkt_type))
 					bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len);
-				dev_kfree_skb(bcs->tx_skb);
+				dev_kfree_skb_any(bcs->tx_skb);
 				bcs->tx_skb = NULL;
 			}
 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
@@ -873,7 +876,7 @@
 		discard_queue(&bcs->rqueue);
 		discard_queue(&bcs->squeue);
 		if (bcs->tx_skb) {
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			bcs->tx_skb = NULL;
 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 		}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hisax/w6692.c linux/drivers/isdn/hisax/w6692.c
--- v2.3.47/linux/drivers/isdn/hisax/w6692.c	Thu Nov 11 20:11:38 1999
+++ linux/drivers/isdn/hisax/w6692.c	Sat Feb 26 20:20:13 2000
@@ -1,4 +1,4 @@
-/* $Id: w6692.c,v 1.1 1999/09/04 06:28:58 keil Exp $
+/* $Id: w6692.c,v 1.2 2000/02/26 00:35:13 keil Exp $
 
  * w6692.c   Winbond W6692 specific routines
  *
@@ -8,6 +8,9 @@
  *              This file is (c) under GNU PUBLIC LICENSE
  *
  * $Log: w6692.c,v $
+ * Revision 1.2  2000/02/26 00:35:13  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 1.1  1999/09/04 06:28:58  keil
  * first revision
  *
@@ -47,7 +50,7 @@
 
 extern const char *CardType[];
 
-const char *w6692_revision = "$Revision: 1.1 $";
+const char *w6692_revision = "$Revision: 1.2 $";
 
 #define DBUSY_TIMER_VALUE 80
 
@@ -378,7 +381,7 @@
 				if (bcs->st->lli.l1writewakeup &&
 				 (PACKET_NOACK != bcs->tx_skb->pkt_type))
 					bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.w6692.count);
-				dev_kfree_skb(bcs->tx_skb);
+				dev_kfree_skb_irq(bcs->tx_skb);
 				bcs->hw.w6692.count = 0;
 				bcs->tx_skb = NULL;
 			}
@@ -478,7 +481,7 @@
 				W6692_fill_fifo(cs);
 				goto afterXFR;
 			} else {
-				dev_kfree_skb(cs->tx_skb);
+				dev_kfree_skb_irq(cs->tx_skb);
 				cs->tx_cnt = 0;
 				cs->tx_skb = NULL;
 			}
@@ -655,7 +658,7 @@
 			discard_queue(&cs->rq);
 			discard_queue(&cs->sq);
 			if (cs->tx_skb) {
-				dev_kfree_skb(cs->tx_skb);
+				dev_kfree_skb_any(cs->tx_skb);
 				cs->tx_skb = NULL;
 			}
 			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
@@ -704,7 +707,7 @@
 			/* discard frame; reset transceiver */
 			test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags);
 			if (cs->tx_skb) {
-				dev_kfree_skb(cs->tx_skb);
+				dev_kfree_skb_any(cs->tx_skb);
 				cs->tx_cnt = 0;
 				cs->tx_skb = NULL;
 			} else {
@@ -819,7 +822,7 @@
 		discard_queue(&bcs->rqueue);
 		discard_queue(&bcs->squeue);
 		if (bcs->tx_skb) {
-			dev_kfree_skb(bcs->tx_skb);
+			dev_kfree_skb_any(bcs->tx_skb);
 			bcs->tx_skb = NULL;
 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 		}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hysdn/hysdn_procconf.c linux/drivers/isdn/hysdn/hysdn_procconf.c
--- v2.3.47/linux/drivers/isdn/hysdn/hysdn_procconf.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hysdn/hysdn_procconf.c	Sat Feb 26 20:33:02 2000
@@ -416,8 +416,6 @@
 	NULL			/* fsync */
 };
 
-static struct inode_operations conf_inode_operations;
-
 /*****************************/
 /* hysdn subdir in /proc/net */
 /*****************************/
@@ -446,10 +444,8 @@
 		if ((card->procconf = (void *) create_proc_entry(conf_name,
 					     S_IFREG | S_IRUGO | S_IWUSR,
 					    hysdn_proc_entry)) != NULL) {
-			memset(&conf_inode_operations, 0, sizeof(struct inode_operations));
-			conf_inode_operations.default_file_ops = &conf_fops;
 
-			((struct proc_dir_entry *) card->procconf)->ops = &conf_inode_operations;
+			((struct proc_dir_entry *) card->procconf)->proc_fops = &conf_fops;
 			hysdn_proclog_init(card);	/* init the log file entry */
 		}
 		card = card->next;	/* next entry */
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hysdn/hysdn_procfs.c linux/drivers/isdn/hysdn/hysdn_procfs.c
--- v2.3.47/linux/drivers/isdn/hysdn/hysdn_procfs.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hysdn/hysdn_procfs.c	Sat Feb 26 20:33:02 2000
@@ -351,27 +351,6 @@
 	NULL			/* fsync */
 };
 
-struct inode_operations log_inode_operations =
-{
-	&log_fops,		/* log proc file-ops */
-	NULL,			/* create      */
-	NULL,			/* lookup      */
-	NULL,			/* link        */
-	NULL,			/* unlink      */
-	NULL,			/* symlink     */
-	NULL,			/* mkdir       */
-	NULL,			/* rmdir       */
-	NULL,			/* mknod       */
-	NULL,			/* rename      */
-	NULL,			/* readlink    */
-	NULL,			/* follow_link */
-	NULL,			/* readpage    */
-	NULL,			/* writepage   */
-	NULL,			/* bmap        */
-	NULL,			/* truncate    */
-	NULL			/* permission  */
-};
-
 /*****************************************/
 /* Output info data to the cardinfo file */
 /*****************************************/
@@ -464,7 +443,7 @@
 
 			sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid);
 			if ((pd->log = create_proc_entry(pd->log_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry)) != NULL)
-				pd->log->ops = &log_inode_operations;	/* set new operations table */
+				pd->log->proc_fops = &log_fops;	/* set new operations table */
 
 			init_waitqueue_head(&(pd->rd_queue));
 
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/hysdn/hysdn_proclog.c linux/drivers/isdn/hysdn/hysdn_proclog.c
--- v2.3.47/linux/drivers/isdn/hysdn/hysdn_proclog.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/hysdn/hysdn_proclog.c	Sat Feb 26 20:33:02 2000
@@ -433,8 +433,6 @@
 	NULL			/* fsync */
 };
 
-struct inode_operations log_inode_operations;
-
 /***********************************************************************************/
 /* hysdn_proclog_init is called when the module is loaded after creating the cards */
 /* conf files.                                                                     */
@@ -448,12 +446,10 @@
 
 	if ((pd = (struct procdata *) kmalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) {
 		memset(pd, 0, sizeof(struct procdata));
-		memset(&log_inode_operations, 0, sizeof(struct inode_operations));
-		log_inode_operations.default_file_ops = &log_fops;
 
 		sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid);
 		if ((pd->log = create_proc_entry(pd->log_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry)) != NULL)
-			pd->log->ops = &log_inode_operations;	/* set new operations table */
+			pd->log->proc_fops = &log_fops;	/* set new operations table */
 
 		init_waitqueue_head(&(pd->rd_queue));
 
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- v2.3.47/linux/drivers/isdn/isdn_common.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/isdn_common.c	Sat Feb 26 20:20:13 2000
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.c,v 1.97 2000/01/23 18:45:37 keil Exp $
+/* $Id: isdn_common.c,v 1.99 2000/02/26 01:00:52 keil Exp $
 
  * Linux ISDN subsystem, common used functions (linklevel).
  *
@@ -21,6 +21,12 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: isdn_common.c,v $
+ * Revision 1.99  2000/02/26 01:00:52  keil
+ * changes from 2.3.47
+ *
+ * Revision 1.98  2000/02/16 14:56:27  paul
+ * translated ISDN_MODEM_ANZREG to ISDN_MODEM_NUMREG for english speakers
+ *
  * Revision 1.97  2000/01/23 18:45:37  keil
  * Change EAZ mapping to forbit the use of cards (insert a "-" for the MSN)
  *
@@ -443,7 +449,7 @@
 
 isdn_dev *dev = (isdn_dev *) 0;
 
-static char *isdn_revision = "$Revision: 1.97 $";
+static char *isdn_revision = "$Revision: 1.99 $";
 
 extern char *isdn_net_revision;
 extern char *isdn_tty_revision;
@@ -1795,15 +1801,15 @@
 					int i;
 
 					if ((ret = verify_area(VERIFY_WRITE, (void *) arg,
-					(ISDN_MODEM_ANZREG + ISDN_MSNLEN + ISDN_LMSNLEN)
+					(ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN)
 						   * ISDN_MAX_CHANNELS)))
 						return ret;
 
 					for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
 						if (copy_to_user(p, dev->mdm.info[i].emu.profile,
-						      ISDN_MODEM_ANZREG))
+						      ISDN_MODEM_NUMREG))
 							return -EFAULT;
-						p += ISDN_MODEM_ANZREG;
+						p += ISDN_MODEM_NUMREG;
 						if (copy_to_user(p, dev->mdm.info[i].emu.pmsn, ISDN_MSNLEN))
 							return -EFAULT;
 						p += ISDN_MSNLEN;
@@ -1811,7 +1817,7 @@
 							return -EFAULT;
 						p += ISDN_LMSNLEN;
 					}
-					return (ISDN_MODEM_ANZREG + ISDN_MSNLEN + ISDN_LMSNLEN) * ISDN_MAX_CHANNELS;
+					return (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN) * ISDN_MAX_CHANNELS;
 				} else
 					return -EINVAL;
 				break;
@@ -1822,15 +1828,15 @@
 					int i;
 
 					if ((ret = verify_area(VERIFY_READ, (void *) arg,
-					(ISDN_MODEM_ANZREG + ISDN_MSNLEN)
+					(ISDN_MODEM_NUMREG + ISDN_MSNLEN)
 						   * ISDN_MAX_CHANNELS)))
 						return ret;
 
 					for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
 						if (copy_from_user(dev->mdm.info[i].emu.profile, p,
-						     ISDN_MODEM_ANZREG))
+						     ISDN_MODEM_NUMREG))
 							return -EFAULT;
-						p += ISDN_MODEM_ANZREG;
+						p += ISDN_MODEM_NUMREG;
 						if (copy_from_user(dev->mdm.info[i].emu.pmsn, p, ISDN_MSNLEN))
 							return -EFAULT;
 						p += ISDN_MSNLEN;
@@ -2632,7 +2638,7 @@
 	devfs_unregister (devfs_handle);
 }
 
-#else   /*  CONFIG_DEVFS_FS  */
+#else   /* CONFIG_DEVFS_FS */
 static void isdn_register_devfs(int dummy)
 {
 	return;
@@ -2653,7 +2659,7 @@
     return;
 }
 
-#endif  /*  CONFIG_DEVFS_FS  */
+#endif  /* CONFIG_DEVFS_FS */
 
 /*
  * Allocate and initialize all data, register modem-devices
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
--- v2.3.47/linux/drivers/isdn/isdn_net.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/isdn/isdn_net.c	Sat Feb 26 20:20:13 2000
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.c,v 1.107 2000/02/13 09:52:05 kai Exp $
+/* $Id: isdn_net.c,v 1.110 2000/02/26 01:00:53 keil Exp $
 
  * Linux ISDN subsystem, network interfaces and related functions (linklevel).
  *
@@ -21,6 +21,16 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: isdn_net.c,v $
+ * Revision 1.110  2000/02/26 01:00:53  keil
+ * changes from 2.3.47
+ *
+ * Revision 1.109  2000/02/25 11:29:17  paul
+ * changed chargetime to ulong from int (after about 20 days the "chargetime of
+ * ipppX is now 1234" message displays a negative number on alpha).
+ *
+ * Revision 1.108  2000/02/15 12:54:01  kai
+ * set TX timeout back to 2 secs for 2.2.x, just to be safe
+ *
  * Revision 1.107  2000/02/13 09:52:05  kai
  * increased TX_TIMEOUT to 20sec
  *
@@ -521,6 +531,14 @@
 		netif_wake_queue(&lp->netdev->dev);
 }
 
+/* For 2.2.x we leave the transmitter busy timeout at 2 secs, just 
+ * to be safe.
+ * For 2.3.x we push it up to 20 secs, because call establishment
+ * (in particular callback) may take such a long time, and we 
+ * don't want confusing messages in the log. However, there is a slight
+ * possibility that this large timeout will break other things like MPPP,
+ * which might rely on the tx timeout. If so, we'll find out this way...
+ */
 
 #define ISDN_NET_TX_TIMEOUT (20*HZ) 
 
@@ -530,7 +548,7 @@
 static int isdn_net_start_xmit(struct sk_buff *, struct net_device *);
 static int isdn_net_xmit(struct net_device *, isdn_net_local *, struct sk_buff *);
 
-char *isdn_net_revision = "$Revision: 1.107 $";
+char *isdn_net_revision = "$Revision: 1.110 $";
 
  /*
   * Code for raw-networking over ISDN
@@ -727,7 +745,7 @@
 							isdn_net_hangup(&p->dev);
 						} else if (jiffies - l->chargetime > l->chargeint) {
 							printk(KERN_DEBUG
-							       "isdn_net: %s: chtime = %d, chint = %d\n",
+							       "isdn_net: %s: chtime = %lu, chint = %d\n",
 							       l->name, l->chargetime, l->chargeint);
 							isdn_net_hangup(&p->dev);
 						}
@@ -868,7 +886,7 @@
 						 * we correct the timestamp here.
 						 */
 						lp->chargetime = jiffies;
-						printk(KERN_DEBUG "isdn_net: chargetime of %s now %d\n",
+						printk(KERN_DEBUG "isdn_net: chargetime of %s now %lu\n",
 						lp->name, lp->chargetime);
 
 						/* reset dial-timeout */
@@ -915,7 +933,7 @@
 				if (lp->hupflags & ISDN_WAITCHARGE)
 					lp->hupflags |= ISDN_HAVECHARGE;
 				lp->chargetime = jiffies;
-				printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %d\n",
+				printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
 				       lp->name, lp->chargetime);
 				return 1;
 		}
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/isdn_tty.c linux/drivers/isdn/isdn_tty.c
--- v2.3.47/linux/drivers/isdn/isdn_tty.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/isdn_tty.c	Sat Feb 26 20:20:13 2000
@@ -1,4 +1,4 @@
-/* $Id: isdn_tty.c,v 1.82 2000/01/23 18:45:37 keil Exp $
+/* $Id: isdn_tty.c,v 1.84 2000/02/16 15:10:14 paul Exp $
 
  * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel).
  *
@@ -20,6 +20,15 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: isdn_tty.c,v $
+ * Revision 1.84  2000/02/16 15:10:14  paul
+ * If a ttyI has no open FDs, don't connect incoming calls to it.
+ * (Hangup on close of last FD is still to be done.)
+ *
+ * Revision 1.83  2000/02/16 14:59:33  paul
+ * translated ISDN_MODEM_ANZREG to ISDN_MODEM_NUMREG for english speakers;
+ * used defines for result codes;
+ * fixed RING ... RUNG problem (no empty lines in between).
+ *
  * Revision 1.82  2000/01/23 18:45:37  keil
  * Change EAZ mapping to forbit the use of cards (insert a "-" for the MSN)
  *
@@ -379,7 +388,7 @@
 static int si2bit[8] =
 {4, 1, 4, 4, 4, 4, 4, 4};
 
-char *isdn_tty_revision = "$Revision: 1.82 $";
+char *isdn_tty_revision = "$Revision: 1.84 $";
 
 
 /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb()
@@ -901,7 +910,7 @@
 isdn_tty_modem_do_ncarrier(unsigned long data)
 {
 	modem_info *info = (modem_info *) data;
-	isdn_tty_modem_result(3, info);
+	isdn_tty_modem_result(RESULT_NO_CARRIER, info);
 }
 
 /* Next routine is called, whenever the DTR-signal is raised.
@@ -986,7 +995,7 @@
 	i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
 	if (i < 0) {
 		restore_flags(flags);
-		isdn_tty_modem_result(6, info);
+		isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
 	} else {
 		info->isdn_driver = dev->drvmap[i];
 		info->isdn_channel = dev->chanmap[i];
@@ -1056,8 +1065,7 @@
 	if (info->online) {
 		info->last_lhup = local;
 		info->online = 0;
-		/* NO CARRIER message */
-		isdn_tty_modem_result(3, info);
+		isdn_tty_modem_result(RESULT_NO_CARRIER, info);
 	}
 #ifdef CONFIG_ISDN_AUDIO
 	info->vonline = 0;
@@ -1086,7 +1094,7 @@
 #endif
 	if ((info->msr & UART_MSR_RI) &&
 		(info->emu.mdmreg[REG_RUNG] & BIT_RUNG))
-		isdn_tty_modem_result(12, info);
+		isdn_tty_modem_result(RESULT_RUNG, info);
 	info->msr &= ~(UART_MSR_DCD | UART_MSR_RI);
 	info->lsr |= UART_LSR_TEMT;
 	if (info->isdn_driver >= 0) {
@@ -1197,7 +1205,7 @@
 	i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
 	if (i < 0) {
 		restore_flags(flags);
-		isdn_tty_modem_result(6, info);
+		isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
 	} else {
 		info->isdn_driver = dev->drvmap[i];
 		info->isdn_channel = dev->chanmap[i];
@@ -1265,7 +1273,7 @@
 
 	l = strlen(msg);
 	if (!l) {
-		isdn_tty_modem_result(4, info);
+		isdn_tty_modem_result(RESULT_ERROR, info);
 		return;
 	}
 	for (j = 7; j >= 0; j--)
@@ -1291,7 +1299,7 @@
 	i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
 	if (i < 0) {
 		restore_flags(flags);
-		isdn_tty_modem_result(6, info);
+		isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
 	} else {
 		info->isdn_driver = dev->drvmap[i];
 		info->isdn_channel = dev->chanmap[i];
@@ -1589,7 +1597,7 @@
 #ifdef ISDN_DEBUG_MODEM_HUP
 				printk(KERN_DEBUG "Mhup in isdn_tty_write\n");
 #endif
-				isdn_tty_modem_result(3, info);
+				isdn_tty_modem_result(RESULT_NO_CARRIER, info);
 				isdn_tty_modem_hup(info, 1);
 			} else
 				c = isdn_tty_edit_at(buf, c, info, from_user);
@@ -2321,7 +2329,7 @@
 {
 	atemu *m = &info->emu;
 	if ((m->mdmreg[REG_DTRR] & BIT_DTRR) || force) {
-		memcpy(m->mdmreg, m->profile, ISDN_MODEM_ANZREG);
+		memcpy(m->mdmreg, m->profile, ISDN_MODEM_NUMREG);
 		memcpy(m->msn, m->pmsn, ISDN_MSNLEN);
 		memcpy(m->lmsn, m->plmsn, ISDN_LMSNLEN);
 		info->xmit_size = m->mdmreg[REG_PSIZE] * 16;
@@ -2338,7 +2346,7 @@
 static void
 modem_write_profile(atemu * m)
 {
-	memcpy(m->profile, m->mdmreg, ISDN_MODEM_ANZREG);
+	memcpy(m->profile, m->mdmreg, ISDN_MODEM_NUMREG);
 	memcpy(m->pmsn, m->msn, ISDN_MSNLEN);
 	memcpy(m->plmsn, m->lmsn, ISDN_LMSNLEN);
 	if (dev->profd)
@@ -2447,6 +2455,13 @@
 	return 0;
 }
 
+
+/*
+ * isdn_tty_match_icall(char *MSN, atemu *tty_emulator, int dev_idx)
+ *      match the MSN against the MSNs (glob patterns) defined for tty_emulator,
+ *      and return 0 for match, 1 for no match, 2 if MSN could match if longer.
+ */
+
 static int
 isdn_tty_match_icall(char *cid, atemu *emu, int di)
 {
@@ -2512,15 +2527,14 @@
 	int idx;
 	int si1;
 	int si2;
-	char nr[32];
+	char *nr;
 	ulong flags;
 
 	if (!setup.phone[0]) {
-		nr[0] = '0';
-		nr[1] = '\0';
+		nr = "0";
 		printk(KERN_INFO "isdn_tty: Incoming call without OAD, assuming '0'\n");
 	} else
-		strcpy(nr, setup.phone);
+		nr = setup.phone;
 	si1 = (int) setup.si1;
 	si2 = (int) setup.si2;
 	if (!setup.eazmsn[0]) {
@@ -2537,6 +2551,8 @@
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
 		modem_info *info = &dev->mdm.info[i];
 
+                if (info->count == 0)
+                    continue;
 		if ((info->emu.mdmreg[REG_SI1] & si2bit[si1]) &&  /* SI1 is matching */
 		    (info->emu.mdmreg[REG_SI2] == si2))	{         /* SI2 is matching */
 			idx = isdn_dc2minor(di, ch);
@@ -2574,7 +2590,7 @@
 					printk(KERN_INFO "isdn_tty: call from %s, -> RING on ttyI%d\n", nr,
 					       info->line);
 					info->msr |= UART_MSR_RI;
-					isdn_tty_modem_result(2, info);
+					isdn_tty_modem_result(RESULT_RING, info);
 					isdn_timer_ctrl(ISDN_TIMER_MODEMRING, 1);
 					return 1;
 				}
@@ -2660,9 +2676,9 @@
 #endif
 				if (TTY_IS_ACTIVE(info)) {
 					if (info->dialing == 1) 
-						isdn_tty_modem_result(7, info);
+						isdn_tty_modem_result(RESULT_BUSY, info);
 					if (info->dialing > 1) 
-						isdn_tty_modem_result(3, info);
+						isdn_tty_modem_result(RESULT_NO_CARRIER, info);
 					info->dialing = 0;
 #ifdef ISDN_DEBUG_MODEM_HUP
 					printk(KERN_DEBUG "Mhup in ISDN_STAT_DHUP\n");
@@ -2691,12 +2707,12 @@
 					if (USG_MODEM(dev->usage[i])) {
 						if (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) {
 							strcpy(info->emu.connmsg, c->parm.num);
-							isdn_tty_modem_result(1, info);
+							isdn_tty_modem_result(RESULT_CONNECT, info);
 						} else
-							isdn_tty_modem_result(5, info);
+							isdn_tty_modem_result(RESULT_CONNECT64000, info);
 					}
 					if (USG_VOICE(dev->usage[i]))
-						isdn_tty_modem_result(11, info);
+						isdn_tty_modem_result(RESULT_VCON, info);
 					return 1;
 				}
 				break;
@@ -2722,7 +2738,7 @@
 						info->last_l2 = -1;
 						info->last_si = 0;
 						sprintf(info->last_cause, "0000");
-						isdn_tty_modem_result(6, info);
+						isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
 					}
 					isdn_tty_modem_hup(info, 0);
 					return 1;
@@ -2937,6 +2953,7 @@
  * For CONNECT-messages also switch to online-mode.
  * For RING-message handle auto-ATA if register 0 != 0
  */
+
 static void
 isdn_tty_modem_result(int code, modem_info * info)
 {
@@ -2949,14 +2966,13 @@
 	char s[ISDN_MSNLEN+10];
 
 	switch (code) {
-		case 2:
-			m->mdmreg[REG_RINGCNT]++;	/* RING */
+		case RESULT_RING:
+			m->mdmreg[REG_RINGCNT]++;
 			if (m->mdmreg[REG_RINGCNT] == m->mdmreg[REG_RINGATA])
 				/* Automatically accept incoming call */
 				isdn_tty_cmd_ATA(info);
 			break;
-		case 3:
-			/* NO CARRIER */
+		case RESULT_NO_CARRIER:
 #ifdef ISDN_DEBUG_MODEM_HUP
 			printk(KERN_DEBUG "modem_result: NO CARRIER %d %d\n",
 			       (info->flags & ISDN_ASYNC_CLOSING),
@@ -2991,13 +3007,13 @@
 			}
 #endif
 			break;
-		case 1:
-		case 5:
+		case RESULT_CONNECT:
+		case RESULT_CONNECT64000:
 			sprintf(info->last_cause, "0000");
 			if (!info->online)
 				info->online = 2;
 			break;
-		case 11:
+		case RESULT_VCON:
 #ifdef ISDN_DEBUG_MODEM_VOICE
 			printk(KERN_DEBUG "res3: send VCON on ttyI%d\n",
 			       info->line);
@@ -3006,27 +3022,30 @@
 			if (!info->online)
 				info->online = 1;
 			break;
-	}
+	} /* switch(code) */
+
 	if (m->mdmreg[REG_RESP] & BIT_RESP) {
 		/* Show results */
-		isdn_tty_at_cout("\r\n", info);
 		if (m->mdmreg[REG_RESPNUM] & BIT_RESPNUM) {
-			/* Show numeric results */
-			sprintf(s, "%d", code);
+			/* Show numeric results only */
+			sprintf(s, "\r\n%d\r\n", code);
 			isdn_tty_at_cout(s, info);
 		} else {
-			if ((code == 2) &&
-				(m->mdmreg[REG_RUNG] & BIT_RUNG) &&
-				(m->mdmreg[REG_RINGCNT] > 1))
-				return;
-			if ((code == 2) && (!(m->mdmreg[REG_CIDONCE] & BIT_CIDONCE))) {
-				isdn_tty_at_cout("CALLER NUMBER: ", info);
-				isdn_tty_at_cout(dev->num[info->drv_index], info);
-				isdn_tty_at_cout("\r\n", info);
+			if (code == RESULT_RING) {
+			    /* return if "show RUNG" and ringcounter>1 */
+			    if ((m->mdmreg[REG_RUNG] & BIT_RUNG) &&
+				    (m->mdmreg[REG_RINGCNT] > 1))
+						return;
+			    /* print CID, _before_ _every_ ring */
+			    if (!(m->mdmreg[REG_CIDONCE] & BIT_CIDONCE)) {
+				    isdn_tty_at_cout("\r\nCALLER NUMBER: ", info);
+				    isdn_tty_at_cout(dev->num[info->drv_index], info);
+			    }
 			}
+			isdn_tty_at_cout("\r\n", info);
 			isdn_tty_at_cout(msg[code], info);
 			switch (code) {
-				case 1:
+				case RESULT_CONNECT:
 					switch (m->mdmreg[REG_L2PROT]) {
 						case ISDN_PROTO_L2_MODEM:
 							isdn_tty_at_cout(" ", info);
@@ -3034,13 +3053,13 @@
 							break;
 					}
 					break;
-				case 2:
+				case RESULT_RING:
 					/* Append CPN, if enabled */
 					if ((m->mdmreg[REG_CPN] & BIT_CPN)) {
 						sprintf(s, "/%s", m->cpn);
 						isdn_tty_at_cout(s, info);
 					}
-					/* Print CID only once, _after_ 1.st RING */
+					/* Print CID only once, _after_ 1st RING */
 					if ((m->mdmreg[REG_CIDONCE] & BIT_CIDONCE) &&
 					    (m->mdmreg[REG_RINGCNT] == 1)) {
 						isdn_tty_at_cout("\r\n", info);
@@ -3048,10 +3067,10 @@
 						isdn_tty_at_cout(dev->num[info->drv_index], info);
 					}
 					break;
-				case 3:
-				case 6:
-				case 7:
-				case 8:
+				case RESULT_NO_CARRIER:
+				case RESULT_NO_DIALTONE:
+				case RESULT_BUSY:
+				case RESULT_NO_ANSWER:
 					m->mdmreg[REG_RINGCNT] = 0;
 					/* Append Cause-Message if enabled */
 					if (m->mdmreg[REG_RESPXT] & BIT_RESPXT) {
@@ -3059,7 +3078,7 @@
 						isdn_tty_at_cout(s, info);
 					}
 					break;
-				case 5:
+				case RESULT_CONNECT64000:
 					/* Append Protocol to CONNECT message */
 					switch (m->mdmreg[REG_L2PROT]) {
 						case ISDN_PROTO_L2_X75I:
@@ -3087,10 +3106,10 @@
 					}
 					break;
 			}
+			isdn_tty_at_cout("\r\n", info);
 		}
-		isdn_tty_at_cout("\r\n", info);
 	}
-	if (code == 3) {
+	if (code == RESULT_NO_CARRIER) {
 		save_flags(flags);
 		cli();
 		if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) {
@@ -3108,6 +3127,7 @@
 	}
 }
 
+
 /*
  * Display a modem-register-value.
  */
@@ -3160,8 +3180,8 @@
 	*q = 0;
 }
 
-#define PARSE_ERROR { isdn_tty_modem_result(4, info); return; }
-#define PARSE_ERROR1 { isdn_tty_modem_result(4, info); return 1; }
+#define PARSE_ERROR { isdn_tty_modem_result(RESULT_ERROR, info); return; }
+#define PARSE_ERROR1 { isdn_tty_modem_result(RESULT_ERROR, info); return 1; }
 
 static void
 isdn_tty_report(modem_info * info)
@@ -3329,8 +3349,8 @@
 			/* &L -Set Numbers to listen on */
 			p[0]++;
 			i = 0;
-			while ((strchr("0123456789,-*[]?;", *p[0])) &&
-			       (i < ISDN_LMSNLEN) && *p[0])
+			while (*p[0] && (strchr("0123456789,-*[]?;", *p[0])) &&
+			       (i < ISDN_LMSNLEN))
 				m->lmsn[i++] = *p[0]++;
 			m->lmsn[i] = '\0';
 			break;
@@ -3381,7 +3401,7 @@
 			/* &V - Show registers */
 			p[0]++;
 			isdn_tty_at_cout("\r\n", info);
-			for (i = 0; i < ISDN_MODEM_ANZREG; i++) {
+			for (i = 0; i < ISDN_MODEM_NUMREG; i++) {
 				sprintf(rb, "S%02d=%03d%s", i,
 					m->mdmreg[i], ((i + 1) % 10) ? " " : "\r\n");
 				isdn_tty_at_cout(rb, info);
@@ -3486,7 +3506,7 @@
 	int bval;
 
 	mreg = isdn_getnum(p);
-	if (mreg < 0 || mreg >= ISDN_MODEM_ANZREG)
+	if (mreg < 0 || mreg >= ISDN_MODEM_NUMREG)
 		PARSE_ERROR1;
 	switch (*p[0]) {
 		case '=':
@@ -3589,7 +3609,7 @@
 		isdn_command(&cmd);
 		isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1);
 	} else
-		isdn_tty_modem_result(8, info);
+		isdn_tty_modem_result(RESULT_NO_ANSWER, info);
 }
 
 #ifdef CONFIG_ISDN_AUDIO
@@ -3779,7 +3799,7 @@
 			if (!m->vpar[0])
 				PARSE_ERROR1;
 			if (info->online != 1) {
-				isdn_tty_modem_result(8, info);
+				isdn_tty_modem_result(RESULT_NO_ANSWER, info);
 				return 1;
 			}
 			info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state);
@@ -3803,7 +3823,7 @@
 			printk(KERN_DEBUG "AT: +VRX\n");
 #endif
 			info->vonline |= 1;
-			isdn_tty_modem_result(1, info);
+			isdn_tty_modem_result(RESULT_CONNECT, info);
 			return 0;
 			break;
 		case 4:
@@ -3893,7 +3913,7 @@
 			if (!m->vpar[0])
 				PARSE_ERROR1;
 			if (info->online != 1) {
-				isdn_tty_modem_result(8, info);
+				isdn_tty_modem_result(RESULT_NO_ANSWER, info);
 				return 1;
 			}
 			info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state);
@@ -3913,7 +3933,7 @@
 #endif
 			m->lastDLE = 0;
 			info->vonline |= 2;
-			isdn_tty_modem_result(1, info);
+			isdn_tty_modem_result(RESULT_CONNECT, info);
 			return 0;
 			break;
 		case 7:
@@ -3998,13 +4018,13 @@
 				if (info->msr & UART_MSR_DCD)
 					PARSE_ERROR;
 				if (info->msr & UART_MSR_RI) {
-					isdn_tty_modem_result(3, info);
+					isdn_tty_modem_result(RESULT_NO_CARRIER, info);
 					return;
 				}
 				isdn_tty_getdial(++p, ds, sizeof ds);
 				p += strlen(p);
 				if (!strlen(m->msn))
-					isdn_tty_modem_result(10, info);
+					isdn_tty_modem_result(RESULT_NO_MSN_EAZ, info);
 				else if (strlen(ds))
 					isdn_tty_dial(ds, info, m);
 				else
@@ -4076,9 +4096,9 @@
 				p++;
 				if (info->msr & UART_MSR_DCD)
 					/* if B-Channel is up */
-					isdn_tty_modem_result((m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) ? 1:5, info);
+					isdn_tty_modem_result((m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) ? RESULT_CONNECT:RESULT_CONNECT64000, info);
 				else
-					isdn_tty_modem_result(3, info);
+					isdn_tty_modem_result(RESULT_NO_CARRIER, info);
 				return;
 			case 'Q':
 				/* Q - Turn Emulator messages on/off */
@@ -4171,7 +4191,7 @@
 #ifdef CONFIG_ISDN_AUDIO
 	if (!info->vonline)
 #endif
-		isdn_tty_modem_result(0, info);
+		isdn_tty_modem_result(RESULT_OK, info);
 }
 
 /* Need own toupper() because standard-toupper is not available
@@ -4282,7 +4302,7 @@
 					    ((jiffies - info->emu.lastplus) > PLUSWAIT2)) {
 						info->emu.pluscount = 0;
 						info->online = 0;
-						isdn_tty_modem_result(0, info);
+						isdn_tty_modem_result(RESULT_OK, info);
 					}
 				}
 			}
@@ -4304,7 +4324,7 @@
 		modem_info *info = &dev->mdm.info[i];
 		if (info->msr & UART_MSR_RI) {
 			ton = 1;
-			isdn_tty_modem_result(2, info);
+			isdn_tty_modem_result(RESULT_RING, info);
 		}
 	}
 	isdn_timer_ctrl(ISDN_TIMER_MODEMRING, ton);
@@ -4346,7 +4366,7 @@
 		if (info->dialing) {
 			if (info->emu.carrierwait++ > info->emu.mdmreg[REG_WAITC]) {
 				info->dialing = 0;
-				isdn_tty_modem_result(3, info);
+				isdn_tty_modem_result(RESULT_NO_CARRIER, info);
 				isdn_tty_modem_hup(info, 1);
 			}
 			else
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/isdn_tty.h linux/drivers/isdn/isdn_tty.h
--- v2.3.47/linux/drivers/isdn/isdn_tty.h	Wed Feb 16 17:03:52 2000
+++ linux/drivers/isdn/isdn_tty.h	Sat Feb 26 20:20:13 2000
@@ -1,4 +1,4 @@
-/* $Id: isdn_tty.h,v 1.18 2000/01/20 19:55:33 keil Exp $
+/* $Id: isdn_tty.h,v 1.19 2000/02/16 14:59:33 paul Exp $
 
  * header for Linux ISDN subsystem, tty related functions (linklevel).
  *
@@ -20,6 +20,11 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: isdn_tty.h,v $
+ * Revision 1.19  2000/02/16 14:59:33  paul
+ * translated ISDN_MODEM_ANZREG to ISDN_MODEM_NUMREG for english speakers;
+ * used defines for result codes;
+ * fixed RING ... RUNG problem (no empty lines in between).
+ *
  * Revision 1.18  2000/01/20 19:55:33  keil
  * Add FAX Class 1 support
  *
@@ -110,7 +115,7 @@
  * Definition of some special Registers of AT-Emulator
  */
 #define REG_RINGATA   0
-#define REG_RINGCNT   1
+#define REG_RINGCNT   1  /* ring counter register */
 #define REG_ESC       2
 #define REG_CR        3
 #define REG_LF        4
@@ -118,10 +123,10 @@
 
 #define REG_WAITC     7
 
-#define REG_RESP     12
-#define BIT_RESP      1
-#define REG_RESPNUM  12
-#define BIT_RESPNUM   2
+#define REG_RESP     12  /* show response messages register */
+#define BIT_RESP      1  /* show response messages bit      */
+#define REG_RESPNUM  12  /* show numeric responses register */
+#define BIT_RESPNUM   2  /* show numeric responses bit      */
 #define REG_ECHO     12
 #define BIT_ECHO      4
 #define REG_DCD      12
@@ -144,8 +149,8 @@
 #define BIT_RESPXT    8
 #define REG_CIDONCE  13
 #define BIT_CIDONCE  16
-#define REG_RUNG     13
-#define BIT_RUNG     64
+#define REG_RUNG     13  /* show RUNG message register      */
+#define BIT_RUNG     64  /* show RUNG message bit           */
 #define REG_DISPLAY  13
 #define BIT_DISPLAY 128
 
@@ -162,6 +167,21 @@
 #define REG_CPN      23
 #define BIT_CPN       1
 #define BIT_CPNFCON   2
+
+/* defines for result codes */
+#define RESULT_OK		0
+#define RESULT_CONNECT		1
+#define RESULT_RING		2
+#define RESULT_NO_CARRIER	3
+#define RESULT_ERROR		4
+#define RESULT_CONNECT64000	5
+#define RESULT_NO_DIALTONE	6
+#define RESULT_BUSY		7
+#define RESULT_NO_ANSWER	8
+#define RESULT_RINGING		9
+#define RESULT_NO_MSN_EAZ	10
+#define RESULT_VCON		11
+#define RESULT_RUNG		12
 
 #define TTY_IS_FCLASS1(info) \
 	((info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_FAX) && \
diff -u --recursive --new-file v2.3.47/linux/drivers/isdn/sc/debug.h linux/drivers/isdn/sc/debug.h
--- v2.3.47/linux/drivers/isdn/sc/debug.h	Tue Nov 23 22:42:20 1999
+++ linux/drivers/isdn/sc/debug.h	Sat Feb 26 20:20:13 2000
@@ -1,5 +1,5 @@
 /*
- *  $Id: debug.h,v 1.1 1996/11/07 13:07:42 fritz Exp $
+ *  $Id: debug.h,v 1.2 2000/02/26 01:00:53 keil Exp $
  *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
diff -u --recursive --new-file v2.3.47/linux/drivers/net/3c505.c linux/drivers/net/3c505.c
--- v2.3.47/linux/drivers/net/3c505.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/net/3c505.c	Mon Feb 21 11:23:42 2000
@@ -361,8 +361,7 @@
 static inline void prime_rx(struct net_device *dev)
 {
 	elp_device *adapter = dev->priv;
-	while (adapter->rx_active < ELP_RX_PCBS &&
-	       netif_running(dev->state)) {
+	while (adapter->rx_active < ELP_RX_PCBS && netif_running(dev)) {
 		if (!start_receive(dev, &adapter->itx_pcb))
 			break;
 	}
diff -u --recursive --new-file v2.3.47/linux/drivers/net/8139too.c linux/drivers/net/8139too.c
--- v2.3.47/linux/drivers/net/8139too.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/net/8139too.c	Sat Feb 26 20:22:08 2000
@@ -87,7 +87,7 @@
 #include <asm/io.h>
 
 
-#define RTL8139_VERSION "0.9.3"
+#define RTL8139_VERSION "0.9.4"
 #define RTL8139_MODULE_NAME "8139too"
 #define RTL8139_DRIVER_NAME   RTL8139_MODULE_NAME " Fast Ethernet driver " RTL8139_VERSION
 #define PFX RTL8139_MODULE_NAME ": "
@@ -101,8 +101,8 @@
 #define DPRINTK(fmt, args...)
 #endif
 
-#define RTL8139_NDEBUG 0	/* define to 1 to disable lightweight runtime checks */
-#if RTL8139_NDEBUG
+#undef RTL8139_NDEBUG	/* define to 1 to disable lightweight runtime checks */
+#ifdef RTL8139_NDEBUG
 #define assert(expr)
 #else
 #define assert(expr) \
@@ -144,6 +144,7 @@
 #define RX_DMA_BURST	4	/* Maximum PCI burst, '4' is 256 bytes */
 #define TX_DMA_BURST	4	/* Calculate as 16<<val. */
 
+
 /* Operational parameters that usually are not changed. */
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT  (6*HZ)
@@ -154,12 +155,13 @@
 	HAS_LNK_CHNG = 0x040000,
 };
 
-#define RTL_IO_SIZE 0x80
+#define RTL_MIN_IO_SIZE 0x80
+#define RTL8139B_IO_SIZE 0xFF
 
-#define RTL8139_CAPS  HAS_CHIP_XCVR|HAS_LNK_CHNG
+#define RTL8139_CAPS	HAS_CHIP_XCVR|HAS_LNK_CHNG
 
 typedef enum {
-	RTL8139,
+	RTL8139 = 0,
 	RTL8139_CB,
 	SMC1211TX,
 	/*MPX5030,*/
@@ -168,17 +170,16 @@
 } chip_t;
 
 
+/* indexed by chip_t, above */
 static struct {
-	chip_t chip;
 	const char *name;
 } chip_info[] __devinitdata = {
-	{ RTL8139, "RealTek RTL8139 Fast Ethernet"},
-	{ RTL8139_CB, "RealTek RTL8139B PCI/CardBus"},
-	{ SMC1211TX, "SMC1211TX EZCard 10/100 (RealTek RTL8139)"},
-/*	{ MPX5030, "Accton MPX5030 (RealTek RTL8139)"},*/
-	{ DELTA8139, "Delta Electronics 8139 10/100BaseTX"},
-	{ ADDTRON8139, "Addtron Technolgy 8139 10/100BaseTX"},
-	{0,},
+	{ "RealTek RTL8139 Fast Ethernet" },
+	{ "RealTek RTL8139B PCI/CardBus" },
+	{ "SMC1211TX EZCard 10/100 (RealTek RTL8139)" },
+/*	{ MPX5030, "Accton MPX5030 (RealTek RTL8139)" },*/
+	{ "Delta Electronics 8139 10/100BaseTX" },
+	{ "Addtron Technolgy 8139 10/100BaseTX" },
 };
 
 
@@ -298,6 +299,14 @@
 	Cfg1_LED1 = 0x80,
 };
 
+enum RxConfigBits {
+	RxCfgRcv8K = 0,
+	RxCfgRcv16K = (1 << 11),
+	RxCfgRcv32K = (1 << 12),
+	RxCfgRcv64K = (1 << 11) | (1 << 12),
+};
+
+
 /* Twister tuning parameters from RealTek.
    Completely undocumented, but required to tune bad links. */
 enum CSCRBits {
@@ -307,6 +316,14 @@
 	CSCR_LinkDownOffCmd = 0x003c0,
 	CSCR_LinkDownCmd = 0x0f3c0,
 };
+
+
+enum Cfg9346Bits {
+	Cfg9346_Lock = 0x00,
+	Cfg9346_Unlock = 0xC0,
+};
+
+
 #define PARA78_default	0x78fa8388
 #define PARA7c_default	0xcb38de43	/* param[0][3] */
 #define PARA7c_xxx		0xcb38de43
@@ -327,7 +344,6 @@
 struct rtl8139_private {
 	chip_t chip;
 	void *mmio_addr;
-	spinlock_t lock;
 	int drv_flags;
 	struct pci_dev *pci_dev;
 	struct net_device_stats stats;
@@ -349,6 +365,8 @@
 	unsigned int media2:4;	/* Secondary monitored media port. */
 	unsigned int medialock:1;	/* Don't sense media type. */
 	unsigned int mediasense:1;	/* Media sensing in progress. */
+	int extended_regs;		/* bool: supports regs > 0x80 ? */
+	spinlock_t lock;
 };
 
 MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>");
@@ -374,6 +392,8 @@
 static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
 static inline u32 ether_crc (int length, unsigned char *data);
 static void rtl8139_set_rx_mode (struct net_device *dev);
+static void rtl8139_hw_start (struct net_device *dev);
+
 
 /* write MMIO register, with flush */
 /* Flush avoids rtl8139 bug w/ posted MMIO writes */
@@ -409,30 +429,17 @@
 	TxErr | TxOK | RxErr | RxOK;
 
 static const unsigned int rtl8139_rx_config =
-	    (RX_FIFO_THRESH << 13) |
-	    (RX_BUF_LEN_IDX << 11) |
+	    (RX_FIFO_THRESH << 13) | (RxCfgRcv32K) |
 	    (RX_DMA_BURST << 8);
 
 
-static const char * __devinit rtl8139_name_from_chip (chip_t chip)
-{
-	int i;
-	
-	for (i = 0; i < arraysize (chip_info); i++)
-		if (chip == chip_info[i].chip)
-			return chip_info[i].name;
-	
-	return "unknown";
-}
-
-
 static int __devinit rtl8139_init_pci (struct pci_dev *pdev, void **ioaddr_out)
 {
 	void *ioaddr = NULL;
 	u8 tmp8;
 	int rc;
-	u32 pio_start, pio_end, pio_flags;
-	u32 mmio_start, mmio_end, mmio_flags;
+	u32 pio_start, pio_end, pio_flags, pio_len;
+	u32 mmio_start, mmio_end, mmio_flags, mmio_len;
 
 	DPRINTK ("ENTER\n");
 
@@ -444,48 +451,67 @@
 	pio_start = pci_resource_start (pdev, 0);
 	pio_end = pci_resource_end (pdev, 0);
 	pio_flags = pci_resource_flags (pdev, 0);
+	pio_len = pci_resource_len (pdev, 0);
 
 	mmio_start = pci_resource_start (pdev, 1);
 	mmio_end = pci_resource_end (pdev, 1);
 	mmio_flags = pci_resource_flags (pdev, 1);
+	mmio_len = pci_resource_len (pdev, 1);
 
 	/* make sure PCI base addr 0 is PIO */
-	if (pio_start == 0 || pio_end <= pio_start ||
-	    (!(pio_flags & IORESOURCE_IO))) {
-		printk (KERN_ERR PFX "no PIO resource, aborting\n");
-		return -ENODEV;
+	if (!(pio_flags & IORESOURCE_IO)) {
+		printk (KERN_ERR PFX "region #0 not a PIO resource, aborting\n");
+		rc = -ENODEV;
+		goto err_out;
 	}
 	
 	/* make sure PCI base addr 1 is MMIO */
-	if (mmio_start == 0 || mmio_end <= mmio_start ||
-	    (!(mmio_flags & IORESOURCE_MEM))) {
-		printk (KERN_ERR PFX "no MMIO resource, aborting\n");
-		return -ENODEV;
+	if (!(mmio_flags & IORESOURCE_MEM)) {
+		printk (KERN_ERR PFX "region #1 not an MMIO resource, aborting\n");
+		rc = -ENODEV;
+		goto err_out;
+	}
+	
+	/* check for weird/broken PCI region reporting */
+	if ((pio_len != mmio_len) ||
+	    (pio_len < RTL_MIN_IO_SIZE) ||
+	    (mmio_len < RTL_MIN_IO_SIZE)) {
+		printk (KERN_ERR PFX "Invalid PCI region size(s), aborting\n");
+		rc = -ENODEV;
+		goto err_out;
 	}
 
 	/* make sure our PIO region in PCI space is available */
-	if (!request_region (pio_start, RTL_IO_SIZE, RTL8139_MODULE_NAME)) {
+	if (!request_region (pio_start, pio_len, RTL8139_MODULE_NAME)) {
 		printk (KERN_ERR PFX "no I/O resource available, aborting\n");
-		return -EBUSY;
+		rc = -EBUSY;
+		goto err_out;
 	}
 	
 	/* make sure our MMIO region in PCI space is available */
-	if (!request_mem_region (mmio_start, RTL_IO_SIZE, RTL8139_MODULE_NAME)) {
-		release_region (pio_start, RTL_IO_SIZE);
+	if (!request_mem_region (mmio_start, mmio_len, RTL8139_MODULE_NAME)) {
 		printk (KERN_ERR PFX "no mem resource available, aborting\n");
-		return -EBUSY;
+		rc = -EBUSY;
+		goto err_out_free_pio;
 	}
 	
 	/* enable device (incl. PCI PM wakeup), and bus-mastering */
-	pci_enable_device (pdev);
+	rc = pci_enable_device (pdev);
+	if (rc) {
+		printk (KERN_ERR PFX "cannot enable PCI device (bus %d, "
+			"devfn %d), aborting\n",
+			pdev->bus->number, pdev->devfn);
+		goto err_out_free_mmio;
+	}
+
 	pci_set_master (pdev);
 
 	/* ioremap MMIO region */
-	ioaddr = ioremap (mmio_start, RTL_IO_SIZE);
+	ioaddr = ioremap (mmio_start, mmio_len);
 	if (ioaddr == NULL) {
 		printk (KERN_ERR PFX "cannot remap MMIO, aborting\n");
 		rc = -EIO;
-		goto err_out;
+		goto err_out_free_mmio;
 	}
 
 	/* Bring the chip out of low-power mode. */
@@ -496,12 +522,12 @@
 	if ((tmp8 & Cfg1_PIO) == 0) {
 		printk (KERN_ERR PFX "PIO not enabled, Cfg1=%02X, aborting\n", tmp8);
 		rc = -EIO;
-		goto err_out;
+		goto err_out_iounmap;
 	}
 	if ((tmp8 & Cfg1_MMIO) == 0) {
 		printk (KERN_ERR PFX "MMIO not enabled, Cfg1=%02X, aborting\n", tmp8);
 		rc = -EIO;
-		goto err_out;
+		goto err_out_iounmap;
 	}
 	
 	/* sanity checks -- ensure PIO and MMIO registers agree */
@@ -514,28 +540,43 @@
 	*ioaddr_out = ioaddr;
 	return 0;	
 
+err_out_iounmap:
+	assert (ioaddr > 0);
+	iounmap (ioaddr);
+err_out_free_mmio:
+	release_mem_region (mmio_start, mmio_len);
+err_out_free_pio:
+	release_region (pio_start, pio_len);
 err_out:
-	if (ioaddr)
-		iounmap (ioaddr);
-	release_region (pio_start, RTL_IO_SIZE);
-	release_mem_region (mmio_start, RTL_IO_SIZE);
 	DPRINTK ("EXIT, returning %d\n", rc);
 	return rc;
 }
 
 
-static int __devinit rtl8139_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int __devinit rtl8139_init_one (struct pci_dev *pdev,
+				       const struct pci_device_id *ent)
 {
 	struct net_device *dev;
 	struct rtl8139_private *tp;
 	int i, addr_len, option = -1;
 	void *ioaddr = NULL;
 
+#ifndef RTL8139_NDEBUG
+	static int printed_version = 0;
+#endif /* RTL8139_NDEBUG */
+
 	DPRINTK ("ENTER\n");
 	
 	assert (pdev != NULL);
 	assert (ent != NULL);
-	
+
+#ifndef RTL8139_NDEBUG
+	if (!printed_version) {
+		printk (KERN_INFO RTL8139_DRIVER_NAME " loaded\n");
+		printed_version = 1;
+	}
+#endif /* RTL8139_NDEBUG */
+
 	i = rtl8139_init_pci (pdev, &ioaddr);
 	if (i < 0) {
 		DPRINTK ("EXIT, returning %d\n", i);
@@ -571,31 +612,34 @@
 	dev->irq = pdev->irq;
 	dev->base_addr = pci_resource_start (pdev, 1);
 
+	/* dev->priv/tp zeroed in init_etherdev */
 	dev->priv = tp = (void *)
 		(((long)dev->priv + PRIV_ALIGN) & ~PRIV_ALIGN);
 
-	printk (KERN_INFO "%s: %s at 0x%lx, IRQ %d, "
-		"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
-		dev->name, rtl8139_name_from_chip(ent->driver_data),
-		dev->base_addr, dev->irq,
-		dev->dev_addr[0], dev->dev_addr[1],
-		dev->dev_addr[2], dev->dev_addr[3],
-		dev->dev_addr[4], dev->dev_addr[5]);
-
-	/* tp zeroed in init_etherdev */
 	tp->drv_flags = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
 			PCI_COMMAND_MASTER | RTL8139_CAPS;
 	tp->pci_dev = pdev;
 	tp->chip = ent->driver_data;
 	tp->mmio_addr = ioaddr;
+	tp->extended_regs =
+		(pci_resource_len (pdev, 0) == RTL8139B_IO_SIZE) ? 1 : 0;
 	tp->lock = SPIN_LOCK_UNLOCKED;
 
 	PCI_SET_DRIVER_DATA (pdev, dev);
 
 	tp->phys[0] = 32;
 
+	printk (KERN_INFO "%s: %s at 0x%lx, IRQ %d,%s "
+		"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
+		dev->name, chip_info[ent->driver_data].name,
+		dev->base_addr, dev->irq,
+		tp->extended_regs ? " 8139B regs," : "",
+		dev->dev_addr[0], dev->dev_addr[1],
+		dev->dev_addr[2], dev->dev_addr[3],
+		dev->dev_addr[4], dev->dev_addr[5]);
+
 	/* Put the chip into low-power mode. */
-	RTL_W8 (Cfg9346, 0xC0);
+	RTL_W8 (Cfg9346, Cfg9346_Unlock);
 	RTL_W8 (Config1, 0x03);	/* Enable PM & PCI VPD */
 	RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
 
@@ -635,8 +679,10 @@
 	unregister_netdev (dev);
 
 	iounmap (np->mmio_addr);
-	release_region (pci_resource_start (pdev, 0), RTL_IO_SIZE);
-	release_mem_region (pci_resource_start (pdev, 1), RTL_IO_SIZE);
+	release_region (pci_resource_start (pdev, 0),
+			pci_resource_len (pdev, 0));
+	release_mem_region (pci_resource_start (pdev, 1),
+			    pci_resource_len (pdev, 1));
 
 #ifndef RTL8139_NDEBUG
 	/* poison memory before freeing */
@@ -644,7 +690,7 @@
 		sizeof (struct net_device) +
 		sizeof (struct rtl8139_private) +
 		PRIV_ALIGN);
-#endif
+#endif /* RTL8139_NDEBUG */
 
 	kfree (dev);
 	
@@ -851,16 +897,14 @@
 static int rtl8139_open (struct net_device *dev)
 {
 	struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
+#ifdef RTL8139_DEBUG
 	void *ioaddr = tp->mmio_addr;
-	int i;
+#endif
 
 	DPRINTK ("ENTER\n");
 
 	MOD_INC_USE_COUNT;
 
-	/* Soft reset the chip. */
-	RTL_W8 (ChipCmd, CmdReset);
-
 	if (request_irq (dev->irq, &rtl8139_interrupt, SA_SHIRQ, dev->name, dev)) {
 		DPRINTK ("EXIT, returning -EBUSY\n");
 		MOD_DEC_USE_COUNT;
@@ -891,44 +935,7 @@
 	tp->full_duplex = tp->duplex_lock;
 	tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;
 
-	/* Check that the chip has finished the reset. */
-	for (i = 1000; i > 0; i--)
-		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
-			break;
-
-	RTL_W32_F (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
-	RTL_W32_F (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
-
-	/* Must enable Tx/Rx before setting transfer thresholds! */
-	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
-	RTL_W32 (RxConfig, rtl8139_rx_config);
-	RTL_W32 (TxConfig, (TX_DMA_BURST << 8) | 0x00000000);
-
-	/* Reset N-Way to chipset defaults */
-	RTL_W16 (BasicModeCtrl, (1<<15)|(1<<12)|(1<<9));
-	for (i = 1000; i > 0; i--)
-		if ((RTL_R8 (BasicModeCtrl) & (1<<15)) == 0)
-			break;
-	
-	/* Set N-Way to sane defaults */
-	RTL_W16 (FIFOTMS, 0x0000);
-	RTL_W16 (NWayAdvert, (1<<13)|(1<<8)|(1<<7)|(1<<6)|(1<<5)|0x1);
-	RTL_W16 (BasicModeCtrl, (1<<13)|(1<<12)|(1<<9)|(1<<8));
-	
-	RTL_W8 (Cfg9346, 0xC0);
-	RTL_W8 (Config1, tp->full_duplex ? 0x60 : 0x20);
-	RTL_W8 (Cfg9346, 0x00);
-
-	RTL_W32 (RxBuf, tp->rx_ring_dma);
-
-	/* Start the chip's Tx and Rx process. */
-	RTL_W32 (RxMissed, 0);
-	rtl8139_set_rx_mode (dev);
-
-	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
-
-	/* Enable all known interrupts by setting the interrupt mask. */
-	RTL_W16 (IntrMask, rtl8139_intr_mask);
+	rtl8139_hw_start (dev);
 
 	DPRINTK ("%s: rtl8139_open() ioaddr %#lx IRQ %d"
 			" GP Pins %2.2x %s-duplex.\n",
@@ -944,23 +951,26 @@
 	tp->timer.function = &rtl8139_timer;
 	add_timer (&tp->timer);
 
-	netif_start_queue (dev);
-
 	DPRINTK ("EXIT, returning 0\n");
 	return 0;
 }
 
+
 /* Start the hardware at open or resume. */
 static void rtl8139_hw_start (struct net_device *dev)
 {
 	struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
 	void *ioaddr = tp->mmio_addr;
 	int i;
+	unsigned long flags;
 
 	DPRINTK ("ENTER\n");
+	
+	spin_lock_irqsave (&tp->lock, flags);
 
 	/* Soft reset the chip. */
 	RTL_W8 (ChipCmd, CmdReset);
+
 	/* Check that the chip has finished the reset. */
 	for (i = 1000; i > 0; i--)
 		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
@@ -970,8 +980,9 @@
 	RTL_W32_F (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
 	RTL_W32_F (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
 
-	/* Hmmm, do these belong here? */
-	RTL_W8 (Cfg9346, 0x00);
+	/* unlock Config[01234] and BMCR register writes */
+	RTL_W8 (Cfg9346, Cfg9346_Unlock);
+
 	tp->cur_rx = 0;
 
 	/* Must enable Tx/Rx before setting transfer thresholds! */
@@ -993,19 +1004,30 @@
 	RTL_W16 (BasicModeCtrl, (1<<13)|(1<<12)|(1<<9)|(1<<8));
 	
 	/* check_duplex() here. */
-	RTL_W8 (Cfg9346, 0xC0);
 	RTL_W8 (Config1, tp->full_duplex ? 0x60 : 0x20);
-	RTL_W8 (Cfg9346, 0x00);
+
+	/* lock Config[01234] and BMCR register writes */
+	RTL_W8 (Cfg9346, Cfg9346_Lock);
 
 	RTL_W32 (RxBuf, tp->rx_ring_dma);
+
 	/* Start the chip's Tx and Rx process. */
 	RTL_W32 (RxMissed, 0);
+
+	/* release lock cuz set_rx_mode wants it */
+	spin_unlock_irqrestore (&tp->lock, flags);
 	rtl8139_set_rx_mode (dev);
+	spin_lock_irqsave (&tp->lock, flags);
+
 	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
+
 	/* Enable all known interrupts by setting the interrupt mask. */
 	RTL_W16 (IntrMask, rtl8139_intr_mask);
 
-	netif_start_queue (dev);
+	if (netif_queue_stopped (dev))
+		netif_start_queue (dev);
+
+	spin_unlock_irqrestore (&tp->lock, flags);
 
 	DPRINTK ("EXIT\n");
 }
@@ -1111,9 +1133,14 @@
 	struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
 	void *ioaddr = tp->mmio_addr;
 	int next_tick = 60 * HZ;
-	int mii_reg5 = mdio_read (dev, tp->phys[0], 5);
+	int mii_reg5;
+	unsigned long flags;
 
 	DPRINTK ("ENTER\n");
+	
+	spin_lock_irqsave (&tp->lock, flags);
+
+	mii_reg5 = mdio_read (dev, tp->phys[0], 5);
 
 	if (!tp->duplex_lock && mii_reg5 != 0xffff) {
 		int duplex = (mii_reg5 & 0x0100)
@@ -1125,9 +1152,9 @@
 				" partner ability of %4.4x.\n", dev->name,
 				tp->full_duplex ? "full" : "half",
 				tp->phys[0], mii_reg5);
-			RTL_W8 (Cfg9346, 0xC0);
+			RTL_W8 (Cfg9346, Cfg9346_Unlock);
 			RTL_W8 (Config1, tp->full_duplex ? 0x60 : 0x20);
-			RTL_W8 (Cfg9346, 0x00);
+			RTL_W8 (Cfg9346, Cfg9346_Lock);
 		}
 	}
 
@@ -1144,6 +1171,8 @@
 		 dev->name, RTL_R8 (Config0),
 		 RTL_R8 (Config1));
 
+	spin_unlock_irqrestore (&tp->lock, flags);
+
 	tp->timer.expires = jiffies + next_tick;
 	add_timer (&tp->timer);
 
@@ -1156,10 +1185,11 @@
 	struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
 	void *ioaddr = tp->mmio_addr;
 	int mii_reg, i;
+	unsigned long flags;
 
 	DPRINTK ("ENTER\n");
 
-	netif_stop_queue (dev);
+	spin_lock_irqsave (&tp->lock, flags);
 
 	DPRINTK ("%s: Transmit timeout, status %2.2x %4.4x "
 		 "media %2.2x.\n", dev->name,
@@ -1201,6 +1231,8 @@
 		}
 	}
 
+	spin_unlock_irqrestore (&tp->lock, flags);
+
 	rtl8139_hw_start (dev);
 
 	DPRINTK ("EXIT\n");
@@ -1227,6 +1259,7 @@
 	DPRINTK ("EXIT\n");
 }
 
+
 static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
 {
 	struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
@@ -1236,13 +1269,11 @@
 
 	DPRINTK ("ENTER\n");
 	
-	netif_stop_queue (dev);
+	spin_lock_irqsave (&tp->lock, flags);
 
 	/* Calculate the next Tx descriptor entry. */
 	entry = tp->cur_tx % NUM_TX_DESC;
 
-	spin_lock_irqsave (&tp->lock, flags);
-	
 	tp->tx_info[entry].skb = skb;
 	if ((long) skb->data & 3) {	/* Must use alignment buffer. */
 		tp->tx_info[entry].mapping = 0;
@@ -1263,12 +1294,12 @@
 		 tp->tx_flag | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
 
 	dev->trans_start = jiffies;
-	if (++tp->cur_tx - tp->dirty_tx < NUM_TX_DESC)	/* Typical path */
-		netif_start_queue (dev);
+	if (++tp->cur_tx - tp->dirty_tx >= NUM_TX_DESC)
+		netif_stop_queue (dev);
 
 	spin_unlock_irqrestore (&tp->lock, flags);
-	
-	DPRINTK ("%s: Queued Tx packet at %p size %lu to slot %d.\n",
+
+	DPRINTK ("%s: Queued Tx packet at %p size %u to slot %d.\n",
 		 dev->name, skb->data, skb->len, entry);
 
 	DPRINTK ("EXIT\n");
@@ -1277,16 +1308,16 @@
 
 
 static inline void rtl8139_tx_interrupt (struct net_device *dev,
-					 struct rtl8139_private *tp)
+					 struct rtl8139_private *tp,
+					 void *ioaddr)
 {
-	void *ioaddr;
 	unsigned int dirty_tx;
 
 	assert (dev != NULL);
 	assert (tp != NULL);
-
+	assert (ioaddr != NULL);
+	
 	dirty_tx = tp->dirty_tx;
-	ioaddr = tp->mmio_addr;
 
 	while (tp->cur_tx - dirty_tx > 0) {
 		int entry = dirty_tx % NUM_TX_DESC;
@@ -1338,8 +1369,6 @@
 		dirty_tx++;
 		if (tp->cur_tx - dirty_tx < NUM_TX_DESC)
 			netif_wake_queue (dev);
-		else
-			netif_stop_queue (dev);
 	}
 
 #ifndef RTL8139_NDEBUG
@@ -1349,7 +1378,7 @@
 		     dev->name, dirty_tx, tp->cur_tx);
 		dirty_tx += NUM_TX_DESC;
 	}
-#endif
+#endif /* RTL8139_NDEBUG */
 
 	tp->dirty_tx = dirty_tx;
 }
@@ -1358,11 +1387,18 @@
 /* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the
    field alignments and semantics. */
 static inline void rtl8139_rx_interrupt (struct net_device *dev,
-					 struct rtl8139_private *tp)
+					 struct rtl8139_private *tp,
+					 void *ioaddr)
 {
-	void *ioaddr = tp->mmio_addr;
-	unsigned char *rx_ring = tp->rx_ring;
-	u16 cur_rx = tp->cur_rx;
+	unsigned char *rx_ring;
+	u16 cur_rx;
+
+	assert (dev != NULL);
+	assert (tp != NULL);
+	assert (ioaddr != NULL);
+	
+	rx_ring = tp->rx_ring;
+	cur_rx = tp->cur_rx;
 
 	DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
 			" free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
@@ -1376,15 +1412,17 @@
 		    le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
 		int rx_size = rx_status >> 16;
 
-#ifdef RTL8139_DEBUG
-		int i;
 		DPRINTK ("%s:  rtl8139_rx() status %4.4x, size %4.4x,"
 			" cur %4.4x.\n", dev->name, rx_status,
 			rx_size, cur_rx);
+#if RTL8139_DEBUG > 2
+		{
+		int i;
 		DPRINTK ("%s: Frame contents ", dev->name);
 		for (i = 0; i < 70; i++)
 			printk (" %2.2x", rx_ring[ring_offset + i]);
 		printk (".\n");
+		}
 #endif
 
 		/* E. Gill */
@@ -1490,23 +1528,16 @@
 
 static inline int rtl8139_weird_interrupt (struct net_device *dev,
 					   struct rtl8139_private *tp,
+					   void *ioaddr,
 					   int status, int link_changed)
 {
-	void *ioaddr;
-
 	DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n",
 		 dev->name, status);
 		 
 	assert (dev != NULL);
 	assert (tp != NULL);
-
-	ioaddr = tp->mmio_addr;
-
-	if (status == 0xffffffff) {
-		printk (KERN_WARNING PFX "abnormal interrupt, card ejected? (ok to ignore)\n");
-		return -1;
-	}
-
+	assert (ioaddr != NULL);
+	
 	/* Update the error count. */
 	tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
 	RTL_W32 (RxMissed, 0);
@@ -1519,9 +1550,9 @@
 				|| tp->duplex_lock;
 		if (tp->full_duplex != duplex) {
 			tp->full_duplex = duplex;
-			RTL_W8 (Cfg9346, 0xC0);
+			RTL_W8 (Cfg9346, Cfg9346_Unlock);
 			RTL_W8 (Config1, tp->full_duplex ? 0x60 : 0x20);
-			RTL_W8 (Cfg9346, 0x00);
+			RTL_W8 (Cfg9346, Cfg9346_Lock);
 		}
 		status &= ~RxUnderrun;
 	}
@@ -1559,15 +1590,20 @@
 	struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
 	int boguscnt = max_interrupt_work;
 	void *ioaddr = tp->mmio_addr;
-	int link_changed = 0;	/* Grrr, avoid bogus "uninitialized" warning */
-
-	spin_lock_irq (&tp->lock);
+	int status = 0, link_changed = 0; /* avoid bogus "uninit" warning */
 
+	spin_lock (&tp->lock);
+	
 	/* disable interrupt generation while handling this interrupt */
 	RTL_W16 (IntrMask, 0x0000);
 
 	do {
-		int status = RTL_R16 (IntrStatus);
+		status = RTL_R16 (IntrStatus);
+
+		/* h/w no longer present (hotplug?) or major error, bail */
+		if (status == 0xFFFFFFFF)
+			break;
+		
 		/* Acknowledge all of the current interrupt sources ASAP, but
 		   an first get an additional status bit from CSCR. */
 		if (status & RxUnderrun)
@@ -1606,42 +1642,45 @@
 		/* Check uncommon events with one test. */
 		if (status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
 		  	      RxFIFOOver | TxErr | RxErr))
-			if (rtl8139_weird_interrupt (dev, tp, status,
-						     link_changed) == -1)
-				break;
+			rtl8139_weird_interrupt (dev, tp, ioaddr,
+						 status, link_changed);
 
 		if (status & (RxOK | RxUnderrun | RxOverflow | RxFIFOOver))	/* Rx interrupt */
-			rtl8139_rx_interrupt (dev, tp);
+			rtl8139_rx_interrupt (dev, tp, ioaddr);
 
 		if (status & (TxOK | TxErr))
-			rtl8139_tx_interrupt (dev, tp);
+			rtl8139_tx_interrupt (dev, tp, ioaddr);
 
-		if (--boguscnt < 0) {
-			printk (KERN_WARNING
-				"%s: Too much work at interrupt, "
-				"IntrStatus=0x%4.4x.\n", dev->name,
-				status);
-			/* Clear all interrupt sources. */
-			RTL_W16 (IntrStatus, 0xffff);
-			break;
-		}
-	} while (1);
+		boguscnt--;
+	} while (boguscnt > 0);
+
+	if (boguscnt <= 0) {
+		printk (KERN_WARNING
+			"%s: Too much work at interrupt, "
+			"IntrStatus=0x%4.4x.\n", dev->name,
+			status);
+
+		/* Clear all interrupt sources. */
+		RTL_W16 (IntrStatus, 0xffff);
+	}
 
 	/* Enable all known interrupts by setting the interrupt mask. */
 	RTL_W16 (IntrMask, rtl8139_intr_mask);
 
-	spin_unlock_irq (&tp->lock);
-
+	spin_unlock (&tp->lock);
+	
 	DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
-			dev->name, RTL_R16 (IntrStatus));
+		 dev->name, RTL_R16 (IntrStatus));
 
 }
 
+
 static int rtl8139_close (struct net_device *dev)
 {
 	struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
 	void *ioaddr = tp->mmio_addr;
 	int i;
+	unsigned long flags;
 
 	DPRINTK ("ENTER\n");
 
@@ -1650,6 +1689,8 @@
 	DPRINTK ("%s: Shutting down ethercard, status was 0x%4.4x.\n",
 			dev->name, RTL_R16 (IntrStatus));
 
+	spin_lock_irqsave (&tp->lock, flags);
+
 	/* Disable interrupts by clearing the interrupt mask. */
 	RTL_W16 (IntrMask, 0x0000);
 
@@ -1660,7 +1701,13 @@
 	tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
 	RTL_W32 (RxMissed, 0);
 
+	spin_unlock_irqrestore (&tp->lock, flags);
+	
 	del_timer (&tp->timer);
+	
+	/* snooze for a small bit */
+	if (current->need_resched)
+		schedule ();
 
 	free_irq (dev->irq, dev);
 
@@ -1685,7 +1732,7 @@
 	tp->tx_bufs = NULL;
 
 	/* Green! Put the chip in low-power mode. */
-	RTL_W8 (Cfg9346, 0xC0);
+	RTL_W8 (Cfg9346, Cfg9346_Unlock);
 	RTL_W8 (Config1, 0x03);
 	RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
 
@@ -1695,10 +1742,13 @@
 	return 0;
 }
 
+
 static int mii_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
 	u16 *data = (u16 *) & rq->ifr_data;
+	unsigned long flags;
+	int rc = 0;
 
 	DPRINTK ("ENTER\n");
 
@@ -1706,24 +1756,34 @@
 	case SIOCDEVPRIVATE:	/* Get the address of the PHY in use. */
 		data[0] = tp->phys[0] & 0x3f;
 		/* Fall Through */
+
 	case SIOCDEVPRIVATE + 1:	/* Read the specified MII register. */
+		spin_lock_irqsave (&tp->lock, flags);
 		data[3] = mdio_read (dev, data[0], data[1] & 0x1f);
-		DPRINTK ("EXIT\n");
-		return 0;
+		spin_unlock_irqrestore (&tp->lock, flags);
+		break;
+
 	case SIOCDEVPRIVATE + 2:	/* Write the specified MII register */
-		if (!capable (CAP_NET_ADMIN))
-			return -EPERM;
+		if (!capable (CAP_NET_ADMIN)) {
+			rc = -EPERM;
+			break;
+		}
+
+		spin_lock_irqsave (&tp->lock, flags);
 		mdio_write (dev, data[0], data[1] & 0x1f, data[2]);
-		DPRINTK ("EXIT\n");
-		return 0;
+		spin_unlock_irqrestore (&tp->lock, flags);
+		break;
+
 	default:
-		DPRINTK ("EXIT\n");
-		return -EOPNOTSUPP;
+		rc = -EOPNOTSUPP;
+		break;
 	}
 
-	DPRINTK ("EXIT\n");
+	DPRINTK ("EXIT, returning %d\n", rc);
+	return rc;
 }
 
+
 static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
 {
 	struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
@@ -1734,8 +1794,14 @@
 	assert (tp != NULL);
 
 	if (netif_running(dev)) {
+		unsigned long flags;
+
+		spin_lock_irqsave (&tp->lock, flags);
+
 		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
 		RTL_W32 (RxMissed, 0);
+
+		spin_unlock_irqrestore (&tp->lock, flags);
 	}
 
 	DPRINTK ("EXIT\n");
@@ -1765,12 +1831,14 @@
 	return crc;
 }
 
+
 static void rtl8139_set_rx_mode (struct net_device *dev)
 {
 	struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
 	void *ioaddr = tp->mmio_addr;
 	u32 mc_filter[2];	/* Multicast hash filter */
 	int i, rx_mode;
+	unsigned long flags;
 
 	DPRINTK ("ENTER\n");
 
@@ -1803,11 +1871,19 @@
 						       dmi_addr) >> 26,
 					    mc_filter);
 	}
+	
+	/* if called from irq handler, lock already acquired */
+	if (!in_irq ())
+		spin_lock_irqsave (&tp->lock, flags);
+
 	/* We can safely update without stopping the chip. */
 	RTL_W32 (RxConfig, rtl8139_rx_config | rx_mode);
 	RTL_W32_F (MAR0 + 0, mc_filter[0]);
 	RTL_W32_F (MAR0 + 4, mc_filter[1]);
 
+	if (!in_irq ())
+		spin_unlock_irqrestore (&tp->lock, flags);
+
 	DPRINTK ("EXIT\n");
 }
 
@@ -1817,9 +1893,12 @@
 	struct net_device *dev = PCI_GET_DRIVER_DATA (pdev);
 	struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
 	void *ioaddr = tp->mmio_addr;
+	unsigned long flags;
 
-	netif_stop_queue (dev);
+	netif_device_detach (dev);
 	
+	spin_lock_irqsave (&tp->lock, flags);
+
 	/* Disable interrupts, stop Tx and Rx. */
 	RTL_W16 (IntrMask, 0x0000);
 	RTL_W8 (ChipCmd, 0x00);
@@ -1827,6 +1906,8 @@
 	/* Update the error counts. */
 	tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
 	RTL_W32 (RxMissed, 0);
+
+	spin_unlock_irqrestore (&tp->lock, flags);
 }
 
 
@@ -1834,7 +1915,8 @@
 {
 	struct net_device *dev = PCI_GET_DRIVER_DATA (pdev);
 
-	rtl8139_hw_start(dev);
+	netif_device_attach (dev);
+	rtl8139_hw_start (dev);
 }
 
 
@@ -1850,22 +1932,7 @@
 
 static int __init rtl8139_init_module (void)
 {
-	int rc;
-	
-	DPRINTK ("ENTER\n");
-
-	rc = pci_register_driver (&rtl8139_pci_driver);
-	
-	if (rc > 0) {
-		printk (KERN_INFO RTL8139_DRIVER_NAME
-			" loaded (%d device%s registered)\n",
-			rc, rc > 1 ? "s" : "");
-	} else {
-		pci_unregister_driver (&rtl8139_pci_driver);
-	}
-
-	DPRINTK ("EXIT\n");
-	return rc > 0 ? 0 : -ENODEV;
+	return pci_module_init (&rtl8139_pci_driver);
 }
 
 
diff -u --recursive --new-file v2.3.47/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v2.3.47/linux/drivers/net/Config.in	Sun Feb 20 21:12:39 2000
+++ linux/drivers/net/Config.in	Thu Feb 24 22:49:19 2000
@@ -46,6 +46,9 @@
    if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then
       tristate '  MIPS JAZZ onboard SONIC Ethernet support' CONFIG_MIPS_JAZZ_SONIC
    fi
+   if [ "$CONFIG_SGI_IP27" = "y" ]; then
+      bool ' SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH
+   fi
    bool '  3COM cards' CONFIG_NET_VENDOR_3COM
    if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
       tristate '    3c501 support' CONFIG_EL1
@@ -251,9 +254,7 @@
 bool 'Wireless LAN (non-hamradio)' CONFIG_NET_RADIO
 if [ "$CONFIG_NET_RADIO" = "y" ]; then
    dep_tristate '  STRIP (Metricom starmode radio IP)' CONFIG_STRIP $CONFIG_INET
-   if [ "$CONFIG_OBSOLETE" = "y" ]; then
-      tristate '  AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN
-   fi
+   tristate '  AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN
    tristate '  Aironet Arlan 655 & IC2200 DS support' CONFIG_ARLAN
    tristate '  Aironet 4500/4800 series adapters' CONFIG_AIRONET4500
    dep_tristate '   Aironet 4500/4800 ISA/PCI/PNP/365 support ' CONFIG_AIRONET4500_NONCS $CONFIG_AIRONET4500
diff -u --recursive --new-file v2.3.47/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v2.3.47/linux/drivers/net/Makefile	Sun Feb 20 21:12:39 2000
+++ linux/drivers/net/Makefile	Thu Feb 24 22:49:19 2000
@@ -18,7 +18,7 @@
 MOD_SUB_DIRS :=
 MOD_IN_SUB_DIRS :=
 ALL_SUB_DIRS := $(SUB_DIRS) fc hamradio irda pcmcia tokenring wan sk98lin \
-		arcnet skfp
+		arcnet skfp tulip
 
 O_TARGET := net.o
 MOD_LIST_NAME := NET_MODULES
@@ -38,6 +38,15 @@
   endif
 endif
 
+ifeq ($(CONFIG_TULIP),y)
+  SUB_DIRS += tulip
+  obj-y += tulip/tulip.o
+else
+  ifeq ($(CONFIG_TULIP),m)
+    MOD_SUB_DIRS += tulip
+  endif
+endif
+
 ifeq ($(CONFIG_IRDA),y)
 SUB_DIRS += irda
 MOD_IN_SUB_DIRS += irda
@@ -122,7 +131,6 @@
 obj-$(CONFIG_PCNET32) += pcnet32.o
 obj-$(CONFIG_EEPRO100) += eepro100.o
 obj-$(CONFIG_TLAN) += tlan.o
-obj-$(CONFIG_TULIP) += tulip.o
 obj-$(CONFIG_EPIC100) += epic100.o
 obj-$(CONFIG_SIS900) += sis900.o
 obj-$(CONFIG_DM9102) += dmfe.o
@@ -261,6 +269,7 @@
 obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o
 obj-$(CONFIG_EQUALIZER) += eql.o
 obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
+obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
 obj-$(CONFIG_BAGETLANCE) += bagetlance.o
 obj-$(CONFIG_DECLANCE) += declance.o
 obj-$(CONFIG_ATARILANCE) += atarilance.o
diff -u --recursive --new-file v2.3.47/linux/drivers/net/Space.c linux/drivers/net/Space.c
--- v2.3.47/linux/drivers/net/Space.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/net/Space.c	Thu Feb 24 22:49:19 2000
@@ -79,6 +79,7 @@
 extern int ni52_probe(struct net_device *);
 extern int ni65_probe(struct net_device *);
 extern int sonic_probe(struct net_device *);
+extern int ioc3_probe(struct net_device *);
 extern int SK_init(struct net_device *);
 extern int seeq8005_probe(struct net_device *);
 extern int smc_init( struct net_device * );
@@ -384,6 +385,9 @@
 struct devprobe mips_probes[] __initdata = {
 #ifdef CONFIG_MIPS_JAZZ_SONIC
 	{sonic_probe, 0},
+#endif
+#ifdef CONFIG_SGI_IOC3_ETH
+	{ioc3_probe, 0},
 #endif
 #ifdef CONFIG_DECLANCE		/* DECstation on-board controller */
 	{dec_lance_probe, 0},   /* and maybe TURBOchannel option boards */
diff -u --recursive --new-file v2.3.47/linux/drivers/net/bagetlance.c linux/drivers/net/bagetlance.c
--- v2.3.47/linux/drivers/net/bagetlance.c	Tue Aug 31 17:29:14 1999
+++ linux/drivers/net/bagetlance.c	Thu Feb 24 22:49:19 2000
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: bagetlance.c,v 1.2 1999/10/09 00:01:21 ralf Exp $
  * vmelance.c: Ethernet driver for VME Lance cards on Baget/MIPS
  *      This code stealed and adopted from linux/drivers/net/atarilance.c
  *      See that for author info
diff -u --recursive --new-file v2.3.47/linux/drivers/net/declance.c linux/drivers/net/declance.c
--- v2.3.47/linux/drivers/net/declance.c	Tue Aug 31 17:29:14 1999
+++ linux/drivers/net/declance.c	Thu Feb 24 22:49:19 2000
@@ -60,6 +60,7 @@
 #include <asm/dec/machtype.h>
 #include <asm/dec/tc.h>
 #include <asm/dec/kn01.h>
+#include <asm/wbflush.h>
 #include <asm/addrspace.h>
 
 #include <linux/config.h>
@@ -301,6 +302,7 @@
 static inline void writereg(volatile unsigned short *regptr, short value)
 {
 	*regptr = value;
+	wbflush();
 }
 
 /* Load the CSR registers */
@@ -380,6 +382,7 @@
 		}
 	}
 
+	wbflush();
 }
 
 void cp_from_buf(void *to, unsigned char *from, int len)
@@ -515,6 +518,7 @@
 		if (i < 3 && ZERO)
 			printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->rx_buf_ptr_cpu[i]);
 	}
+	wbflush();
 }
 
 static int init_restart_lance(struct lance_private *lp)
@@ -752,6 +756,7 @@
 			 * re-enable LANCE DMA
 			 */
 			*(unsigned long *) (system_base + IOCTL + SSR) |= (1 << 16);
+			wbflush();
 		}
 		writereg(&ll->rdp, LE_C0_STOP);
 
@@ -1071,6 +1076,7 @@
 		lp->dma_ptr_reg = (unsigned long *) (system_base + IOCTL + LANCE_DMA_P);
 		*(lp->dma_ptr_reg) = PHYSADDR(dev->mem_start) << 3;
 		*(unsigned long *) (system_base + IOCTL + SSR) |= (1 << 16);
+		wbflush();
 
 		break;
 	case PMAD_LANCE:
diff -u --recursive --new-file v2.3.47/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- v2.3.47/linux/drivers/net/eepro100.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/net/eepro100.c	Sat Feb 26 20:22:09 2000
@@ -536,6 +536,9 @@
 
 	static int did_version = 0;			/* Already printed version info. */
 
+	if (speedo_debug > 0  &&  did_version++ == 0)
+		printk(version);
+
 #ifdef USE_IO
 	ioaddr = pci_resource_start (pdev, 0);
 #else
@@ -569,9 +572,6 @@
 	}
 #endif
 
-	if (speedo_debug > 0  &&  did_version++ == 0)
-		printk(version);
-
 	tx_ring = pci_alloc_consistent(pdev, TX_RING_SIZE * sizeof(struct TxFD)
 					     + sizeof(struct speedo_stats), &tx_ring_dma);
 	if (!tx_ring) {
@@ -604,7 +604,11 @@
 		acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
 	}
 
-	pci_enable_device (pdev);
+	if (pci_enable_device (pdev)) {
+		printk(KERN_ERR PFX "Could not enable PCI device\n");
+		goto err_out_free_netdev;
+	}
+
 	pci_set_master (pdev);
 
 	/* Read the station address EEPROM before doing the reset.
@@ -732,11 +736,12 @@
 	/* Return the chip to its original power state. */
 	pci_set_power_state (pdev, acpi_idle_state);
 
+	pdev->driver_data = dev;
+
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
 
 	sp = dev->priv;
-	memset(sp, 0, sizeof(*sp));
 
 	sp->pdev = pdev;
 	sp->acpi_pwr = acpi_idle_state;
@@ -872,6 +877,8 @@
 	if (speedo_debug > 1)
 		printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq);
 
+	MOD_INC_USE_COUNT;
+
 	pci_set_power_state(sp->pdev, 0);
 
 	/* Set up the Tx queue early.. */
@@ -882,12 +889,13 @@
 	spin_lock_init(&sp->lock);
 
 	/* .. we can safely take handler calls during init. */
-	if (request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, dev->name, dev))
+	if (request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, dev->name, dev)) {
+		MOD_DEC_USE_COUNT;
 		return -EBUSY;
-
-	MOD_INC_USE_COUNT;
+	}
 
 	dev->if_port = sp->default_port;
+
 #if 0
 	/* With some transceivers we must retrigger negotiation to reset
 	   power-up errors. */
@@ -1174,8 +1182,6 @@
 	long ioaddr = dev->base_addr;
 	int entry;
 
-	netif_stop_queue (dev);
-
 	/* Caution: the write order is important here, set the base address
 	   with the "ownership" bits last. */
 
@@ -1216,16 +1222,15 @@
 		}
 		if (sp->cur_tx - sp->dirty_tx >= TX_QUEUE_LIMIT) {
 			sp->tx_full = 1;
+			netif_stop_queue (dev);
 		}
 		spin_unlock_irqrestore(&sp->lock, flags);
 	}
+
 	wait_for_cmd_done(ioaddr + SCBCmd);
 	outw(CUResume, ioaddr + SCBCmd);
 	dev->trans_start = jiffies;
 	
-	if (! sp->tx_full)
-		netif_start_queue (dev);
-
 	return 0;
 }
 
@@ -1328,22 +1333,18 @@
 				&&  sp->cur_tx - dirty_tx < TX_QUEUE_LIMIT - 1) {
 				/* The ring is no longer full, clear tbusy. */
 				sp->tx_full = 0;
-			}
-			
-			if (sp->tx_full)
-				netif_stop_queue (dev);
-			else
 				netif_wake_queue (dev);
+			}
 		}
 
-		if (--boguscnt < 0) {
-			printk(KERN_ERR "%s: Too much work at interrupt, status=0x%4.4x.\n",
-				   dev->name, status);
-			/* Clear all interrupt sources. */
-			outl(0xfc00, ioaddr + SCBStatus);
-			break;
-		}
-	} while (1);
+	} while (--boguscnt > 0);
+
+	if (boguscnt <= 0) {
+		printk(KERN_ERR "%s: Too much work at interrupt, status=0x%4.4x.\n",
+			   dev->name, status);
+		/* Clear all interrupt sources. */
+		outl(0xfc00, ioaddr + SCBStatus);
+	}
 
 	if (speedo_debug > 3)
 		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
@@ -1502,8 +1503,8 @@
 		/* Clear the Tx descriptors. */
 		if (skb) {
 			pci_unmap_single(sp->pdev,
-							 le32_to_cpu(sp->tx_ring[i].tx_buf_addr0),
-							 skb->len, PCI_DMA_TODEVICE);
+					 le32_to_cpu(sp->tx_ring[i].tx_buf_addr0),
+					 skb->len, PCI_DMA_TODEVICE);
 			dev_kfree_skb(skb);
 		}
 	}
@@ -1811,8 +1812,6 @@
 	iounmap ((char *) dev->base_addr);
 #endif
 
-	pci_set_power_state (pdev, sp->acpi_pwr);
-
 	pci_free_consistent(pdev, TX_RING_SIZE * sizeof(struct TxFD)
 				  + sizeof(struct speedo_stats),
 			    sp->tx_ring, sp->tx_ring_dma);
@@ -1841,23 +1840,10 @@
 
 static int __init eepro100_init_module(void)
 {
-	int cards_found;
-
 	if (debug >= 0)
 		speedo_debug = debug;
 
-	/* Always emit the version message. */
-	if (speedo_debug)
-		printk(KERN_INFO "%s", version);
-
-	cards_found = pci_register_driver (&eepro100_driver);
-	if (cards_found <= 0) {
-		printk(KERN_INFO PFX "No cards found, driver not installed.\n");
-		pci_unregister_driver (&eepro100_driver);
-		return -ENODEV;
-	}
-
-	return 0;
+	return pci_module_init (&eepro100_driver);
 }
 
 
diff -u --recursive --new-file v2.3.47/linux/drivers/net/hamradio/6pack.c linux/drivers/net/hamradio/6pack.c
--- v2.3.47/linux/drivers/net/hamradio/6pack.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/net/hamradio/6pack.c	Tue Feb 22 10:20:11 2000
@@ -752,8 +752,8 @@
 				 * VSV = if dev->start==0, then device
 				 * unregistered while close proc.
 				 */ 
-				if (netif_running(sixpack_ctrls[i]->dev))
-					unregister_netdev(&(sixpack_ctrls[i]->dev));
+				if (netif_running(&sixpack_ctrls[i]->dev))
+					unregister_netdev(&sixpack_ctrls[i]->dev);
 
 				kfree(sixpack_ctrls[i]);
 				sixpack_ctrls[i] = NULL;
diff -u --recursive --new-file v2.3.47/linux/drivers/net/ioc3-eth.c linux/drivers/net/ioc3-eth.c
--- v2.3.47/linux/drivers/net/ioc3-eth.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/ioc3-eth.c	Thu Feb 24 22:49:19 2000
@@ -0,0 +1,905 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Driver for SGI's IOC3 based Ethernet cards as found in the PCI card.
+ *
+ * Copyright (C) 1999, 2000 Ralf Baechle
+ * Copyright (C) 1995, 1999, 2000 by Silicon Graphics, Inc.
+ *
+ * Reporting bugs:
+ *
+ * If you find problems with this drivers, then if possible do the
+ * following.  Hook up a terminal to the MSC port, send an NMI to the CPUs
+ * by typing ^Tnmi (where ^T stands for <CTRL>-T).  You'll see something
+ * like:
+ * 1A 000: 
+ * 1A 000: *** NMI while in Kernel and no NMI vector installed on node 0
+ * 1A 000: *** Error EPC: 0xffffffff800265e4 (0xffffffff800265e4)
+ * 1A 000: *** Press ENTER to continue.
+ *
+ * Next enter the command ``lw i:0x86000f0 0x18'' and include this
+ * commands output which will look like below with your bugreport.
+ *
+ * 1A 000: POD MSC Dex> lw i:0x86000f0 0x18
+ * 1A 000: 92000000086000f0: 0021f28c 00000000 00000000 00000000
+ * 1A 000: 9200000008600100: a5000000 01cde000 00000000 000004e0
+ * 1A 000: 9200000008600110: 00000650 00000000 00110b15 00000000
+ * 1A 000: 9200000008600120: 006d0005 77bbca0a a5000000 01ce0000
+ * 1A 000: 9200000008600130: 80000500 00000500 00002538 05690008
+ * 1A 000: 9200000008600140: 00000000 00000000 000003e1 0000786d
+ *
+ * To do:
+ *
+ *  - ioc3_close() should attempt to shutdown the adapter somewhat more
+ *    gracefully. 
+ *  - Free rings and buffers when closing or before re-initializing rings.
+ *  - Handle allocation failures in ioc3_alloc_skb() more gracefully.
+ *  - Handle allocation failures in ioc3_init_rings().
+ *  - Maybe implement private_ioctl().
+ *  - Use prefetching for large packets.  What is a good lower limit for
+ *    prefetching?
+ *  - We're probably allocating a bit too much memory.
+ *  - Workarounds for various PHYs.
+ *  - Proper autonegotiation.
+ *  - What exactly is net_device_stats.tx_dropped supposed to count?
+ *  - Use hardware checksums.
+ *  - Convert to using the PCI infrastructure / IOC3 meta driver.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/klconfig.h>
+#include <asm/ioc3.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/pci/bridge.h>
+
+/* 32 RX buffers.  This is tunable in the range of 16 <= x < 512.  */
+#define RX_BUFFS 32
+
+static void ioc3_set_multicast_list(struct net_device *dev);
+static int ioc3_open(struct net_device *dev);
+static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static void ioc3_timeout(struct net_device *dev);
+static int ioc3_close(struct net_device *dev);
+static inline unsigned int ioc3_hash(const unsigned char *addr);
+
+static const char ioc3_str[] = "IOC3 Ethernet";
+
+/* Private per NIC data of the driver.  */
+struct ioc3_private {
+	struct ioc3 *regs;
+	int phy;
+	unsigned long rxr;		/* pointer to receiver ring */
+	struct ioc3_etxd *txr;
+	struct sk_buff *rx_skbs[512];
+	struct sk_buff *tx_skbs[128];
+	struct net_device_stats stats;
+	int rx_ci;			/* RX consumer index */
+	int rx_pi;			/* RX producer index */
+	int tx_ci;			/* TX consumer index */
+	int tx_pi;			/* TX producer index */
+};
+
+/* We use this to acquire receive skb's that we can DMA directly into. */
+#define ALIGNED_RX_SKB_ADDR(addr) \
+	((((unsigned long)(addr) + (128 - 1)) & ~(128 - 1)) - (unsigned long)(addr))
+
+#define ioc3_alloc_skb(__length, __gfp_flags) \
+({	struct sk_buff *__skb; \
+	__skb = alloc_skb((__length) + 128, (__gfp_flags)); \
+	if (__skb) { \
+		int __offset = ALIGNED_RX_SKB_ADDR(__skb->data); \
+		if(__offset) \
+			skb_reserve(__skb, __offset); \
+	} \
+	__skb; \
+})
+
+/* BEWARE: The IOC3 documentation documents the size of rx buffers as
+   1644 while it's actually 1664.  This one was nasty to track down ...  */
+#define RX_OFFSET		10
+#define RX_BUF_ALLOC_SIZE	(1664 + RX_OFFSET + 128)
+
+/* DMA barrier to separate cached and uncached accesses.  */
+#define BARRIER()							\
+	__asm__("sync" ::: "memory")
+
+/* This El Cheapo implementatin of TX_BUFFS_AVAIL may leave on entry unused.
+   Since the TX ring has 128 entries which is fairly large we don't care and
+   use this, more efficient implementation.  */
+#define TX_BUFFS_AVAIL(ip)						\
+({									\
+	struct ioc3_private *_ip = (ip);				\
+	((512 + _ip->tx_ci + 1) - _ip->tx_pi) & 511;			\
+})
+//#undef TX_BUFFS_AVAIL
+//#define TX_BUFFS_AVAIL(ip) (1)
+
+
+#define IOC3_SIZE 0x100000
+
+#define ioc3_r(reg)							\
+({									\
+	u32 __res;							\
+	__res = ioc3->reg;						\
+	__res;								\
+})
+
+#define ioc3_w(reg,val)							\
+do {									\
+	(ioc3->reg = (val));						\
+} while(0)
+
+static inline u32
+mcr_pack(u32 pulse, u32 sample)
+{
+	return (pulse << 10) | (sample << 2);
+}
+
+static int
+nic_wait(struct ioc3 *ioc3)
+{
+	u32 mcr;
+
+        do {
+                mcr = ioc3_r(mcr);
+        } while (!(mcr & 2));
+
+        return mcr & 1;
+}
+
+static int
+nic_reset(struct ioc3 *ioc3)
+{
+        int presence;
+
+	ioc3_w(mcr, mcr_pack(500, 65));
+	presence = nic_wait(ioc3);
+
+	ioc3_w(mcr, mcr_pack(0, 500));
+	nic_wait(ioc3);
+
+        return presence;
+}
+
+/*
+ * Read a byte from an iButton device
+ */
+static u32
+nic_read_byte(struct ioc3 *ioc3)
+{
+	u32 result = 0;
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		ioc3_w(mcr, mcr_pack(6, 13));
+		result = (result >> 1) | (nic_wait(ioc3) << 7);
+
+		ioc3_w(mcr, mcr_pack(0, 100));
+		nic_wait(ioc3);
+	}
+
+	return result;
+}
+
+/*
+ * Write a byte to an iButton device
+ */
+static void
+nic_write_byte(struct ioc3 *ioc3, int byte)
+{
+	int i, bit;
+
+	for (i = 8; i; i--) {
+		bit = byte & 1;
+		byte >>= 1;
+
+		if (bit)
+			ioc3_w(mcr, mcr_pack(6, 110));
+		else
+			ioc3_w(mcr, mcr_pack(80, 30));
+		nic_wait(ioc3);
+	}
+}
+
+static void nic_show_regnr(struct ioc3 *ioc3)
+{
+	const char *type;
+	u8 regnr[8];
+	int i;
+
+	nic_write_byte(ioc3, 0x33);
+	for (i = 0; i < 8; i++)
+		regnr[i] = nic_read_byte(ioc3);
+
+	switch(regnr[0]) {
+	case 0x01:	type = "DS1990A"; break;
+	case 0x91:	type = "DS1981U"; break;
+	default:	type = "unknown"; break;
+	}
+
+	printk("Found %s NIC, registration number "
+	       "%02x:%02x:%02x:%02x:%02x:%02x, CRC %02x.\n", type,
+	       regnr[1], regnr[2], regnr[3], regnr[4], regnr[5], regnr[6],
+	       regnr[7]);
+}
+
+/*
+ * Read the NIC (Number-In-a-Can) device.
+ */
+static void ioc3_get_eaddr(struct net_device *dev, struct ioc3 *ioc3)
+{
+	u8 nic[14];
+	int i;
+
+	ioc3_w(gpcr_s, (1 << 21));
+
+	nic_reset(ioc3);
+	nic_show_regnr(ioc3);
+
+	nic_reset(ioc3);
+	nic_write_byte(ioc3, 0xcc);
+	nic_write_byte(ioc3, 0xf0);
+	nic_write_byte(ioc3, 0x00);
+	nic_write_byte(ioc3, 0x00);
+
+	for (i = 13; i >= 0; i--)
+		nic[i] = nic_read_byte(ioc3);
+
+	printk("Ethernet address is ");
+	for (i = 2; i < 8; i++) {
+		dev->dev_addr[i - 2] = nic[i];
+		printk("%02x", nic[i]);
+		if (i < 7)
+			printk(":");
+	}
+	printk(".\n");
+}
+
+static u16 mii_read(struct ioc3 *ioc3, int phy, int reg)
+{
+	while (ioc3->micr & MICR_BUSY);
+	ioc3->micr = (phy << MICR_PHYADDR_SHIFT) | reg | MICR_READTRIG;
+	while (ioc3->micr & MICR_BUSY);
+
+	return ioc3->midr & MIDR_DATA_MASK;
+}
+
+static void mii_write(struct ioc3 *ioc3, int phy, int reg, u16 data)
+{
+	while (ioc3->micr & MICR_BUSY);
+	ioc3->midr = data;
+	ioc3->micr = (phy << MICR_PHYADDR_SHIFT) | reg;
+	while (ioc3->micr & MICR_BUSY);
+}
+
+static struct net_device_stats *ioc3_get_stats(struct net_device *dev)
+{
+	struct ioc3_private *ip = (struct ioc3_private *) dev->priv;
+	struct ioc3 *ioc3 = ip->regs;
+
+	ip->stats.collisions += (ioc3->etcdc & ETCDC_COLLCNT_MASK);
+	return &ip->stats;
+}
+
+static inline void
+ioc3_rx(struct net_device *dev, struct ioc3_private *ip, struct ioc3 *ioc3)
+{
+	struct sk_buff *skb, *new_skb;
+	int rx_entry, n_entry, len;
+	struct ioc3_erxbuf *rxb;
+	unsigned long *rxr;
+	u32 w0, err;
+
+	rxr = (unsigned long *) ip->rxr;		/* Ring base */
+	rx_entry = ip->rx_ci;				/* RX consume index */
+	n_entry = ip->rx_pi;
+
+	skb = ip->rx_skbs[rx_entry];
+	rxb = (struct ioc3_erxbuf *) (skb->data - RX_OFFSET);
+	w0 = rxb->w0;
+
+	while (w0 & ERXBUF_V) {
+		ioc3->eisr = EISR_RXTIMERINT;		/* Ack */
+		ioc3->eisr;				/* Flush */
+
+		err = rxb->err;				/* It's valid ...  */
+		if (err & ERXBUF_GOODPKT) {
+			len = (w0 >> ERXBUF_BYTECNT_SHIFT) & 0x7ff;
+			skb_trim(skb, len);
+			skb->protocol = eth_type_trans(skb, dev);
+			netif_rx(skb);
+
+			new_skb = ioc3_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
+			if (!new_skb) {
+				/* Ouch, drop packet and just recycle packet
+				   to keep the ring filled.  */
+				ip->stats.rx_dropped++;
+				new_skb = skb;
+				goto next;
+			}
+
+			new_skb->dev = dev;
+
+			/* Because we reserve afterwards. */
+			skb_put(new_skb, (1664 + RX_OFFSET));
+			rxb = (struct ioc3_erxbuf *) new_skb->data;
+			skb_reserve(new_skb, RX_OFFSET);
+
+			ip->stats.rx_packets++;		/* Statistics */
+			ip->stats.rx_bytes += len;
+
+			goto next;
+		}
+		if (err & (ERXBUF_CRCERR | ERXBUF_FRAMERR | ERXBUF_CODERR |
+		           ERXBUF_INVPREAMB | ERXBUF_BADPKT | ERXBUF_CARRIER)) {
+			/* We don't send the skbuf to the network layer, so
+			   just recycle it.  */
+			new_skb = skb;
+
+			if (err & ERXBUF_CRCERR)	/* Statistics */
+				ip->stats.rx_crc_errors++;
+			if (err & ERXBUF_FRAMERR)
+				ip->stats.rx_frame_errors++;
+			ip->stats.rx_errors++;
+		}
+
+next:
+		ip->rx_skbs[n_entry] = new_skb;
+		rxr[n_entry] = (0xa5UL << 56) |
+		                ((unsigned long) rxb & TO_PHYS_MASK);
+		rxb->w0 = 0;				/* Clear valid flag */
+		n_entry = (n_entry + 1) & 511;		/* Update erpir */
+		ioc3->erpir = (n_entry << 3) | ERPIR_ARM;
+
+		/* Now go on to the next ring entry.  */
+		rx_entry = (rx_entry + 1) & 511;
+		skb = ip->rx_skbs[rx_entry];
+		rxb = (struct ioc3_erxbuf *) (skb->data - RX_OFFSET);
+		w0 = rxb->w0;
+	}
+	ip->rx_pi = n_entry;
+	ip->rx_ci = rx_entry;
+
+	return;
+}
+
+static inline void
+ioc3_tx(struct ioc3_private *ip, struct ioc3 *ioc3)
+{
+	int tx_entry, o_entry;
+	struct sk_buff *skb;
+	u32 etcir;
+
+	etcir = ioc3->etcir;
+	tx_entry = (etcir >> 7) & 127;
+	o_entry = ip->tx_ci;
+
+	while (o_entry != tx_entry) {
+		ioc3->eisr = EISR_TXEXPLICIT;		/* Ack */
+		ioc3->eisr;				/* Flush */
+
+		skb = ip->tx_skbs[o_entry];
+		ip->stats.tx_packets++;
+		ip->stats.tx_bytes += skb->len;
+		dev_kfree_skb(skb);
+		ip->tx_skbs[o_entry] = NULL;
+
+		o_entry = (o_entry + 1) & 127;		/* Next */
+
+		etcir = ioc3->etcir;			/* More pkts sent?  */
+		tx_entry = (etcir >> 7) & 127;
+	}
+	ip->tx_ci = o_entry;
+}
+
+/*
+ * Deal with fatal IOC3 errors.  For now let's panic.  This condition might
+ * be caused by a hard or software problems, so we should try to recover
+ * more gracefully if this ever happens.
+ */
+static void
+ioc3_error(struct net_device *dev, struct ioc3_private *ip,
+           struct ioc3 *ioc3, u32 eisr)
+{
+	if (eisr & (EISR_RXMEMERR | EISR_TXMEMERR)) {
+		if (eisr & EISR_RXMEMERR) {
+			panic("%s: RX PCI error.\n", dev->name);
+		}
+		if (eisr & EISR_TXMEMERR) {
+			panic("%s: TX PCI error.\n", dev->name);
+		}
+	}
+}
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+   after the Tx thread.  */
+static void ioc3_interrupt(int irq, void *_dev, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *)_dev;
+	struct ioc3_private *ip = dev->priv;
+	struct ioc3 *ioc3 = ip->regs;
+	u32 eisr, eier;
+
+	ip = dev->priv;
+
+	eier = ioc3->eier;				/* Disable eth ints */
+	ioc3->eier = 0;
+	eisr = ioc3->eisr;
+	__sti();
+
+	if (eisr & EISR_RXTIMERINT) {
+		ioc3_rx(dev, ip, ioc3);
+	}
+	if (eisr & EISR_TXEXPLICIT) {
+		ioc3_tx(ip, ioc3);
+	}
+	if (eisr & (EISR_RXMEMERR | EISR_TXMEMERR)) {
+		ioc3_error(dev, ip, ioc3, eisr);
+	}
+
+	if ((TX_BUFFS_AVAIL(ip) >= 0) && netif_queue_stopped(dev)) {
+		netif_wake_queue(dev);
+	}
+
+	__cli();
+	ioc3->eier = eier;
+
+	return;
+}
+
+int
+ioc3_eth_init(struct net_device *dev, struct ioc3_private *p, struct ioc3 *ioc3)
+{
+	u16 word, mii0, mii_status, mii2, mii3, mii4;
+	u32 vendor, model, rev;
+	int i, phy;
+
+	ioc3->emcr = EMCR_RST;			/* Reset		*/
+	ioc3->emcr;				/* flush WB		*/
+	udelay(4);				/* Give it time ...	*/
+	ioc3->emcr = 0;
+
+	phy = -1;
+	for (i = 0; i < 32; i++) {
+		word = mii_read(ioc3, i, 2);
+		if ((word != 0xffff) & (word != 0x0000)) {
+			phy = i;
+			break;			/* Found a PHY		*/
+		}
+	}
+	if (phy == -1) {
+		printk("Didn't find a PHY, goodbye.\n");
+		return -ENODEV;
+	}
+	p->phy = phy;
+
+	mii0 = mii_read(ioc3, phy, 0);
+	mii_status = mii_read(ioc3, phy, 1);
+	mii2 = mii_read(ioc3, phy, 2);
+	mii3 = mii_read(ioc3, phy, 3);
+	mii4 = mii_read(ioc3, phy, 4);
+	vendor = (mii2 << 12) | (mii3 >> 4);
+	model  = (mii3 >> 4) & 0x3f;
+	rev    = mii3 & 0xf;
+	printk("Ok, using PHY %d, vendor 0x%x, model %d, rev %d.\n",
+	       phy, vendor, model, rev);
+	printk(KERN_INFO "%s:  MII transceiver found at MDIO address "
+	       "%d, config %4.4x status %4.4x.\n",
+	       dev->name, phy, mii0, mii_status);
+
+	/* Autonegotiate 100mbit and fullduplex. */
+	mii_write(ioc3, phy, 0, mii0 | 0x3100);
+	mdelay(1000);
+	mii_status = mii_read(ioc3, phy, 1);
+
+	return 0;	/* XXX */
+}
+
+/* To do: For reinit of the ring we have to cleanup old skbs first ... */
+static void
+ioc3_init_rings(struct net_device *dev, struct ioc3_private *p,
+	        struct ioc3 *ioc3)
+{
+	struct ioc3_erxbuf *rxb;
+	unsigned long *rxr;
+	unsigned long ring;
+	int i;
+
+	/* Allocate and initialize rx ring.  4kb = 512 entries  */
+	p->rxr = get_free_page(GFP_KERNEL);
+	rxr = (unsigned long *) p->rxr;
+
+	/* Now the rx buffers.  The RX ring may be larger but we only
+	   allocate 16 buffers for now.  Need to tune this for performance
+	   and memory later.  */
+	for (i = 0; i < RX_BUFFS; i++) {
+		struct sk_buff *skb;
+
+		skb = ioc3_alloc_skb(RX_BUF_ALLOC_SIZE, 0);
+		if (!skb) {
+			show_free_areas();
+			continue;
+		}
+
+		p->rx_skbs[i] = skb;
+		skb->dev = dev;
+
+		/* Because we reserve afterwards. */
+		skb_put(skb, (1664 + RX_OFFSET));
+		rxb = (struct ioc3_erxbuf *) skb->data;
+		rxb->w0 = 0;				/* Clear valid bit */
+		rxr[i] = (0xa5UL << 56) | ((unsigned long) rxb & TO_PHYS_MASK);
+		skb_reserve(skb, RX_OFFSET);
+	}
+
+	/* Now the rx ring base, consume & produce registers.  */
+	ring = (0xa5UL << 56) | (p->rxr & TO_PHYS_MASK);
+	ioc3->erbr_h = ring >> 32;
+	ioc3->erbr_l = ring & 0xffffffff;
+	p->rx_ci = 0;
+	ioc3->ercir  = (p->rx_ci << 3);
+	p->rx_pi = RX_BUFFS;
+	ioc3->erpir  = (p->rx_pi << 3) | ERPIR_ARM;
+
+	/* Allocate and initialize tx rings.  16kb = 128 bufs.  */
+	p->txr = (struct ioc3_etxd *)__get_free_pages(GFP_KERNEL, 2);
+	ring = (0xa5UL << 56) | ((unsigned long)p->txr & TO_PHYS_MASK);
+
+	/* Now the tx ring base, consume & produce registers.  */
+	ioc3->etbr_h = ring >> 32;
+	ioc3->etbr_l = ring & 0xffffffff;
+	p->tx_pi = 0;
+	ioc3->etpir  = (p->tx_pi << 7);
+	p->tx_ci = 0;
+	ioc3->etcir  = (p->tx_pi << 7);
+	ioc3->etcir;					/* Flush */
+}
+
+void
+ioc3_ssram_disc(struct ioc3_private *ip)
+{
+	struct ioc3 *ioc3 = ip->regs;
+	volatile u32 *ssram0 = &ioc3->ssram[0x0000];
+	volatile u32 *ssram1 = &ioc3->ssram[0x4000];
+	unsigned int pattern = 0x5555;
+
+	/* Assume the larger size SSRAM and enable parity checking */
+	ioc3->emcr |= (EMCR_BUFSIZ | EMCR_RAMPAR);
+
+	*ssram0 = pattern;
+	*ssram1 = ~pattern & IOC3_SSRAM_DM;
+
+	if ((*ssram0 & IOC3_SSRAM_DM) != pattern ||
+	    (*ssram1 & IOC3_SSRAM_DM) != (~pattern & IOC3_SSRAM_DM)) {
+		/* set ssram size to 64 KB */
+		ioc3->emcr &= ~EMCR_BUFSIZ;
+		printk("IOC3 SSRAM has 64 kbyte.\n");
+	} else {
+		//ei->ei_ssram_bits = EMCR_BUFSIZ | EMCR_RAMPAR;
+		printk("IOC3 SSRAM has 64 kbyte.\n");
+	}
+}
+
+static void ioc3_probe1(struct net_device *dev, struct ioc3 *ioc3)
+{
+	struct ioc3_private *p;
+
+	dev = init_etherdev(dev, 0);
+	p = (struct ioc3_private *) kmalloc(sizeof(*p), GFP_KERNEL);
+	memset(p, 0, sizeof(*p));
+	dev->priv = p;
+	dev->irq = IOC3_ETH_INT;
+
+	p->regs = ioc3;
+
+	ioc3_eth_init(dev, p, ioc3);
+	ioc3_ssram_disc(p);
+        ioc3_get_eaddr(dev, ioc3);
+	ioc3_init_rings(dev, p, ioc3);
+
+	/* Misc registers  */
+	ioc3->erbar = 0;
+	ioc3->etcsr = (17<<ETCSR_IPGR2_SHIFT) | (11<<ETCSR_IPGR1_SHIFT) | 21;
+	ioc3->etcdc;				/* Clear on read */
+	ioc3->ercsr = 15;			/* RX low watermark  */
+	ioc3->ertr = 0;				/* Interrupt immediately */
+	ioc3->emar_h = (dev->dev_addr[5] << 8) | dev->dev_addr[4];
+	ioc3->emar_l = (dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) |
+	               (dev->dev_addr[1] <<  8) | dev->dev_addr[0];
+	ioc3->ehar_h = ioc3->ehar_l = 0;
+	ioc3->ersr = 42;	/* XXX should be random */
+	//ioc3->erpir = ERPIR_ARM;
+
+	/* The IOC3-specific entries in the device structure. */
+	dev->open		= &ioc3_open;
+	dev->hard_start_xmit	= &ioc3_start_xmit;
+	dev->tx_timeout		= ioc3_timeout;
+	dev->watchdog_timeo	= (400 * HZ) / 1000;
+	dev->stop		= &ioc3_close;
+	dev->get_stats		= &ioc3_get_stats;
+	dev->set_multicast_list	= &ioc3_set_multicast_list;
+}
+
+int
+ioc3_probe(struct net_device *dev)
+{
+	static int initialized;
+	struct ioc3 *ioc3;
+	nasid_t nid;
+
+	if (initialized)		/* Only initialize once ...  */
+		return 0;
+	initialized++;
+
+	nid = get_nasid();
+	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
+	ioc3_probe1(dev, ioc3);
+
+	return 0;
+}
+
+static int
+ioc3_open(struct net_device *dev)
+{
+	struct ioc3_private *ip = dev->priv;
+	struct ioc3 *ioc3 = ip->regs;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	if (request_irq(dev->irq, ioc3_interrupt, 0, ioc3_str, dev)) {
+		printk("%s: Can't get irq %d\n", dev->name, dev->irq);
+		restore_flags(flags);
+
+		return -EAGAIN;
+	}
+
+	//ioc3_eth_init(dev, p, ioc3);
+
+	ioc3->emcr = ((RX_OFFSET / 2) << EMCR_RXOFF_SHIFT) | EMCR_TXDMAEN |
+	             EMCR_TXEN | EMCR_RXDMAEN | EMCR_RXEN;
+	ioc3->eier = EISR_RXTIMERINT | EISR_TXEXPLICIT | /* Interrupts ...  */
+	             EISR_RXMEMERR | EISR_TXMEMERR;
+
+	netif_wake_queue(dev);
+	restore_flags(flags);
+
+	MOD_INC_USE_COUNT;
+
+        return 0;
+}
+
+static int
+ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	unsigned long data;
+	struct ioc3_private *ip = dev->priv;
+	struct ioc3 *ioc3 = ip->regs;
+	unsigned int len;
+	struct ioc3_etxd *desc;
+	int produce;
+
+	if (!TX_BUFFS_AVAIL(ip)) {
+		return 1;
+	}
+
+	data = (unsigned long) skb->data;
+	len = skb->len;
+
+	produce = ip->tx_pi;
+	desc = &ip->txr[produce];
+
+	if (len <= 104) {
+		/* Short packet, let's copy it directly into the ring.  */
+		memcpy(desc->data, skb->data, skb->len);
+		if (len < ETH_ZLEN) {
+			/* Very short packet, pad with zeros at the end. */
+			memset(desc->data + len, 0, ETH_ZLEN - len);
+			len = ETH_ZLEN;
+		}
+		desc->cmd    = len | ETXD_INTWHENDONE | ETXD_D0V;
+		desc->bufcnt = len;
+	} if ((data ^ (data + len)) & 0x4000) {
+		unsigned long b2, s1, s2;
+
+		b2 = (data | 0x3fffUL) + 1UL;
+		s1 = b2 - data;
+		s2 = data + len - b2;
+
+		desc->cmd    = len | ETXD_INTWHENDONE | ETXD_B1V | ETXD_B2V;
+		desc->bufcnt = (s1 << ETXD_B1CNT_SHIFT) |
+		               (s2 << ETXD_B2CNT_SHIFT);
+		desc->p1     = (0xa5UL << 56) | (data & TO_PHYS_MASK);
+		desc->p2     = (0xa5UL << 56) | (data & TO_PHYS_MASK);
+	} else {
+		/* Normal sized packet that doesn't cross a page boundary. */
+		desc->cmd    = len | ETXD_INTWHENDONE | ETXD_B1V;
+		desc->bufcnt = len << ETXD_B1CNT_SHIFT;
+		desc->p1     = (0xa5UL << 56) | (data & TO_PHYS_MASK);
+	}
+
+	BARRIER();
+
+	dev->trans_start = jiffies;
+	ip->tx_skbs[produce] = skb;			/* Remember skb */
+	produce = (produce + 1) & 127;
+	ip->tx_pi = produce;
+	ioc3->etpir = produce << 7;			/* Fire ... */
+
+	if (TX_BUFFS_AVAIL(ip))
+		netif_wake_queue(dev);
+
+	return 0;
+}
+
+static void ioc3_timeout(struct net_device *dev)
+{
+	printk("%s: transmit timed out, resetting\n", dev->name);
+	/* XXX should reset device here.  */
+
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+}
+
+static int
+ioc3_close(struct net_device *dev)
+{
+	struct ioc3_private *ip = dev->priv;
+	struct ioc3 *ioc3 = ip->regs;
+
+	netif_stop_queue(dev);
+
+	ioc3->emcr = 0;				/* Shutup */
+	ioc3->eier = 0;				/* Disable interrupts */
+	ioc3->eier;				/* Flush */
+	free_irq(dev->irq, dev);
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+#if 0
+/* Initialize the NIC  */
+static int
+ioc3_init(struct ioc3_private *p, struct pci_dev *dev)
+{
+#if 0
+	unsigned long base;
+	struct ioc3 *ioc3;
+
+	pci_set_master(dev);
+	base = dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK;
+	printk("Base address at %08lx\n", base);
+
+	p->regs = ioc3 = ioremap (base, IOC3_SIZE);
+	printk("Remapped base address to %08lx\n", (unsigned long) regs);
+
+	read_nic(ioc3);
+
+	return 0;
+#endif
+	panic(__FUNCTION__" has been called.\n");
+}
+#endif
+
+/*
+ * Given a multicast ethernet address, this routine calculates the
+ * address's bit index in the logical address filter mask
+ */
+#define CRC_MASK        0xEDB88320
+
+static inline unsigned int
+ioc3_hash(const unsigned char *addr)
+{
+	unsigned int temp = 0;
+	unsigned char byte;
+	unsigned int crc;
+	int bits, len;
+
+	len = ETH_ALEN;
+	for (crc = ~0; --len >= 0; addr++) {
+		byte = *addr;
+		for (bits = 8; --bits >= 0; ) {
+			if ((byte ^ crc) & 1)
+				crc = (crc >> 1) ^ CRC_MASK;
+			else
+				crc >>= 1;
+			byte >>= 1;
+		}
+	}
+
+	crc &= 0x3f;    /* bit reverse lowest 6 bits for hash index */
+	for (bits = 6; --bits >= 0; ) {
+		temp <<= 1;
+		temp |= (crc & 0x1);
+		crc >>= 1;
+	}
+
+	return temp;
+}
+
+static void ioc3_set_multicast_list(struct net_device *dev)
+{
+	struct dev_mc_list *dmi = dev->mc_list;
+	char *addr = dmi->dmi_addr;
+	struct ioc3_private *p;
+	struct ioc3 *ioc3;
+	u64 ehar = 0;
+	int i;
+
+	p = dev->priv;
+	ioc3 = p->regs;
+
+	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous.  */
+		/* Unconditionally log net taps.  */
+		printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name);
+		ioc3->emcr |= EMCR_PROMISC;
+		ioc3->emcr;
+	} else {
+		ioc3->emcr &= ~EMCR_PROMISC;		/* Clear promiscuous. */
+		ioc3->emcr;
+
+		if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
+			/* Too many for hashing to make sense or we want all
+			   multicast packets anyway,  so skip computing all the
+			   hashes and just accept all packets.  */
+			ioc3->ehar_h = 0xffffffff;
+			ioc3->ehar_l = 0xffffffff;
+		} else {
+			for (i = 0; i < dev->mc_count; i++) {
+				dmi = dmi->next;
+
+				if (!(*addr & 1))
+					continue;
+
+				ehar |= (1 << ioc3_hash(addr));
+			}
+			ioc3->ehar_h = ehar >> 32;
+			ioc3->ehar_l = ehar & 0xffffffff;
+		}
+	}
+}
+
+#ifdef MODULE
+MODULE_AUTHOR("Ralf Baechle <ralf@oss.sgi.com>");
+MODULE_DESCRIPTION("SGI IOC3 Ethernet driver");
+
+int
+init_module(void)
+{
+	struct pci_dev *dev = NULL;
+
+	while ((dev = pci_find_device(PCI_VENDOR_ID_SGI, 0x0003, dev))) {
+		ioc3_init(&p, dev);
+	}
+
+	return -EBUSY;
+}
+
+void
+cleanup_module(void)
+{
+	printk("cleanup_module called\n");
+}
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/net/irda/nsc-ircc.c linux/drivers/net/irda/nsc-ircc.c
--- v2.3.47/linux/drivers/net/irda/nsc-ircc.c	Sat Feb 12 11:22:10 2000
+++ linux/drivers/net/irda/nsc-ircc.c	Tue Feb 22 22:28:59 2000
@@ -6,7 +6,7 @@
  * Status:        Stable.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Nov  7 21:43:15 1998
- * Modified at:   Fri Jan 28 12:10:10 2000
+ * Modified at:   Fri Feb 18 01:48:51 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>
@@ -42,6 +42,7 @@
  ********************************************************************/
 
 #include <linux/module.h>
+
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/skbuff.h>
@@ -1431,8 +1432,10 @@
 		/* We must empty the status FIFO no matter what */
 		len = inb(iobase+RFLFL) | ((inb(iobase+RFLFH) & 0x1f) << 8);
 
-		if (st_fifo->tail >= MAX_RX_WINDOW)
+		if (st_fifo->tail >= MAX_RX_WINDOW) {
+			IRDA_DEBUG(0, __FUNCTION__ "(), window is full!\n");
 			continue;
+		}
 			
 		st_fifo->entries[st_fifo->tail].status = status;
 		st_fifo->entries[st_fifo->tail].len = len;
@@ -1492,7 +1495,18 @@
 					st_fifo->pending_bytes += len;
 					st_fifo->entries[st_fifo->head].status = status;
 					st_fifo->entries[st_fifo->head].len = len;
-				
+					/*  
+					 * DMA not finished yet, so try again 
+					 * later, set timer value, resolution 
+					 * 125 us 
+					 */
+					switch_bank(iobase, BANK4);
+					outb(0x02, iobase+TMRL); /* x 125 us */
+					outb(0x00, iobase+TMRH);
+
+					/* Start timer */
+					outb(IRCR1_TMR_EN, iobase+IRCR1);
+
 					/* Restore bank register */
 					outb(bank, iobase+BSR);
 					
@@ -1597,7 +1611,7 @@
 		else { 
 
 			self->stats.tx_packets++;
-			netif_wakeup_queue(self->netdev);
+			netif_wake_queue(self->netdev);
 			self->ier = IER_TXEMP_IE;
 		}
 			
@@ -1648,21 +1662,12 @@
 	
 	/* Status FIFO event*/
 	if (eir & EIR_SFIF_EV) {
+		/* Check if DMA has finished */
 		if (nsc_ircc_dma_receive_complete(self, iobase)) {
 			/* Wait for next status FIFO interrupt */
 			self->ier = IER_SFIF_IE;
 		} else {
-			/* 
-			 * DMA not finished yet, so try again later, set 
-			 * timer value, resolution 125 us 
-			 */
-			switch_bank(iobase, BANK4);
-			outb(0x02, iobase+TMRL); /* 2 * 125 us */
-			outb(0x00, iobase+TMRH);
-
-			/* Start timer */
-			outb(IRCR1_TMR_EN, iobase+IRCR1);
-			self->ier = IER_TMR_IE | IER_SFIF_IE;
+			self->ier = IER_SFIF_IE | IER_TMR_IE;
 		}
 	} else if (eir & EIR_TMR_EV) { /* Timer finished */
 		/* Disable timer */
@@ -1677,15 +1682,17 @@
 		if (self->io.direction == IO_XMIT) {
 			nsc_ircc_dma_xmit(self, iobase);
 
-			/*  Interrupt on DMA */
+			/* Interrupt on DMA */
 			self->ier = IER_DMA_IE;
 		} else {
-			/* Check if DMA has now finished */
-			nsc_ircc_dma_receive_complete(self, iobase);
-
-			self->ier = IER_SFIF_IE;
+			/* Check (again) if DMA has finished */
+			if (nsc_ircc_dma_receive_complete(self, iobase)) {
+				self->ier = IER_SFIF_IE;
+			} else {
+				self->ier = IER_SFIF_IE | IER_TMR_IE;
+			}
 		}
-	} else if (eir & EIR_DMA_EV) { 
+	} else if (eir & EIR_DMA_EV) {
 		/* Finished with all transmissions? */
 		if (nsc_ircc_dma_xmit_complete(self)) {		
 			/* Check if there are more frames to be transmitted */
diff -u --recursive --new-file v2.3.47/linux/drivers/net/irda/smc-ircc.c linux/drivers/net/irda/smc-ircc.c
--- v2.3.47/linux/drivers/net/irda/smc-ircc.c	Thu Feb 10 17:11:10 2000
+++ linux/drivers/net/irda/smc-ircc.c	Tue Feb 22 22:28:59 2000
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Thomas Davis (tadavis@jps.net)
  * Created at:    
- * Modified at:   Fri Jan 21 09:41:08 2000
+ * Modified at:   Tue Feb 22 10:05:06 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999-2000 Dag Brattli
@@ -567,7 +567,6 @@
 			   "(), using irport to change speed to %d\n", speed);
 		irport_change_speed(self->irport, speed);
 	}	
-	dev->tbusy = 0;
 
 	register_bank(iobase, 1);
 	outb(((inb(iobase+IRCC_SCE_CFGA) & 0x87) | ir_mode), 
@@ -617,9 +616,7 @@
 	if ((speed = irda_get_speed(skb)) != self->io.speed)
 		self->new_speed = speed;
 	
-	/* Lock transmit buffer */
-	if (irda_lock((void *) &dev->tbusy) == FALSE)
-		return -EBUSY;
+	netif_stop_queue(dev);
 
 	memcpy(self->tx_buff.head, skb->data, skb->len);
 
@@ -741,11 +738,7 @@
 		self->new_speed = 0;
 	}
 
-	/* Unlock tx_buff and request another frame */
-	self->netdev->tbusy = 0; /* Unlock */
-	
-	/* Tell the network layer, that we can accept more frames */
-	mark_bh(NET_BH);
+	netif_wake_queue(self->netdev);
 }
 
 /*
@@ -875,7 +868,6 @@
 	iobase = self->io.fir_base;
 
 	spin_lock(&self->lock);	
-	dev->interrupt = 1;
 
 	register_bank(iobase, 0);
 	iir = inb(iobase+IRCC_IIR);
@@ -898,7 +890,6 @@
 	register_bank(iobase, 0);
 	outb(IRCC_IER_ACTIVE_FRAME|IRCC_IER_EOM, iobase+IRCC_IER);
 
-	dev->interrupt = 0;
 	spin_unlock(&self->lock);
 }
 
diff -u --recursive --new-file v2.3.47/linux/drivers/net/pcmcia/3c589_cs.c linux/drivers/net/pcmcia/3c589_cs.c
--- v2.3.47/linux/drivers/net/pcmcia/3c589_cs.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/net/pcmcia/3c589_cs.c	Sun Feb 20 21:59:27 2000
@@ -788,8 +788,7 @@
     
     while ((status = inw(ioaddr + EL3_STATUS)) &
 	(IntLatch | RxComplete | StatsFull)) {
-	if (!netif_device_present(dev)) ||
-	    ((status & 0xe000) != 0x2000)) {
+	if (!netif_device_present(dev) || ((status & 0xe000) != 0x2000)) {
 	    DEBUG(1, "%s: interrupt from dead card\n", dev->name);
 	    break;
 	}
diff -u --recursive --new-file v2.3.47/linux/drivers/net/sgiseeq.c linux/drivers/net/sgiseeq.c
--- v2.3.47/linux/drivers/net/sgiseeq.c	Wed Aug 18 11:36:42 1999
+++ linux/drivers/net/sgiseeq.c	Thu Feb 24 22:49:19 2000
@@ -31,7 +31,8 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
-#include <asm/sgihpc.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
 #include <asm/sgialib.h>
 
 #include "sgiseeq.h"
@@ -70,12 +71,12 @@
 
 struct sgiseeq_rx_desc {
 	struct hpc_dma_desc rdma;
-	unsigned long buf_vaddr;
+	signed int buf_vaddr;
 };
 
 struct sgiseeq_tx_desc {
 	struct hpc_dma_desc tdma;
-	unsigned long buf_vaddr;
+	signed int buf_vaddr;
 };
 
 /* Warning: This structure is layed out in a certain way because
@@ -86,7 +87,7 @@
 	/* Ptrs to the descriptors in KSEG1 uncached space. */
 	struct sgiseeq_rx_desc *rx_desc;
 	struct sgiseeq_tx_desc *tx_desc;
-	unsigned long _padding[30]; /* Pad out to largest cache line size. */
+	unsigned int _padding[30]; /* Pad out to largest cache line size. */
 
 	struct sgiseeq_rx_desc rxvector[SEEQ_RX_BUFFERS];
 	struct sgiseeq_tx_desc txvector[SEEQ_TX_BUFFERS];
@@ -140,7 +141,7 @@
 	int i;
 
 	sregs->tstat = SEEQ_TCMD_RB0;
-	for(i = 0; i < 6; i++)
+	for (i = 0; i < 6; i++)
 		sregs->rw.eth_addr[i] = dev->dev_addr[i];
 }
 
@@ -154,7 +155,7 @@
 	volatile struct sgiseeq_init_block *ib = &sp->srings;
 	int i;
 
-	dev->tbusy = 1;
+	netif_stop_queue(dev);
 	sp->rx_new = sp->tx_new = 0;
 	sp->rx_old = sp->tx_old = 0;
 
@@ -180,8 +181,8 @@
 	}
 
 	/* And now the rx ring. */
-	for(i = 0; i < SEEQ_RX_BUFFERS; i++) {
-		if(!ib->rx_desc[i].rdma.pbuf) {
+	for (i = 0; i < SEEQ_RX_BUFFERS; i++) {
+		if (!ib->rx_desc[i].rdma.pbuf) {
 			unsigned long buffer;
 
 			buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
@@ -210,29 +211,29 @@
 		return;
 	once++;
 	printk("RING DUMP:\n");
-	for(i = 0; i < SEEQ_RX_BUFFERS; i++) {
-		printk("RX [%d]: @(%p) [%08lx,%08lx,%08lx] ",
+	for (i = 0; i < SEEQ_RX_BUFFERS; i++) {
+		printk("RX [%d]: @(%p) [%08x,%08x,%08x] ",
 		       i, (&r[i]), r[i].rdma.pbuf, r[i].rdma.cntinfo,
 		       r[i].rdma.pnext);
 		i += 1;
-		printk("-- [%d]: @(%p) [%08lx,%08lx,%08lx]\n",
+		printk("-- [%d]: @(%p) [%08x,%08x,%08x]\n",
 		       i, (&r[i]), r[i].rdma.pbuf, r[i].rdma.cntinfo,
 		       r[i].rdma.pnext);
 	}
-	for(i = 0; i < SEEQ_TX_BUFFERS; i++) {
-		printk("TX [%d]: @(%p) [%08lx,%08lx,%08lx] ",
+	for (i = 0; i < SEEQ_TX_BUFFERS; i++) {
+		printk("TX [%d]: @(%p) [%08x,%08x,%08x] ",
 		       i, (&t[i]), t[i].tdma.pbuf, t[i].tdma.cntinfo,
 		       t[i].tdma.pnext);
 		i += 1;
-		printk("-- [%d]: @(%p) [%08lx,%08lx,%08lx]\n",
+		printk("-- [%d]: @(%p) [%08x,%08x,%08x]\n",
 		       i, (&t[i]), t[i].tdma.pbuf, t[i].tdma.cntinfo,
 		       t[i].tdma.pnext);
 	}
 	printk("INFO: [rx_new = %d rx_old=%d] [tx_new = %d tx_old = %d]\n",
 	       gpriv->rx_new, gpriv->rx_old, gpriv->tx_new, gpriv->tx_old);
-	printk("RREGS: rx_cbptr[%08lx] rx_ndptr[%08lx] rx_ctrl[%08lx]\n",
+	printk("RREGS: rx_cbptr[%08x] rx_ndptr[%08x] rx_ctrl[%08x]\n",
 	       hregs->rx_cbptr, hregs->rx_ndptr, hregs->rx_ctrl);
-	printk("TREGS: tx_cbptr[%08lx] tx_ndptr[%08lx] tx_ctrl[%08lx]\n",
+	printk("TREGS: tx_cbptr[%08x] tx_ndptr[%08x] tx_ctrl[%08x]\n",
 	       hregs->tx_cbptr, hregs->tx_ndptr, hregs->tx_ctrl);
 }
 #endif
@@ -250,7 +251,7 @@
 	seeq_init_ring(dev);
 
 	/* Setup to field the proper interrupt types. */
-	if(sp->is_edlc) {
+	if (sp->is_edlc) {
 		sregs->tstat = (TSTAT_INIT_EDLC);
 		sregs->rw.wregs.control = sp->control;
 		sregs->rw.wregs.frame_gap = 0;
@@ -269,14 +270,14 @@
 static inline void record_rx_errors(struct sgiseeq_private *sp,
 				    unsigned char status)
 {
-	if(status & SEEQ_RSTAT_OVERF ||
-	   status & SEEQ_RSTAT_SFRAME)
+	if (status & SEEQ_RSTAT_OVERF ||
+	    status & SEEQ_RSTAT_SFRAME)
 		sp->stats.rx_over_errors++;
-	if(status & SEEQ_RSTAT_CERROR)
+	if (status & SEEQ_RSTAT_CERROR)
 		sp->stats.rx_crc_errors++;
-	if(status & SEEQ_RSTAT_DERROR)
+	if (status & SEEQ_RSTAT_DERROR)
 		sp->stats.rx_frame_errors++;
-	if(status & SEEQ_RSTAT_REOF)
+	if (status & SEEQ_RSTAT_REOF)
 		sp->stats.rx_errors++;
 }
 
@@ -284,7 +285,7 @@
 				    volatile struct hpc3_ethregs *hregs,
 				    volatile struct sgiseeq_regs *sregs)
 {
-	if(!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) {
+	if (!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) {
 		hregs->rx_ndptr = PHYSADDR(&sp->srings.rx_desc[sp->rx_new]);
 		seeq_go(sp, hregs, sregs);
 	}
@@ -308,14 +309,14 @@
 	/* Service every received packet. */
 	for_each_rx(rd, sp) {
 		len = (PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3);
-		pkt_pointer = (unsigned char *)rd->buf_vaddr;
+		pkt_pointer = (unsigned char *)(long)rd->buf_vaddr;
 		pkt_status = pkt_pointer[len + 2];
 
-		if(pkt_status & SEEQ_RSTAT_FIG) {
+		if (pkt_status & SEEQ_RSTAT_FIG) {
 			/* Packet is OK. */
 			skb = dev_alloc_skb(len + 2);
 
-			if(skb) {
+			if (skb) {
 				skb->dev = dev;
 				skb_reserve(skb, 2);
 				skb_put(skb, len);
@@ -346,7 +347,7 @@
 static inline void tx_maybe_reset_collisions(struct sgiseeq_private *sp,
 					     volatile struct sgiseeq_regs *sregs)
 {
-	if(sp->is_edlc) {
+	if (sp->is_edlc) {
 		sregs->rw.wregs.control = sp->control & ~(SEEQ_CTRL_XCNT);
 		sregs->rw.wregs.control = sp->control;
 	}
@@ -361,11 +362,10 @@
 	 * adapter.  The following code is only safe iff the HPCDMA
 	 * is not active!
 	 */
-	while((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) ==
+	while ((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) ==
 	      (HPCDMA_XIU | HPCDMA_ETXD))
-		td = (struct sgiseeq_tx_desc *)
-			KSEG1ADDR(td->tdma.pnext);
-	if(td->tdma.cntinfo & HPCDMA_XIU) {
+		td = (struct sgiseeq_tx_desc *)(long) KSEG1ADDR(td->tdma.pnext);
+	if (td->tdma.cntinfo & HPCDMA_XIU) {
 		hregs->tx_ndptr = PHYSADDR(td);
 		hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
 	}
@@ -381,23 +381,23 @@
 
 	tx_maybe_reset_collisions(sp, sregs);
 
-	if(!(status & (HPC3_ETXCTRL_ACTIVE | SEEQ_TSTAT_PTRANS))) {
+	if (!(status & (HPC3_ETXCTRL_ACTIVE | SEEQ_TSTAT_PTRANS))) {
 		/* Oops, HPC detected some sort of error. */
-		if(status & SEEQ_TSTAT_R16)
+		if (status & SEEQ_TSTAT_R16)
 			sp->stats.tx_aborted_errors++;
-		if(status & SEEQ_TSTAT_UFLOW)
+		if (status & SEEQ_TSTAT_UFLOW)
 			sp->stats.tx_fifo_errors++;
-		if(status & SEEQ_TSTAT_LCLS)
+		if (status & SEEQ_TSTAT_LCLS)
 			sp->stats.collisions++;
 	}
 
 	/* Ack 'em... */
-	for(j = sp->tx_old; j != sp->tx_new; j = NEXT_TX(j)) {
+	for (j = sp->tx_old; j != sp->tx_new; j = NEXT_TX(j)) {
 		td = &sp->srings.tx_desc[j];
 
-		if(!(td->tdma.cntinfo & (HPCDMA_XIU)))
+		if (!(td->tdma.cntinfo & (HPCDMA_XIU)))
 			break;
-		if(!(td->tdma.cntinfo & (HPCDMA_ETXD))) {
+		if (!(td->tdma.cntinfo & (HPCDMA_ETXD))) {
 			if(!(status & HPC3_ETXCTRL_ACTIVE)) {
 				hregs->tx_ndptr = PHYSADDR(td);
 				hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
@@ -411,15 +411,6 @@
 	}
 }
 
-static inline void tx_maybe_unbusy(struct sgiseeq_private *sp,
-				   struct net_device *dev)
-{
-	if((TX_BUFFS_AVAIL(sp) >= 0) && dev->tbusy) {
-		dev->tbusy = 0;
-		mark_bh(NET_BH);
-	}
-}
-
 static void sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
@@ -429,17 +420,17 @@
 
 	/* Ack the IRQ and set software state. */
 	hregs->rx_reset = HPC3_ERXRST_CLRIRQ;
-	dev->interrupt = 1;
 
 	/* Always check for received packets. */
 	sgiseeq_rx(dev, sp, hregs, sregs);
 
 	/* Only check for tx acks iff we have something queued. */
-	if(sp->tx_old != sp->tx_new)
+	if (sp->tx_old != sp->tx_new)
 		sgiseeq_tx(dev, sp, hregs, sregs);
 
-	tx_maybe_unbusy(sp, dev);
-	dev->interrupt = 0;
+	if ((TX_BUFFS_AVAIL(sp) > 0) && netif_queue_stopped(dev)) {
+		netif_wake_queue(dev);
+	}
 }
 
 static int sgiseeq_open(struct net_device *dev)
@@ -449,7 +440,7 @@
 	unsigned long flags;
 
 	save_flags(flags); cli();
-	if(request_irq(dev->irq, sgiseeq_interrupt, 0, sgiseeqstr, (void *) dev)) {
+	if (request_irq(dev->irq, sgiseeq_interrupt, 0, sgiseeqstr, (void *) dev)) {
 		printk("Seeq8003: Can't get irq %d\n", dev->irq);
 		restore_flags(flags);
 		return -EAGAIN;
@@ -457,9 +448,7 @@
 
 	init_seeq(dev, sp, sregs);
 
-	dev->tbusy = 0;
-	dev->interrupt = 0;
-	dev->start = 1;
+	netif_start_queue(dev);
 	restore_flags(flags);
 	return 0;
 }
@@ -469,8 +458,7 @@
 	struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
 	volatile struct sgiseeq_regs *sregs = sp->sregs;
 
-	dev->start = 0;
-	dev->tbusy = 1;
+	netif_stop_queue(dev);
 
 	/* Shutdown the Seeq. */
 	reset_hpc3_and_seeq(sp->hregs, sregs);
@@ -488,9 +476,7 @@
 	init_seeq(dev, sp, sregs);
 
 	dev->trans_start = jiffies;
-	dev->interrupt = 0;
-	dev->start = 1;
-	dev->tbusy = 0;
+	netif_wake_queue(dev);
 
 	return 0;
 }
@@ -501,34 +487,6 @@
 	sgiseeq_reset(gdev);
 }
 
-static inline int verify_tx(struct sgiseeq_private *sp,
-			    struct net_device *dev,
-			    struct sk_buff *skb)
-{
-	/* Are we bolixed? */
-	if(dev->tbusy) {
-		int tickssofar = jiffies - dev->trans_start;
-		if (tickssofar < 20)
-			return 1;
-
-		printk("%s: transmit timed out, ticks=%d resetting\n",
-		       dev->name, tickssofar);
-		sgiseeq_reset(dev);
-		return 0;
-	}
-	/* Are we getting in someone else's way? */
-	if(test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
-		printk("%s: Transmitter access conflict.\n", dev->name);
-		return -1;
-	}
-
-	/* Can we even send anything? */
-	if(!TX_BUFFS_AVAIL(sp))
-		return -1;
-
-	return 0;
-}
-
 static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
@@ -537,10 +495,7 @@
 	struct sgiseeq_tx_desc *td;
 	int skblen, len, entry;
 
-	if(verify_tx(sp, dev, skb))
-		return -1; /* Yeee... */
-
-	save_flags(flags); cli();
+	save_and_cli(flags);
 
 	/* Setup... */
 	skblen = skb->len;
@@ -561,10 +516,10 @@
 	 *    entry and the HPC got to the end of the chain before we
 	 *    added this new entry and restarted it.
 	 */
-	memcpy((char *)td->buf_vaddr, skb->data, skblen);
-	td->tdma.cntinfo = ((len) & HPCDMA_BCNT) |
-		(HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX);
-	if(sp->tx_old != sp->tx_new) {
+	memcpy((char *)(long)td->buf_vaddr, skb->data, skblen);
+	td->tdma.cntinfo = (len & HPCDMA_BCNT) |
+	                   (HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX);
+	if (sp->tx_old != sp->tx_new) {
 		struct sgiseeq_tx_desc *backend;
 
 		backend = &sp->srings.tx_desc[PREV_TX(sp->tx_new)];
@@ -573,18 +528,28 @@
 	sp->tx_new = NEXT_TX(sp->tx_new); /* Advance. */
 
 	/* Maybe kick the HPC back into motion. */
-	if(!(hregs->tx_ctrl & HPC3_ETXCTRL_ACTIVE))
+	if (!(hregs->tx_ctrl & HPC3_ETXCTRL_ACTIVE))
 		kick_tx(&sp->srings.tx_desc[sp->tx_old], hregs);
 
 	dev->trans_start = jiffies;
 	dev_kfree_skb(skb);
 
-	if(TX_BUFFS_AVAIL(sp))
-		dev->tbusy = 0;
+	if (!TX_BUFFS_AVAIL(sp))
+		netif_stop_queue(dev);
 	restore_flags(flags);
+
 	return 0;
 }
 
+static void timeout(struct net_device *dev)
+{
+	printk("%s: transmit timed out, resetting\n", dev->name);
+	sgiseeq_reset(dev);
+
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+}
+
 static struct enet_statistics *sgiseeq_get_stats(struct net_device *dev)
 {
 	struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
@@ -600,7 +565,7 @@
 {
 	int i = 0;
 
-	while(i < (nbufs - 1)) {
+	while (i < (nbufs - 1)) {
 		buf[i].tdma.pnext = PHYSADDR(&buf[i + 1]);
 		buf[i].tdma.pbuf = 0;
 		i++;
@@ -612,7 +577,7 @@
 {
 	int i = 0;
 
-	while(i < (nbufs - 1)) {
+	while (i < (nbufs - 1)) {
 		buf[i].rdma.pnext = PHYSADDR(&buf[i + 1]);
 		buf[i].rdma.pbuf = 0;
 		i++;
@@ -632,20 +597,20 @@
 	int i;
 	struct sgiseeq_private *sp;
 
-	if(dev == NULL) {
+	if (dev == NULL) {
 		dev = init_etherdev(0, sizeof(struct sgiseeq_private));
 	} else {
 		dev->priv = (struct sgiseeq_private *) get_free_page(GFP_KERNEL);
-		if(dev->priv == NULL)
+		if (dev->priv == NULL)
 			return -ENOMEM;
 	}
 
-	if(!version_printed++)
+	if (!version_printed++)
 		printk(version);
 
 	printk("%s: SGI Seeq8003 ", dev->name);
 
-	for(i = 0; i < 6; i++)
+	for (i = 0; i < 6; i++)
 		printk("%2.2x%c",
 		       dev->dev_addr[i] = onboard_eth_addr[i],
 		       i == 5 ? ' ': ':');
@@ -679,7 +644,7 @@
 	hpc3_eth_reset((volatile struct hpc3_ethregs *) hregs);
 
 	sp->is_edlc = !(sregs->rw.rregs.collision_tx[0] & 0xff);
-	if(sp->is_edlc) {
+	if (sp->is_edlc) {
 		sp->control = (SEEQ_CTRL_XCNT | SEEQ_CTRL_ACCNT |
 			       SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT |
 			       SEEQ_CTRL_ENCARR);
@@ -688,6 +653,8 @@
 	dev->open                 = sgiseeq_open;
 	dev->stop                 = sgiseeq_close;
 	dev->hard_start_xmit      = sgiseeq_start_xmit;
+	dev->tx_timeout           = timeout;
+	dev->watchdog_timeo       = (200 * HZ) / 1000;
 	dev->get_stats            = sgiseeq_get_stats;
 	dev->set_multicast_list   = sgiseeq_set_multicast;
 	dev->irq                  = irq;
@@ -699,9 +666,9 @@
 
 static inline unsigned char str2hexnum(unsigned char c)
 {
-	if(c >= '0' && c <= '9')
+	if (c >= '0' && c <= '9')
 		return c - '0';
-	if(c >= 'a' && c <= 'f')
+	if (c >= 'a' && c <= 'f')
 		return c - 'a' + 10;
 	return 0; /* foo */
 }
@@ -710,7 +677,7 @@
 {
 	int i;
 
-	for(i = 0; i < 6; i++) {
+	for (i = 0; i < 6; i++) {
 		unsigned char num;
 
 		if(*str == ':')
@@ -732,11 +699,12 @@
 
 	/* First get the ethernet address of the onboard
 	 * interface from ARCS.
-	 * (This is fragile; PROM doesn't like running from cache.)
+	 * This is fragile; PROM doesn't like running from cache.
+	 * On MIPS64 it crashes for some other, yet unknown reason.
 	 */
 	ep = romvec->get_evar("eaddr");
 	str2eaddr(onboard_eth_addr, ep);
 	return sgiseeq_init(dev,
 			    (struct sgiseeq_regs *) (KSEG1ADDR(0x1fbd4000)),
-			    &hpc3c0->ethregs, 3);
+			    &hpc3c0->ethregs, SGI_ENET_IRQ);
 }
diff -u --recursive --new-file v2.3.47/linux/drivers/net/sgiseeq.h linux/drivers/net/sgiseeq.h
--- v2.3.47/linux/drivers/net/sgiseeq.h	Mon Oct 11 15:38:15 1999
+++ linux/drivers/net/sgiseeq.h	Thu Feb 24 22:49:19 2000
@@ -1,4 +1,4 @@
-/* $Id: sgiseeq.h,v 1.3 1998/08/25 09:17:45 ralf Exp $
+/* $Id: sgiseeq.h,v 1.5 1999/12/04 03:59:03 ralf Exp $
  * sgiseeq.h: Defines for the Seeq8003 ethernet controller.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -7,27 +7,27 @@
 #define _SGISEEQ_H
 
 struct sgiseeq_wregs {
-	volatile unsigned long multicase_high[2];
-	volatile unsigned long frame_gap;
-	volatile unsigned long control;
+	volatile unsigned int multicase_high[2];
+	volatile unsigned int frame_gap;
+	volatile unsigned int control;
 };
 
 struct sgiseeq_rregs {
-	volatile unsigned long collision_tx[2];
-	volatile unsigned long collision_all[2];
-	volatile unsigned long _unused0;
-	volatile unsigned long rflags; 
+	volatile unsigned int collision_tx[2];
+	volatile unsigned int collision_all[2];
+	volatile unsigned int _unused0;
+	volatile unsigned int rflags; 
 };
 
 struct sgiseeq_regs {
 	union {
-		volatile unsigned long eth_addr[6];
-		volatile unsigned long multicast_low[6];
+		volatile unsigned int eth_addr[6];
+		volatile unsigned int multicast_low[6];
 		struct sgiseeq_wregs wregs;
 		struct sgiseeq_rregs rregs;
 	} rw;
-	volatile unsigned long rstat;
-	volatile unsigned long tstat;
+	volatile unsigned int rstat;
+	volatile unsigned int tstat;
 };
 
 /* Seeq8003 receive status register */
diff -u --recursive --new-file v2.3.47/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c
--- v2.3.47/linux/drivers/net/sk_g16.c	Sun Feb 13 19:29:04 2000
+++ linux/drivers/net/sk_g16.c	Mon Feb 21 11:24:39 2000
@@ -1172,7 +1172,7 @@
  *     YY/MM/DD  uid  Description
 -*/
 
-static int SK_timeout(struct net_device *dev)
+static void SK_timeout(struct net_device *dev)
 {
 	printk(KERN_WARNING "%s: xmitter timed out, try to restart!\n", dev->name);
 	SK_lance_init(dev, MODE_NORMAL); /* Reinit LANCE */
diff -u --recursive --new-file v2.3.47/linux/drivers/net/tokenring/olympic.c linux/drivers/net/tokenring/olympic.c
--- v2.3.47/linux/drivers/net/tokenring/olympic.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/net/tokenring/olympic.c	Wed Feb 23 11:27:14 2000
@@ -26,10 +26,9 @@
  *	      resource. Driver also reports the card name returned by
  *            the pci resource.
  *  1/11/00 - Added spinlocks for smp
- *  
- *  To Do:
+ *  2/23/00 - Updated to dev_kfree_irq 
  *
- *  IPv6 Multicast
+ *  To Do:
  *
  *  If Problems do Occur
  *  Most problems can be rectified by either closing and opening the interface
@@ -88,7 +87,7 @@
  */
 
 static char *version = 
-"Olympic.c v0.3.1 1/11/00 - Peter De Schrijver & Mike Phillips" ; 
+"Olympic.c v0.3.2 2/23/00 - Peter De Schrijver & Mike Phillips" ; 
 
 static char *open_maj_error[]  = {"No error", "Lobe Media Test", "Physical Insertion",
 				   "Address Verification", "Neighbor Notification (Ring Poll)",
@@ -777,7 +776,7 @@
 			olympic_priv->free_tx_ring_entries++;
 			olympic_priv->olympic_stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
 			olympic_priv->olympic_stats.tx_packets++ ; 
-			dev_kfree_skb(olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]);
+			dev_kfree_skb_irq(olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]);
 			olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=0xdeadbeef;
 			olympic_priv->olympic_tx_status_ring[olympic_priv->tx_ring_last_status].status=0;
 			netif_wake_queue(dev);
diff -u --recursive --new-file v2.3.47/linux/drivers/net/tulip/21142.c linux/drivers/net/tulip/21142.c
--- v2.3.47/linux/drivers/net/tulip/21142.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/tulip/21142.c	Fri Feb 25 15:16:37 2000
@@ -0,0 +1,235 @@
+/*
+	drivers/net/tulip/21142.c
+
+	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
+	Copyright 2000  The Linux Kernel Team
+	Written/copyright 1994-1999 by Donald Becker.
+
+	This software may be used and distributed according to the terms
+	of the GNU Public License, incorporated herein by reference.
+
+	Please refer to Documentation/networking/tulip.txt for more
+	information on this driver.
+
+*/
+
+#include "tulip.h"
+#include <asm/io.h>
+
+
+static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, };
+u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, };
+static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
+
+
+
+/* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list
+   of available transceivers.  */
+void t21142_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int csr12 = inl(ioaddr + CSR12);
+	int next_tick = 60*HZ;
+	int new_csr6 = 0;
+
+	if (tulip_debug > 2)
+		printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n",
+			   dev->name, csr12, medianame[dev->if_port]);
+	if (tulip_media_cap[dev->if_port] & MediaIsMII) {
+		tulip_check_duplex(dev);
+		next_tick = 60*HZ;
+	} else if (tp->nwayset) {
+		/* Don't screw up a negotiated session! */
+		if (tulip_debug > 1)
+			printk(KERN_INFO"%s: Using NWay-set %s media, csr12 %8.8x.\n",
+				   dev->name, medianame[dev->if_port], csr12);
+	} else if (tp->medialock) {
+			;
+	} else if (dev->if_port == 3) {
+		if (csr12 & 2) {	/* No 100mbps link beat, revert to 10mbps. */
+			if (tulip_debug > 1)
+				printk(KERN_INFO"%s: No 21143 100baseTx link beat, %8.8x, "
+					   "trying NWay.\n", dev->name, csr12);
+			t21142_start_nway(dev);
+			next_tick = 3*HZ;
+		}
+	} else if ((csr12 & 0x7000) != 0x5000) {
+		/* Negotiation failed.  Search media types. */
+		if (tulip_debug > 1)
+			printk(KERN_INFO"%s: 21143 negotiation failed, status %8.8x.\n",
+				   dev->name, csr12);
+		if (!(csr12 & 4)) {		/* 10mbps link beat good. */
+			new_csr6 = 0x82420000;
+			dev->if_port = 0;
+			outl(0, ioaddr + CSR13);
+			outl(0x0003FFFF, ioaddr + CSR14);
+			outw(t21142_csr15[dev->if_port], ioaddr + CSR15);
+			outl(t21142_csr13[dev->if_port], ioaddr + CSR13);
+		} else {
+			/* Select 100mbps port to check for link beat. */
+			new_csr6 = 0x83860000;
+			dev->if_port = 3;
+			outl(0, ioaddr + CSR13);
+			outl(0x0003FF7F, ioaddr + CSR14);
+			outw(8, ioaddr + CSR15);
+			outl(1, ioaddr + CSR13);
+		}
+		if (tulip_debug > 1)
+			printk(KERN_INFO"%s: Testing new 21143 media %s.\n",
+				   dev->name, medianame[dev->if_port]);
+		if (new_csr6 != (tp->csr6 & ~0x00D5)) {
+			tp->csr6 &= 0x00D5;
+			tp->csr6 |= new_csr6;
+			outl(0x0301, ioaddr + CSR12);
+			tulip_outl_CSR6(tp, tp->csr6 | 0x0002);
+			tulip_outl_CSR6(tp, tp->csr6 | 0x2002);
+		}
+		next_tick = 3*HZ;
+	}
+
+	tp->timer.expires = RUN_AT(next_tick);
+	add_timer(&tp->timer);
+}
+
+
+void t21142_start_nway(struct net_device *dev)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int csr14 = ((tp->to_advertise & 0x0780) << 9)  |
+		((tp->to_advertise&0x0020)<<1) | 0xffbf;
+
+	dev->if_port = 0;
+	tp->nway = tp->mediasense = 1;
+	tp->nwayset = tp->lpar = 0;
+	if (tulip_debug > 1)
+		printk(KERN_DEBUG "%s: Restarting 21143 autonegotiation, %8.8x.\n",
+			   dev->name, csr14);
+	outl(0x0001, ioaddr + CSR13);
+	outl(csr14, ioaddr + CSR14);
+	tp->csr6 = 0x82420000 | (tp->to_advertise & 0x0040 ? 0x0200 : 0);
+	tulip_outl_CSR6(tp, tp->csr6);
+	if (tp->mtable  &&  tp->mtable->csr15dir) {
+		outl(tp->mtable->csr15dir, ioaddr + CSR15);
+		outl(tp->mtable->csr15val, ioaddr + CSR15);
+	} else
+		outw(0x0008, ioaddr + CSR15);
+	outl(0x1301, ioaddr + CSR12); 		/* Trigger NWAY. */
+}
+
+
+void t21142_lnk_change(struct net_device *dev, int csr5)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int csr12 = inl(ioaddr + CSR12);
+
+	if (tulip_debug > 1)
+		printk(KERN_INFO"%s: 21143 link status interrupt %8.8x, CSR5 %x, "
+			   "%8.8x.\n", dev->name, csr12, csr5, inl(ioaddr + CSR14));
+
+	/* If NWay finished and we have a negotiated partner capability. */
+	if (tp->nway  &&  !tp->nwayset  &&  (csr12 & 0x7000) == 0x5000) {
+		int setup_done = 0;
+		int negotiated = tp->to_advertise & (csr12 >> 16);
+		tp->lpar = csr12 >> 16;
+		tp->nwayset = 1;
+		if (negotiated & 0x0100)		dev->if_port = 5;
+		else if (negotiated & 0x0080)	dev->if_port = 3;
+		else if (negotiated & 0x0040)	dev->if_port = 4;
+		else if (negotiated & 0x0020)	dev->if_port = 0;
+		else {
+			tp->nwayset = 0;
+			if ((csr12 & 2) == 0  &&  (tp->to_advertise & 0x0180))
+				dev->if_port = 3;
+		}
+		tp->full_duplex = (tulip_media_cap[dev->if_port] & MediaAlwaysFD) ? 1:0;
+
+		if (tulip_debug > 1) {
+			if (tp->nwayset)
+				printk(KERN_INFO "%s: Switching to %s based on link "
+					   "negotiation %4.4x & %4.4x = %4.4x.\n",
+					   dev->name, medianame[dev->if_port], tp->to_advertise,
+					   tp->lpar, negotiated);
+			else
+				printk(KERN_INFO "%s: Autonegotiation failed, using %s,"
+					   " link beat status %4.4x.\n",
+					   dev->name, medianame[dev->if_port], csr12);
+		}
+
+		if (tp->mtable) {
+			int i;
+			for (i = 0; i < tp->mtable->leafcount; i++)
+				if (tp->mtable->mleaf[i].media == dev->if_port) {
+					tp->cur_index = i;
+					tulip_select_media(dev, 0);
+					setup_done = 1;
+					break;
+				}
+		}
+		if ( ! setup_done) {
+			tp->csr6 = dev->if_port & 1 ? 0x83860000 : 0x82420000;
+			if (tp->full_duplex)
+				tp->csr6 |= 0x0200;
+			outl(1, ioaddr + CSR13);
+		}
+#if 0							/* Restart shouldn't be needed. */
+		tulip_outl_CSR6(tp, tp->csr6 | 0x0000);
+		if (tulip_debug > 2)
+			printk(KERN_DEBUG "%s:  Restarting Tx and Rx, CSR5 is %8.8x.\n",
+				   dev->name, inl(ioaddr + CSR5));
+#endif
+		tulip_outl_CSR6(tp, tp->csr6 | 0x2002);
+		if (tulip_debug > 2)
+			printk(KERN_DEBUG "%s:  Setting CSR6 %8.8x/%x CSR12 %8.8x.\n",
+				   dev->name, tp->csr6, inl(ioaddr + CSR6),
+				   inl(ioaddr + CSR12));
+	} else if ((tp->nwayset  &&  (csr5 & 0x08000000)
+				&& (dev->if_port == 3  ||  dev->if_port == 5)
+				&& (csr12 & 2) == 2) ||
+			   (tp->nway && (csr5 & (TPLnkFail)))) {
+		/* Link blew? Maybe restart NWay. */
+		del_timer(&tp->timer);
+		t21142_start_nway(dev);
+		tp->timer.expires = RUN_AT(3*HZ);
+		add_timer(&tp->timer);
+	} else if (dev->if_port == 3  ||  dev->if_port == 5) {
+		if (tulip_debug > 1)
+			printk(KERN_INFO"%s: 21143 %s link beat %s.\n",
+				   dev->name, medianame[dev->if_port],
+				   (csr12 & 2) ? "failed" : "good");
+		if ((csr12 & 2)  &&  ! tp->medialock) {
+			del_timer(&tp->timer);
+			t21142_start_nway(dev);
+			tp->timer.expires = RUN_AT(3*HZ);
+			add_timer(&tp->timer);
+		}
+	} else if (dev->if_port == 0  ||  dev->if_port == 4) {
+		if ((csr12 & 4) == 0)
+			printk(KERN_INFO"%s: 21143 10baseT link beat good.\n",
+				   dev->name);
+	} else if (!(csr12 & 4)) {		/* 10mbps link beat good. */
+		if (tulip_debug)
+			printk(KERN_INFO"%s: 21143 10mbps sensed media.\n",
+				   dev->name);
+		dev->if_port = 0;
+	} else if (tp->nwayset) {
+		if (tulip_debug)
+			printk(KERN_INFO"%s: 21143 using NWay-set %s, csr6 %8.8x.\n",
+				   dev->name, medianame[dev->if_port], tp->csr6);
+	} else {		/* 100mbps link beat good. */
+		if (tulip_debug)
+			printk(KERN_INFO"%s: 21143 100baseTx sensed media.\n",
+				   dev->name);
+		dev->if_port = 3;
+		tp->csr6 = 0x83860000;
+		outl(0x0003FF7F, ioaddr + CSR14);
+		outl(0x0301, ioaddr + CSR12);
+		tulip_outl_CSR6(tp, tp->csr6 | 0x0002);
+		tulip_outl_CSR6(tp, tp->csr6 | 0x2002);
+	}
+}
+
+
diff -u --recursive --new-file v2.3.47/linux/drivers/net/tulip/Makefile linux/drivers/net/tulip/Makefile
--- v2.3.47/linux/drivers/net/tulip/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/tulip/Makefile	Mon Feb 21 10:59:36 2000
@@ -0,0 +1,14 @@
+#
+# Makefile for the Tulip ethernet driver
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+O_TARGET := tulip.o
+O_OBJS   := 21142.o eeprom.o interrupt.o media.o pnic.o timer.o tulip_core.o
+M_OBJS   := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.47/linux/drivers/net/tulip/eeprom.c linux/drivers/net/tulip/eeprom.c
--- v2.3.47/linux/drivers/net/tulip/eeprom.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/tulip/eeprom.c	Fri Feb 25 15:16:37 2000
@@ -0,0 +1,270 @@
+/*
+	drivers/net/tulip/eeprom.c
+
+	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
+	Copyright 2000  The Linux Kernel Team
+	Written/copyright 1994-1999 by Donald Becker.
+
+	This software may be used and distributed according to the terms
+	of the GNU Public License, incorporated herein by reference.
+
+	Please refer to Documentation/networking/tulip.txt for more
+	information on this driver.
+
+*/
+
+#include "tulip.h"
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/unaligned.h>
+
+
+
+/* Serial EEPROM section. */
+/* The main routine to parse the very complicated SROM structure.
+   Search www.digital.com for "21X4 SROM" to get details.
+   This code is very complex, and will require changes to support
+   additional cards, so I'll be verbose about what is going on.
+   */
+
+/* Known cards that have old-style EEPROMs. */
+static struct eeprom_fixup eeprom_fixups[] __devinitdata = {
+  {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c,
+						  0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }},
+  {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f,
+							   0x0000, 0x009E, /* 10baseT */
+							   0x0004, 0x009E, /* 10baseT-FD */
+							   0x0903, 0x006D, /* 100baseTx */
+							   0x0905, 0x006D, /* 100baseTx-FD */ }},
+  {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f,
+								 0x0107, 0x8021, /* 100baseFx */
+								 0x0108, 0x8021, /* 100baseFx-FD */
+								 0x0100, 0x009E, /* 10baseT */
+								 0x0104, 0x009E, /* 10baseT-FD */
+								 0x0103, 0x006D, /* 100baseTx */
+								 0x0105, 0x006D, /* 100baseTx-FD */ }},
+  {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513,
+							   0x1001, 0x009E, /* 10base2, CSR12 0x10*/
+							   0x0000, 0x009E, /* 10baseT */
+							   0x0004, 0x009E, /* 10baseT-FD */
+							   0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */
+							   0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}},
+  {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F,
+								  0x1B01, 0x0000, /* 10base2,   CSR12 0x1B */
+								  0x0B00, 0x009E, /* 10baseT,   CSR12 0x0B */
+								  0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */
+								  0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */
+								  0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */
+   }},
+  {0, 0, 0, 0, {}}};
+
+
+static const char *block_name[] __devinitdata = {
+	"21140 non-MII",
+	"21140 MII PHY",
+	"21142 Serial PHY",
+	"21142 MII PHY",
+	"21143 SYM PHY",
+	"21143 reset method"
+};
+
+
+void __devinit tulip_parse_eeprom(struct net_device *dev)
+{
+	/* The last media info list parsed, for multiport boards.  */
+	static struct mediatable *last_mediatable = NULL;
+	static unsigned char *last_ee_data = NULL;
+	static int controller_index = 0;
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	unsigned char *ee_data = tp->eeprom;
+	int i;
+
+	tp->mtable = 0;
+	/* Detect an old-style (SA only) EEPROM layout:
+	   memcmp(eedata, eedata+16, 8). */
+	for (i = 0; i < 8; i ++)
+		if (ee_data[i] != ee_data[16+i])
+			break;
+	if (i >= 8) {
+		if (ee_data[0] == 0xff) {
+			if (last_mediatable) {
+				controller_index++;
+				printk(KERN_INFO "%s:  Controller %d of multiport board.\n",
+					   dev->name, controller_index);
+				tp->mtable = last_mediatable;
+				ee_data = last_ee_data;
+				goto subsequent_board;
+			} else
+				printk(KERN_INFO "%s:  Missing EEPROM, this interface may "
+					   "not work correctly!\n",
+			   dev->name);
+			return;
+		}
+	  /* Do a fix-up based on the vendor half of the station address prefix. */
+	  for (i = 0; eeprom_fixups[i].name; i++) {
+		if (dev->dev_addr[0] == eeprom_fixups[i].addr0
+			&&  dev->dev_addr[1] == eeprom_fixups[i].addr1
+			&&  dev->dev_addr[2] == eeprom_fixups[i].addr2) {
+		  if (dev->dev_addr[2] == 0xE8  &&  ee_data[0x1a] == 0x55)
+			  i++;			/* An Accton EN1207, not an outlaw Maxtech. */
+		  memcpy(ee_data + 26, eeprom_fixups[i].newtable,
+				 sizeof(eeprom_fixups[i].newtable));
+		  printk(KERN_INFO "%s: Old format EEPROM on '%s' board.  Using"
+				 " substitute media control info.\n",
+				 dev->name, eeprom_fixups[i].name);
+		  break;
+		}
+	  }
+	  if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
+		  printk(KERN_INFO "%s: Old style EEPROM with no media selection "
+				 "information.\n",
+			   dev->name);
+		return;
+	  }
+	}
+
+	controller_index = 0;
+	if (ee_data[19] > 1) {		/* Multiport board. */
+		last_ee_data = ee_data;
+	}
+subsequent_board:
+
+	if (ee_data[27] == 0) {		/* No valid media table. */
+	} else if (tp->chip_id == DC21041) {
+		unsigned char *p = (void *)ee_data + ee_data[27 + controller_index*3];
+		int media = get_u16(p);
+		int count = p[2];
+		p += 3;
+
+		printk(KERN_INFO "%s: 21041 Media table, default media %4.4x (%s).\n",
+			   dev->name, media,
+			   media & 0x0800 ? "Autosense" : medianame[media & 15]);
+		for (i = 0; i < count; i++) {
+			unsigned char media_code = *p++;
+			if (media_code & 0x40)
+				p += 6;
+			printk(KERN_INFO "%s:  21041 media #%d, %s.\n",
+				   dev->name, media_code & 15, medianame[media_code & 15]);
+		}
+	} else {
+		unsigned char *p = (void *)ee_data + ee_data[27];
+		unsigned char csr12dir = 0;
+		int count, new_advertise = 0;
+		struct mediatable *mtable;
+		u16 media = get_u16(p);
+
+		p += 2;
+		if (tp->flags & CSR12_IN_SROM)
+			csr12dir = *p++;
+		count = *p++;
+		mtable = (struct mediatable *)
+			kmalloc(sizeof(struct mediatable) + count*sizeof(struct medialeaf),
+					GFP_KERNEL);
+		if (mtable == NULL)
+			return;				/* Horrible, impossible failure. */
+		last_mediatable = tp->mtable = mtable;
+		mtable->defaultmedia = media;
+		mtable->leafcount = count;
+		mtable->csr12dir = csr12dir;
+		mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
+		mtable->csr15dir = mtable->csr15val = 0;
+
+		printk(KERN_INFO "%s:  EEPROM default media type %s.\n", dev->name,
+			   media & 0x0800 ? "Autosense" : medianame[media & 15]);
+		for (i = 0; i < count; i++) {
+			struct medialeaf *leaf = &mtable->mleaf[i];
+
+			if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */
+				leaf->type = 0;
+				leaf->media = p[0] & 0x3f;
+				leaf->leafdata = p;
+				if ((p[2] & 0x61) == 0x01)	/* Bogus, but Znyx boards do it. */
+					mtable->has_mii = 1;
+				p += 4;
+			} else {
+				leaf->type = p[1];
+				if (p[1] == 0x05) {
+					mtable->has_reset = i;
+					leaf->media = p[2] & 0x0f;
+				} else if (p[1] & 1) {
+					mtable->has_mii = 1;
+					leaf->media = 11;
+				} else {
+					mtable->has_nonmii = 1;
+					leaf->media = p[2] & 0x0f;
+					switch (leaf->media) {
+					case 0: new_advertise |= 0x0020; break;
+					case 4: new_advertise |= 0x0040; break;
+					case 3: new_advertise |= 0x0080; break;
+					case 5: new_advertise |= 0x0100; break;
+					case 6: new_advertise |= 0x0200; break;
+					}
+					if (p[1] == 2  &&  leaf->media == 0) {
+						if (p[2] & 0x40) {
+							u32 base15 = get_unaligned((u16*)&p[7]);
+							mtable->csr15dir =
+								(get_unaligned((u16*)&p[9])<<16) + base15;
+							mtable->csr15val =
+								(get_unaligned((u16*)&p[11])<<16) + base15;
+						} else {
+							mtable->csr15dir = get_unaligned((u16*)&p[3])<<16;
+							mtable->csr15val = get_unaligned((u16*)&p[5])<<16;
+						}
+					}
+				}
+				leaf->leafdata = p + 2;
+				p += (p[0] & 0x3f) + 1;
+			}
+			if (tulip_debug > 1  &&  leaf->media == 11) {
+				unsigned char *bp = leaf->leafdata;
+				printk(KERN_INFO "%s:  MII interface PHY %d, setup/reset "
+					   "sequences %d/%d long, capabilities %2.2x %2.2x.\n",
+					   dev->name, bp[0], bp[1], bp[2 + bp[1]*2],
+					   bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]);
+			}
+			printk(KERN_INFO "%s:  Index #%d - Media %s (#%d) described "
+				   "by a %s (%d) block.\n",
+				   dev->name, i, medianame[leaf->media], leaf->media,
+				   block_name[leaf->type], leaf->type);
+		}
+		if (new_advertise)
+			tp->to_advertise = new_advertise;
+	}
+}
+/* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/
+
+/* Note: this routine returns extra data bits for size detection. */
+int __devinit tulip_read_eeprom(long ioaddr, int location, int addr_len)
+{
+	int i;
+	unsigned retval = 0;
+	long ee_addr = ioaddr + CSR9;
+	int read_cmd = location | (EE_READ_CMD << addr_len);
+
+	outl(EE_ENB & ~EE_CS, ee_addr);
+	outl(EE_ENB, ee_addr);
+
+	/* Shift the read command bits out. */
+	for (i = 4 + addr_len; i >= 0; i--) {
+		short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+		outl(EE_ENB | dataval, ee_addr);
+		eeprom_delay();
+		outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay();
+		retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
+	}
+	outl(EE_ENB, ee_addr);
+
+	for (i = 16; i > 0; i--) {
+		outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay();
+		retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
+		outl(EE_ENB, ee_addr);
+		eeprom_delay();
+	}
+
+	/* Terminate the EEPROM access. */
+	outl(EE_ENB & ~EE_CS, ee_addr);
+	return retval;
+}
+
diff -u --recursive --new-file v2.3.47/linux/drivers/net/tulip/interrupt.c linux/drivers/net/tulip/interrupt.c
--- v2.3.47/linux/drivers/net/tulip/interrupt.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/tulip/interrupt.c	Fri Feb 25 15:16:37 2000
@@ -0,0 +1,337 @@
+/*
+	drivers/net/tulip/interrupt.c
+
+	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
+	Copyright 2000  The Linux Kernel Team
+	Written/copyright 1994-1999 by Donald Becker.
+
+	This software may be used and distributed according to the terms
+	of the GNU Public License, incorporated herein by reference.
+
+	Please refer to Documentation/networking/tulip.txt for more
+	information on this driver.
+
+*/
+
+#include "tulip.h"
+#include <asm/io.h>
+#include <linux/etherdevice.h>
+
+
+int tulip_rx_copybreak;
+int tulip_max_interrupt_work;
+
+
+
+static int tulip_refill_rx(struct net_device *dev)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	int entry;
+	int refilled = 0;
+
+	/* Refill the Rx ring buffers. */
+	for (; tp->cur_rx - tp->dirty_rx > 0; tp->dirty_rx++) {
+		entry = tp->dirty_rx % RX_RING_SIZE;
+		if (tp->rx_skbuff[entry] == NULL) {
+			struct sk_buff *skb;
+			skb = tp->rx_skbuff[entry] = dev_alloc_skb(PKT_BUF_SZ);
+			if (skb == NULL)
+				break;
+			skb->dev = dev;			/* Mark as being used by this device. */
+			tp->rx_ring[entry].buffer1 = virt_to_le32desc(skb->tail);
+			refilled++;
+		}
+		tp->rx_ring[entry].status = cpu_to_le32(DescOwned);
+	}
+	return refilled;
+}
+
+
+static int tulip_rx(struct net_device *dev)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	int entry = tp->cur_rx % RX_RING_SIZE;
+	int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
+	int received = 0;
+
+	if (tulip_debug > 4)
+		printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
+			   tp->rx_ring[entry].status);
+	/* If we own the next entry, it is a new packet. Send it up. */
+	while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
+		s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+
+		if (tulip_debug > 5)
+			printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
+				   dev->name, entry, status);
+		if (--rx_work_limit < 0)
+			break;
+		if ((status & 0x38008300) != 0x0300) {
+			if ((status & 0x38000300) != 0x0300) {
+				/* Ingore earlier buffers. */
+				if ((status & 0xffff) != 0x7fff) {
+					if (tulip_debug > 1)
+						printk(KERN_WARNING "%s: Oversized Ethernet frame "
+							   "spanned multiple buffers, status %8.8x!\n",
+							   dev->name, status);
+					tp->stats.rx_length_errors++;
+				}
+			} else if (status & RxDescFatalErr) {
+				/* There was a fatal error. */
+				if (tulip_debug > 2)
+					printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
+						   dev->name, status);
+				tp->stats.rx_errors++; /* end of a packet.*/
+				if (status & 0x0890) tp->stats.rx_length_errors++;
+				if (status & 0x0004) tp->stats.rx_frame_errors++;
+				if (status & 0x0002) tp->stats.rx_crc_errors++;
+				if (status & 0x0001) tp->stats.rx_fifo_errors++;
+			}
+		} else {
+			/* Omit the four octet CRC from the length. */
+			short pkt_len = ((status >> 16) & 0x7ff) - 4;
+			struct sk_buff *skb;
+
+#ifndef final_version
+			if (pkt_len > 1518) {
+				printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
+					   dev->name, pkt_len, pkt_len);
+				pkt_len = 1518;
+				tp->stats.rx_length_errors++;
+			}
+#endif
+			/* Check if the packet is long enough to accept without copying
+			   to a minimally-sized skbuff. */
+			if (pkt_len < tulip_rx_copybreak
+				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+				skb->dev = dev;
+				skb_reserve(skb, 2);	/* 16 byte align the IP header */
+#if ! defined(__alpha__)
+				eth_copy_and_sum(skb, tp->rx_skbuff[entry]->tail, pkt_len, 0);
+				skb_put(skb, pkt_len);
+#else
+				memcpy(skb_put(skb, pkt_len), tp->rx_skbuff[entry]->tail,
+					   pkt_len);
+#endif
+			} else { 	/* Pass up the skb already on the Rx ring. */
+				char *temp = skb_put(skb = tp->rx_skbuff[entry], pkt_len);
+				tp->rx_skbuff[entry] = NULL;
+#ifndef final_version
+				if (le32desc_to_virt(tp->rx_ring[entry].buffer1) != temp)
+					printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
+						   "do not match in tulip_rx: %p vs. %p / %p.\n",
+						   dev->name,
+						   le32desc_to_virt(tp->rx_ring[entry].buffer1),
+						   skb->head, temp);
+#endif
+			}
+			skb->protocol = eth_type_trans(skb, dev);
+			netif_rx(skb);
+			dev->last_rx = jiffies;
+			tp->stats.rx_packets++;
+			tp->stats.rx_bytes += pkt_len;
+		}
+		received++;
+		entry = (++tp->cur_rx) % RX_RING_SIZE;
+	}
+
+	return received;
+}
+
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+   after the Tx thread. */
+void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *)dev_instance;
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int csr5;
+	int entry;
+	int missed;
+	int rx = 0;
+	int tx = 0;
+	int oi = 0;
+	int maxrx = RX_RING_SIZE;
+	int maxtx = TX_RING_SIZE;
+	int maxoi = TX_RING_SIZE;
+	int work_count = tulip_max_interrupt_work;
+
+	tp->nir++;
+
+	do {
+		csr5 = inl(ioaddr + CSR5);
+		/* Acknowledge all of the current interrupt sources ASAP. */
+		outl(csr5 & 0x0001ffff, ioaddr + CSR5);
+
+		if (tulip_debug > 4)
+			printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x.\n",
+				   dev->name, csr5, inl(dev->base_addr + CSR5));
+
+		if ((csr5 & (NormalIntr|AbnormalIntr)) == 0)
+			break;
+
+		if (csr5 & (RxIntr | RxNoBuf)) {
+			rx += tulip_rx(dev);
+			tulip_refill_rx(dev);
+		}
+
+		if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) {
+			unsigned int dirty_tx;
+
+			spin_lock(&tp->lock);
+
+			for (dirty_tx = tp->dirty_tx; tp->cur_tx - dirty_tx > 0;
+				 dirty_tx++) {
+				int entry = dirty_tx % TX_RING_SIZE;
+				int status = le32_to_cpu(tp->tx_ring[entry].status);
+
+				if (status < 0)
+					break;			/* It still has not been Txed */
+				/* Check for Rx filter setup frames. */
+				if (tp->tx_skbuff[entry] == NULL)
+					continue;
+				
+				if (status & 0x8000) {
+					/* There was an major error, log it. */
+#ifndef final_version
+					if (tulip_debug > 1)
+						printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
+							   dev->name, status);
+#endif
+					tp->stats.tx_errors++;
+					if (status & 0x4104) tp->stats.tx_aborted_errors++;
+					if (status & 0x0C00) tp->stats.tx_carrier_errors++;
+					if (status & 0x0200) tp->stats.tx_window_errors++;
+					if (status & 0x0002) tp->stats.tx_fifo_errors++;
+					if ((status & 0x0080) && tp->full_duplex == 0)
+						tp->stats.tx_heartbeat_errors++;
+#ifdef ETHER_STATS
+					if (status & 0x0100) tp->stats.collisions16++;
+#endif
+				} else {
+#ifdef ETHER_STATS
+					if (status & 0x0001) tp->stats.tx_deferred++;
+#endif
+					tp->stats.tx_bytes += tp->tx_skbuff[entry]->len;
+					tp->stats.collisions += (status >> 3) & 15;
+					tp->stats.tx_packets++;
+				}
+
+				/* Free the original skb. */
+				dev_kfree_skb_irq(tp->tx_skbuff[entry]);
+				tp->tx_skbuff[entry] = 0;
+				tx++;
+			}
+
+#ifndef final_version
+			if (tp->cur_tx - dirty_tx > TX_RING_SIZE) {
+				printk(KERN_ERR "%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
+					   dev->name, dirty_tx, tp->cur_tx, tp->tx_full);
+				dirty_tx += TX_RING_SIZE;
+			}
+#endif
+
+			if (tp->tx_full && tp->cur_tx - dirty_tx  < TX_RING_SIZE - 2) {
+				/* The ring is no longer full, clear tbusy. */
+				tp->tx_full = 0;
+				netif_wake_queue(dev);
+			}
+
+			tp->dirty_tx = dirty_tx;
+			if (csr5 & TxDied) {
+				if (tulip_debug > 2)
+					printk(KERN_WARNING "%s: The transmitter stopped."
+						   "  CSR5 is %x, CSR6 %x, new CSR6 %x.\n",
+						   dev->name, csr5, inl(ioaddr + CSR6), tp->csr6);
+				tulip_outl_CSR6(tp, tp->csr6 | 0x0002);
+				tulip_outl_CSR6(tp, tp->csr6 | 0x2002);
+			}
+			spin_unlock(&tp->lock);
+		}
+
+		/* Log errors. */
+		if (csr5 & AbnormalIntr) {	/* Abnormal error summary bit. */
+			if (csr5 == 0xffffffff)
+				break;
+			if (csr5 & TxJabber) tp->stats.tx_errors++;
+			if (csr5 & TxFIFOUnderflow) {
+				if ((tp->csr6 & 0xC000) != 0xC000)
+					tp->csr6 += 0x4000;	/* Bump up the Tx threshold */
+				else
+					tp->csr6 |= 0x00200000;  /* Store-n-forward. */
+				/* Restart the transmit process. */
+				tulip_outl_CSR6(tp, tp->csr6 | 0x0002);
+				tulip_outl_CSR6(tp, tp->csr6 | 0x2002);
+				outl(0, ioaddr + CSR1);
+			}
+			if (csr5 & RxDied) {		/* Missed a Rx frame. */
+				tp->stats.rx_errors++;
+				tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
+				tulip_outl_CSR6(tp, tp->csr6 | 0x2002);
+			}
+			if (csr5 & (TPLnkPass | TPLnkFail | 0x08000000)) {
+				if (tp->link_change)
+					(tp->link_change)(dev, csr5);
+			}
+			if (csr5 & SytemError) {
+				printk(KERN_ERR "%s: (%lu) System Error occured\n", dev->name, tp->nir);
+			}
+			/* Clear all error sources, included undocumented ones! */
+			outl(0x0800f7ba, ioaddr + CSR5);
+			oi++;
+		}
+		if (csr5 & TimerInt) {
+#if 0
+			if (tulip_debug > 2)
+				printk(KERN_ERR "%s: Re-enabling interrupts, %8.8x.\n",
+					   dev->name, csr5);
+			outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
+#endif
+			tp->ttimer = 0;
+			oi++;
+		}
+		if (tx > maxtx || rx > maxrx || oi > maxoi) {
+			if (tulip_debug > 1)
+				printk(KERN_WARNING "%s: Too much work during an interrupt, "
+					   "csr5=0x%8.8x. (%lu) (%d,%d,%d)\n", dev->name, csr5, tp->nir, tx, rx, oi);
+			/* Acknowledge all interrupt sources. */
+#if 0
+			/* Clear all interrupting sources, set timer to re-enable. */
+			outl(((~csr5) & 0x0001ebef) | NormalIntr | AbnormalIntr | TimerInt,
+				 ioaddr + CSR7);
+			outl(12, ioaddr + CSR11);
+			tp->ttimer = 1;
+#endif
+			break;
+		}
+	} while (work_count-- > 0);
+
+	tulip_refill_rx(dev);
+
+	/* check if we card is in suspend mode */
+	entry = tp->dirty_rx % RX_RING_SIZE;
+	if (tp->rx_skbuff[entry] == NULL) {
+		if (tulip_debug > 1)
+			printk(KERN_WARNING "%s: in rx suspend mode: (%lu) (tp->cur_rx = %u, ttimer = %d, rx = %d) go/stay in suspend mode\n", dev->name, tp->nir, tp->cur_rx, tp->ttimer, rx);
+		if (tp->ttimer == 0 || (inl(ioaddr + CSR11) & 0xffff) == 0) {
+			if (tulip_debug > 1)
+				printk(KERN_WARNING "%s: in rx suspend mode: (%lu) set timer\n", dev->name, tp->nir);
+			outl(tulip_tbl[tp->chip_id].valid_intrs | TimerInt,
+				ioaddr + CSR7);
+			outl(TimerInt, ioaddr + CSR5);
+			outl(12, ioaddr + CSR11);
+			tp->ttimer = 1;
+		}
+	}
+
+	if ((missed = inl(ioaddr + CSR8) & 0x1ffff)) {
+		tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
+	}
+
+	if (tulip_debug > 4)
+		printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n",
+			   dev->name, inl(ioaddr + CSR5));
+
+}
+
diff -u --recursive --new-file v2.3.47/linux/drivers/net/tulip/media.c linux/drivers/net/tulip/media.c
--- v2.3.47/linux/drivers/net/tulip/media.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/tulip/media.c	Fri Feb 25 15:16:37 2000
@@ -0,0 +1,403 @@
+/*
+	drivers/net/tulip/media.c
+
+	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
+	Copyright 2000  The Linux Kernel Team
+	Written/copyright 1994-1999 by Donald Becker.
+
+	This software may be used and distributed according to the terms
+	of the GNU Public License, incorporated herein by reference.
+
+	Please refer to Documentation/networking/tulip.txt for more
+	information on this driver.
+
+*/
+
+#include "tulip.h"
+#include <asm/io.h>
+
+
+/* This is a mysterious value that can be written to CSR11 in the 21040 (only)
+   to support a pre-NWay full-duplex signaling mechanism using short frames.
+   No one knows what it should be, but if left at its default value some
+   10base2(!) packets trigger a full-duplex-request interrupt. */
+#define FULL_DUPLEX_MAGIC	0x6969
+
+
+/* MII transceiver control section.
+   Read and write the MII registers using software-generated serial
+   MDIO protocol.  See the MII specifications or DP83840A data sheet
+   for details. */
+
+int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	int i;
+	int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
+	int retval = 0;
+	long ioaddr = dev->base_addr;
+	long mdio_addr = ioaddr + CSR9;
+
+	if (tp->chip_id == LC82C168) {
+		int i = 1000;
+		outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
+		inl(ioaddr + 0xA0);
+		inl(ioaddr + 0xA0);
+		while (--i > 0)
+			if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
+				return retval & 0xffff;
+		return 0xffff;
+	}
+
+	if (tp->chip_id == COMET) {
+		if (phy_id == 1) {
+			if (location < 7)
+				return inl(ioaddr + 0xB4 + (location<<2));
+			else if (location == 17)
+				return inl(ioaddr + 0xD0);
+			else if (location >= 29 && location <= 31)
+				return inl(ioaddr + 0xD4 + ((location-29)<<2));
+		}
+		return 0xffff;
+	}
+
+	/* Establish sync by sending at least 32 logic ones. */
+	for (i = 32; i >= 0; i--) {
+		outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
+		mdio_delay();
+		outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
+		mdio_delay();
+	}
+	/* Shift the read command bits out. */
+	for (i = 15; i >= 0; i--) {
+		int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
+
+		outl(MDIO_ENB | dataval, mdio_addr);
+		mdio_delay();
+		outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
+		mdio_delay();
+	}
+	/* Read the two transition, 16 data, and wire-idle bits. */
+	for (i = 19; i > 0; i--) {
+		outl(MDIO_ENB_IN, mdio_addr);
+		mdio_delay();
+		retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
+		outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+		mdio_delay();
+	}
+	return (retval>>1) & 0xffff;
+}
+
+void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int value)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	int i;
+	int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
+	long ioaddr = dev->base_addr;
+	long mdio_addr = ioaddr + CSR9;
+
+	if (tp->chip_id == LC82C168) {
+		int i = 1000;
+		outl(cmd, ioaddr + 0xA0);
+		do
+			if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
+				break;
+		while (--i > 0);
+		return;
+	}
+
+	if (tp->chip_id == COMET) {
+		if (phy_id != 1)
+			return;
+		if (location < 7)
+			outl(value, ioaddr + 0xB4 + (location<<2));
+		else if (location == 17)
+			outl(value, ioaddr + 0xD0);
+		else if (location >= 29 && location <= 31)
+			outl(value, ioaddr + 0xD4 + ((location-29)<<2));
+		return;
+	}
+
+	/* Establish sync by sending 32 logic ones. */
+	for (i = 32; i >= 0; i--) {
+		outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
+		mdio_delay();
+		outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
+		mdio_delay();
+	}
+	/* Shift the command bits out. */
+	for (i = 31; i >= 0; i--) {
+		int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
+		outl(MDIO_ENB | dataval, mdio_addr);
+		mdio_delay();
+		outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
+		mdio_delay();
+	}
+	/* Clear out extra bits. */
+	for (i = 2; i > 0; i--) {
+		outl(MDIO_ENB_IN, mdio_addr);
+		mdio_delay();
+		outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+		mdio_delay();
+	}
+}
+
+
+/* Set up the transceiver control registers for the selected media type. */
+void tulip_select_media(struct net_device *dev, int startup)
+{
+	long ioaddr = dev->base_addr;
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	struct mediatable *mtable = tp->mtable;
+	u32 new_csr6;
+	int i;
+
+	if (mtable) {
+		struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index];
+		unsigned char *p = mleaf->leafdata;
+		switch (mleaf->type) {
+		case 0:					/* 21140 non-MII xcvr. */
+			if (tulip_debug > 1)
+				printk(KERN_DEBUG "%s: Using a 21140 non-MII transceiver"
+					   " with control setting %2.2x.\n",
+					   dev->name, p[1]);
+			dev->if_port = p[0];
+			if (startup)
+				outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
+			outl(p[1], ioaddr + CSR12);
+			new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18);
+			break;
+		case 2: case 4: {
+			u16 setup[5];
+			u32 csr13val, csr14val, csr15dir, csr15val;
+			for (i = 0; i < 5; i++)
+				setup[i] = get_u16(&p[i*2 + 1]);
+
+			dev->if_port = p[0] & 15;
+			if (tulip_media_cap[dev->if_port] & MediaAlwaysFD)
+				tp->full_duplex = 1;
+
+			if (startup && mtable->has_reset) {
+				struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
+				unsigned char *rst = rleaf->leafdata;
+				if (tulip_debug > 1)
+					printk(KERN_DEBUG "%s: Resetting the transceiver.\n",
+						   dev->name);
+				for (i = 0; i < rst[0]; i++)
+					outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
+			}
+			if (tulip_debug > 1)
+				printk(KERN_DEBUG "%s: 21143 non-MII %s transceiver control "
+					   "%4.4x/%4.4x.\n",
+					   dev->name, medianame[dev->if_port], setup[0], setup[1]);
+			if (p[0] & 0x40) {	/* SIA (CSR13-15) setup values are provided. */
+				csr13val = setup[0];
+				csr14val = setup[1];
+				csr15dir = (setup[3]<<16) | setup[2];
+				csr15val = (setup[4]<<16) | setup[2];
+				outl(0, ioaddr + CSR13);
+				outl(csr14val, ioaddr + CSR14);
+				outl(csr15dir, ioaddr + CSR15);	/* Direction */
+				outl(csr15val, ioaddr + CSR15);	/* Data */
+				outl(csr13val, ioaddr + CSR13);
+			} else {
+				csr13val = 1;
+				csr14val = 0x0003FF7F;
+				csr15dir = (setup[0]<<16) | 0x0008;
+				csr15val = (setup[1]<<16) | 0x0008;
+				if (dev->if_port <= 4)
+					csr14val = t21142_csr14[dev->if_port];
+				if (startup) {
+					outl(0, ioaddr + CSR13);
+					outl(csr14val, ioaddr + CSR14);
+				}
+				outl(csr15dir, ioaddr + CSR15);	/* Direction */
+				outl(csr15val, ioaddr + CSR15);	/* Data */
+				if (startup) outl(csr13val, ioaddr + CSR13);
+			}
+			if (tulip_debug > 1)
+				printk(KERN_DEBUG "%s:  Setting CSR15 to %8.8x/%8.8x.\n",
+					   dev->name, csr15dir, csr15val);
+			if (mleaf->type == 4)
+				new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
+			else
+				new_csr6 = 0x82420000;
+			break;
+		}
+		case 1: case 3: {
+			int phy_num = p[0];
+			int init_length = p[1];
+			u16 *misc_info;
+			u16 to_advertise;
+
+			dev->if_port = 11;
+			new_csr6 = 0x020E0000;
+			if (mleaf->type == 3) {	/* 21142 */
+				u16 *init_sequence = (u16*)(p+2);
+				u16 *reset_sequence = &((u16*)(p+3))[init_length];
+				int reset_length = p[2 + init_length*2];
+				misc_info = reset_sequence + reset_length;
+				if (startup)
+					for (i = 0; i < reset_length; i++)
+						outl(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
+				for (i = 0; i < init_length; i++)
+					outl(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
+			} else {
+				u8 *init_sequence = p + 2;
+				u8 *reset_sequence = p + 3 + init_length;
+				int reset_length = p[2 + init_length];
+				misc_info = (u16*)(reset_sequence + reset_length);
+				if (startup) {
+					outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
+					for (i = 0; i < reset_length; i++)
+						outl(reset_sequence[i], ioaddr + CSR12);
+				}
+				for (i = 0; i < init_length; i++)
+					outl(init_sequence[i], ioaddr + CSR12);
+			}
+			to_advertise = (get_u16(&misc_info[1]) & tp->to_advertise) | 1;
+			tp->advertising[phy_num] = to_advertise;
+			if (tulip_debug > 1)
+				printk(KERN_DEBUG "%s:  Advertising %4.4x on PHY %d (%d).\n",
+					   dev->name, to_advertise, phy_num, tp->phys[phy_num]);
+			/* Bogus: put in by a committee?  */
+			tulip_mdio_write(dev, tp->phys[phy_num], 4, to_advertise);
+			break;
+		}
+		default:
+			printk(KERN_DEBUG "%s:  Invalid media table selection %d.\n",
+					   dev->name, mleaf->type);
+			new_csr6 = 0x020E0000;
+		}
+		if (tulip_debug > 1)
+			printk(KERN_DEBUG "%s: Using media type %s, CSR12 is %2.2x.\n",
+				   dev->name, medianame[dev->if_port],
+				   inl(ioaddr + CSR12) & 0xff);
+	} else if (tp->chip_id == DC21041) {
+		int port = dev->if_port <= 4 ? dev->if_port : 0;
+		if (tulip_debug > 1)
+			printk(KERN_DEBUG "%s: 21041 using media %s, CSR12 is %4.4x.\n",
+				   dev->name, medianame[port == 3 ? 12: port],
+				   inl(ioaddr + CSR12));
+		outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
+		outl(t21041_csr14[port], ioaddr + CSR14);
+		outl(t21041_csr15[port], ioaddr + CSR15);
+		outl(t21041_csr13[port], ioaddr + CSR13);
+		new_csr6 = 0x80020000;
+	} else if (tp->chip_id == LC82C168) {
+		if (startup && ! tp->medialock)
+			dev->if_port = tp->mii_cnt ? 11 : 0;
+		if (tulip_debug > 1)
+			printk(KERN_DEBUG "%s: PNIC PHY status is %3.3x, media %s.\n",
+				   dev->name, inl(ioaddr + 0xB8), medianame[dev->if_port]);
+		if (tp->mii_cnt) {
+			new_csr6 = 0x810C0000;
+			outl(0x0001, ioaddr + CSR15);
+			outl(0x0201B07A, ioaddr + 0xB8);
+		} else if (startup) {
+			/* Start with 10mbps to do autonegotiation. */
+			outl(0x32, ioaddr + CSR12);
+			new_csr6 = 0x00420000;
+			outl(0x0001B078, ioaddr + 0xB8);
+			outl(0x0201B078, ioaddr + 0xB8);
+		} else if (dev->if_port == 3  ||  dev->if_port == 5) {
+			outl(0x33, ioaddr + CSR12);
+			new_csr6 = 0x01860000;
+			/* Trigger autonegotiation. */
+			outl(startup ? 0x0201F868 : 0x0001F868, ioaddr + 0xB8);
+		} else {
+			outl(0x32, ioaddr + CSR12);
+			new_csr6 = 0x00420000;
+			outl(0x1F078, ioaddr + 0xB8);
+		}
+	} else if (tp->chip_id == DC21040) {					/* 21040 */
+		/* Turn on the xcvr interface. */
+		int csr12 = inl(ioaddr + CSR12);
+		if (tulip_debug > 1)
+			printk(KERN_DEBUG "%s: 21040 media type is %s, CSR12 is %2.2x.\n",
+				   dev->name, medianame[dev->if_port], csr12);
+		if (tulip_media_cap[dev->if_port] & MediaAlwaysFD)
+			tp->full_duplex = 1;
+		new_csr6 = 0x20000;
+		/* Set the full duplux match frame. */
+		outl(FULL_DUPLEX_MAGIC, ioaddr + CSR11);
+		outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
+		if (t21040_csr13[dev->if_port] & 8) {
+			outl(0x0705, ioaddr + CSR14);
+			outl(0x0006, ioaddr + CSR15);
+		} else {
+			outl(0xffff, ioaddr + CSR14);
+			outl(0x0000, ioaddr + CSR15);
+		}
+		outl(0x8f01 | t21040_csr13[dev->if_port], ioaddr + CSR13);
+	} else {					/* Unknown chip type with no media table. */
+		if (tp->default_port == 0)
+			dev->if_port = tp->mii_cnt ? 11 : 3;
+		if (tulip_media_cap[dev->if_port] & MediaIsMII) {
+			new_csr6 = 0x020E0000;
+		} else if (tulip_media_cap[dev->if_port] & MediaIsFx) {
+			new_csr6 = 0x028600000;
+		} else
+			new_csr6 = 0x038600000;
+		if (tulip_debug > 1)
+			printk(KERN_DEBUG "%s: No media description table, assuming "
+				   "%s transceiver, CSR12 %2.2x.\n",
+				   dev->name, medianame[dev->if_port],
+				   inl(ioaddr + CSR12));
+	}
+
+	tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
+	return;
+}
+
+/*
+  Check the MII negotiated duplex, and change the CSR6 setting if
+  required.
+  Return 0 if everything is OK.
+  Return < 0 if the transceiver is missing or has no link beat.
+  */
+int tulip_check_duplex(struct net_device *dev)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	int mii_reg1, mii_reg5, negotiated, duplex;
+
+	if (tp->full_duplex_lock)
+		return 0;
+	mii_reg1 = tulip_mdio_read(dev, tp->phys[0], 1);
+	mii_reg5 = tulip_mdio_read(dev, tp->phys[0], 5);
+	if (tulip_debug > 1)
+		printk(KERN_INFO "%s: MII status %4.4x, Link partner report "
+			   "%4.4x.\n", dev->name, mii_reg1, mii_reg5);
+	if (mii_reg1 == 0xffff)
+		return -2;
+	if ((mii_reg1 & 0x0004) == 0) {
+		int new_reg1 = tulip_mdio_read(dev, tp->phys[0], 1);
+		if ((new_reg1 & 0x0004) == 0) {
+			if (tulip_debug  > 1)
+				printk(KERN_INFO "%s: No link beat on the MII interface,"
+					   " status %4.4x.\n", dev->name, new_reg1);
+			return -1;
+		}
+	}
+	negotiated = mii_reg5 & tp->advertising[0];
+	duplex = ((negotiated & 0x0300) == 0x0100
+			  || (negotiated & 0x00C0) == 0x0040);
+	/* 100baseTx-FD  or  10T-FD, but not 100-HD */
+	if (tp->full_duplex != duplex) {
+		tp->full_duplex = duplex;
+		if (negotiated & 0x038)	/* 100mbps. */
+			tp->csr6 &= ~0x00400000;
+		if (tp->full_duplex) tp->csr6 |= 0x0200;
+		else				 tp->csr6 &= ~0x0200;
+		tulip_outl_CSR6(tp, tp->csr6 | 0x0002);
+		tulip_outl_CSR6(tp, tp->csr6 | 0x2002);
+		if (tulip_debug > 0)
+			printk(KERN_INFO "%s: Setting %s-duplex based on MII"
+				   "#%d link partner capability of %4.4x.\n",
+				   dev->name, tp->full_duplex ? "full" : "half",
+				   tp->phys[0], mii_reg5);
+		return 1;
+	}
+	return 0;
+}
+
diff -u --recursive --new-file v2.3.47/linux/drivers/net/tulip/pnic.c linux/drivers/net/tulip/pnic.c
--- v2.3.47/linux/drivers/net/tulip/pnic.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/tulip/pnic.c	Fri Feb 25 15:16:37 2000
@@ -0,0 +1,146 @@
+/*
+	drivers/net/tulip/pnic.c
+
+	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
+	Copyright 2000  The Linux Kernel Team
+	Written/copyright 1994-1999 by Donald Becker.
+
+	This software may be used and distributed according to the terms
+	of the GNU Public License, incorporated herein by reference.
+
+	Please refer to Documentation/networking/tulip.txt for more
+	information on this driver.
+
+*/
+
+#include <linux/kernel.h>
+#include "tulip.h"
+#include <asm/io.h>
+
+
+void pnic_do_nway(struct net_device *dev)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	u32 phy_reg = inl(ioaddr + 0xB8);
+	u32 new_csr6 = tp->csr6 & ~0x40C40200;
+
+	if (phy_reg & 0x78000000) { /* Ignore baseT4 */
+		if (phy_reg & 0x20000000)		dev->if_port = 5;
+		else if (phy_reg & 0x40000000)	dev->if_port = 3;
+		else if (phy_reg & 0x10000000)	dev->if_port = 4;
+		else if (phy_reg & 0x08000000)	dev->if_port = 0;
+		tp->nwayset = 1;
+		new_csr6 = (dev->if_port & 1) ? 0x01860000 : 0x00420000;
+		outl(0x32 | (dev->if_port & 1), ioaddr + CSR12);
+		if (dev->if_port & 1)
+			outl(0x1F868, ioaddr + 0xB8);
+		if (phy_reg & 0x30000000) {
+			tp->full_duplex = 1;
+			new_csr6 |= 0x00000200;
+		}
+		if (tulip_debug > 1)
+			printk(KERN_DEBUG "%s: PNIC autonegotiated status %8.8x, %s.\n",
+				   dev->name, phy_reg, medianame[dev->if_port]);
+		if (tp->csr6 != new_csr6) {
+			tp->csr6 = new_csr6;
+			/* Restart Tx */
+			tulip_outl_CSR6(tp, tp->csr6 | 0x0002);
+			tulip_outl_CSR6(tp, tp->csr6 | 0x2002);
+			dev->trans_start = jiffies;
+		}
+	}
+}
+
+
+void pnic_lnk_change(struct net_device *dev, int csr5)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int phy_reg = inl(ioaddr + 0xB8);
+
+	if (tulip_debug > 1)
+		printk(KERN_DEBUG "%s: PNIC link changed state %8.8x, CSR5 %8.8x.\n",
+			   dev->name, phy_reg, csr5);
+	if (inl(ioaddr + CSR5) & TPLnkFail) {
+		outl((inl(ioaddr + CSR7) & ~TPLnkFail) | TPLnkPass, ioaddr + CSR7);
+		if (! tp->nwayset  ||  jiffies - dev->trans_start > 1*HZ) {
+			tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff);
+			tulip_outl_CSR6(tp, tp->csr6);
+			outl(0x30, ioaddr + CSR12);
+			outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */
+			dev->trans_start = jiffies;
+		}
+	} else if (inl(ioaddr + CSR5) & TPLnkPass) {
+		pnic_do_nway(dev);
+		outl((inl(ioaddr + CSR7) & ~TPLnkPass) | TPLnkFail, ioaddr + CSR7);
+	}
+}
+
+
+void pnic_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int next_tick = 60*HZ;
+
+	if (tulip_media_cap[dev->if_port] & MediaIsMII) {
+		if (tulip_check_duplex(dev) > 0)
+			next_tick = 3*HZ;
+	} else {
+		int csr12 = inl(ioaddr + CSR12);
+		int new_csr6 = tp->csr6 & ~0x40C40200;
+		int phy_reg = inl(ioaddr + 0xB8);
+		int csr5 = inl(ioaddr + CSR5);
+
+		if (tulip_debug > 1)
+			printk(KERN_DEBUG "%s: PNIC timer PHY status %8.8x, %s "
+				   "CSR5 %8.8x.\n",
+				   dev->name, phy_reg, medianame[dev->if_port], csr5);
+		if (phy_reg & 0x04000000) {	/* Remote link fault */
+			outl(0x0201F078, ioaddr + 0xB8);
+			next_tick = 1*HZ;
+			tp->nwayset = 0;
+		} else if (phy_reg & 0x78000000) { /* Ignore baseT4 */
+			pnic_do_nway(dev);
+			next_tick = 60*HZ;
+		} else if (csr5 & TPLnkFail) { /* 100baseTx link beat */
+			if (tulip_debug > 1)
+				printk(KERN_DEBUG "%s: %s link beat failed, CSR12 %4.4x, "
+					   "CSR5 %8.8x, PHY %3.3x.\n",
+					   dev->name, medianame[dev->if_port], csr12,
+					   inl(ioaddr + CSR5), inl(ioaddr + 0xB8));
+			next_tick = 3*HZ;
+			if (tp->medialock) {
+			} else if (tp->nwayset  &&  (dev->if_port & 1)) {
+				next_tick = 1*HZ;
+			} else if (dev->if_port == 0) {
+				dev->if_port = 3;
+				outl(0x33, ioaddr + CSR12);
+				new_csr6 = 0x01860000;
+				outl(0x1F868, ioaddr + 0xB8);
+			} else {
+				dev->if_port = 0;
+				outl(0x32, ioaddr + CSR12);
+				new_csr6 = 0x00420000;
+				outl(0x1F078, ioaddr + 0xB8);
+			}
+			if (tp->csr6 != new_csr6) {
+				tp->csr6 = new_csr6;
+				/* Restart Tx */
+				tulip_outl_CSR6(tp, tp->csr6 | 0x0002);
+				tulip_outl_CSR6(tp, tp->csr6 | 0x2002);
+				dev->trans_start = jiffies;
+				if (tulip_debug > 1)
+					printk(KERN_INFO "%s: Changing PNIC configuration to %s "
+						   "%s-duplex, CSR6 %8.8x.\n",
+						   dev->name, medianame[dev->if_port],
+						   tp->full_duplex ? "full" : "half", new_csr6);
+			}
+		}
+	}
+	tp->timer.expires = RUN_AT(next_tick);
+	add_timer(&tp->timer);
+}
+
diff -u --recursive --new-file v2.3.47/linux/drivers/net/tulip/timer.c linux/drivers/net/tulip/timer.c
--- v2.3.47/linux/drivers/net/tulip/timer.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/tulip/timer.c	Fri Feb 25 15:16:37 2000
@@ -0,0 +1,208 @@
+/*
+	drivers/net/tulip/timer.c
+
+	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
+	Copyright 2000  The Linux Kernel Team
+	Written/copyright 1994-1999 by Donald Becker.
+
+	This software may be used and distributed according to the terms
+	of the GNU Public License, incorporated herein by reference.
+
+	Please refer to Documentation/networking/tulip.txt for more
+	information on this driver.
+
+*/
+
+#include "tulip.h"
+#include <asm/io.h>
+
+
+void tulip_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	u32 csr12 = inl(ioaddr + CSR12);
+	int next_tick = 2*HZ;
+
+	if (tulip_debug > 2) {
+		printk(KERN_DEBUG "%s: Media selection tick, %s, status %8.8x mode"
+			   " %8.8x SIA %8.8x %8.8x %8.8x %8.8x.\n",
+			   dev->name, medianame[dev->if_port], inl(ioaddr + CSR5),
+			   inl(ioaddr + CSR6), csr12, inl(ioaddr + CSR13),
+			   inl(ioaddr + CSR14), inl(ioaddr + CSR15));
+	}
+	switch (tp->chip_id) {
+	case DC21040:
+		if (!tp->medialock  &&  csr12 & 0x0002) { /* Network error */
+			printk(KERN_INFO "%s: No link beat found.\n",
+				   dev->name);
+			dev->if_port = (dev->if_port == 2 ? 0 : 2);
+			tulip_select_media(dev, 0);
+			dev->trans_start = jiffies;
+		}
+		break;
+	case DC21041:
+		if (tulip_debug > 2)
+			printk(KERN_DEBUG "%s: 21041 media tick  CSR12 %8.8x.\n",
+				   dev->name, csr12);
+		if (tp->medialock) break;
+		switch (dev->if_port) {
+		case 0: case 3: case 4:
+		  if (csr12 & 0x0004) { /*LnkFail */
+			/* 10baseT is dead.  Check for activity on alternate port. */
+			tp->mediasense = 1;
+			if (csr12 & 0x0200)
+				dev->if_port = 2;
+			else
+				dev->if_port = 1;
+			printk(KERN_INFO "%s: No 21041 10baseT link beat, Media switched to %s.\n",
+				   dev->name, medianame[dev->if_port]);
+			outl(0, ioaddr + CSR13); /* Reset */
+			outl(t21041_csr14[dev->if_port], ioaddr + CSR14);
+			outl(t21041_csr15[dev->if_port], ioaddr + CSR15);
+			outl(t21041_csr13[dev->if_port], ioaddr + CSR13);
+			next_tick = 10*HZ;			/* 2.4 sec. */
+		  } else
+			next_tick = 30*HZ;
+		  break;
+		case 1:					/* 10base2 */
+		case 2:					/* AUI */
+			if (csr12 & 0x0100) {
+				next_tick = (30*HZ);			/* 30 sec. */
+				tp->mediasense = 0;
+			} else if ((csr12 & 0x0004) == 0) {
+				printk(KERN_INFO "%s: 21041 media switched to 10baseT.\n",
+					   dev->name);
+				dev->if_port = 0;
+				tulip_select_media(dev, 0);
+				next_tick = (24*HZ)/10;				/* 2.4 sec. */
+			} else if (tp->mediasense || (csr12 & 0x0002)) {
+				dev->if_port = 3 - dev->if_port; /* Swap ports. */
+				tulip_select_media(dev, 0);
+				next_tick = 20*HZ;
+			} else {
+				next_tick = 20*HZ;
+			}
+			break;
+		}
+		break;
+	case DC21140:  case DC21142: case MX98713: case COMPEX9881: default: {
+		struct medialeaf *mleaf;
+		unsigned char *p;
+		if (tp->mtable == NULL) {	/* No EEPROM info, use generic code. */
+			/* Not much that can be done.
+			   Assume this a generic MII or SYM transceiver. */
+			next_tick = 60*HZ;
+			if (tulip_debug > 2)
+				printk(KERN_DEBUG "%s: network media monitor CSR6 %8.8x "
+					   "CSR12 0x%2.2x.\n",
+					   dev->name, inl(ioaddr + CSR6), csr12 & 0xff);
+			break;
+		}
+		mleaf = &tp->mtable->mleaf[tp->cur_index];
+		p = mleaf->leafdata;
+		switch (mleaf->type) {
+		case 0: case 4: {
+			/* Type 0 serial or 4 SYM transceiver.  Check the link beat bit. */
+			int offset = mleaf->type == 4 ? 5 : 2;
+			s8 bitnum = p[offset];
+			if (p[offset+1] & 0x80) {
+				if (tulip_debug > 1)
+					printk(KERN_DEBUG"%s: Transceiver monitor tick "
+						   "CSR12=%#2.2x, no media sense.\n",
+						   dev->name, csr12);
+				if (mleaf->type == 4) {
+					if (mleaf->media == 3 && (csr12 & 0x02))
+						goto select_next_media;
+				}
+				break;
+			}
+			if (tulip_debug > 2)
+				printk(KERN_DEBUG "%s: Transceiver monitor tick: CSR12=%#2.2x"
+					   " bit %d is %d, expecting %d.\n",
+					   dev->name, csr12, (bitnum >> 1) & 7,
+					   (csr12 & (1 << ((bitnum >> 1) & 7))) != 0,
+					   (bitnum >= 0));
+			/* Check that the specified bit has the proper value. */
+			if ((bitnum < 0) !=
+				((csr12 & (1 << ((bitnum >> 1) & 7))) != 0)) {
+				if (tulip_debug > 1)
+					printk(KERN_DEBUG "%s: Link beat detected for %s.\n", dev->name,
+						   medianame[mleaf->media]);
+				if ((p[2] & 0x61) == 0x01)	/* Bogus Znyx board. */
+					goto actually_mii;
+				break;
+			}
+			if (tp->medialock)
+				break;
+	  select_next_media:
+			if (--tp->cur_index < 0) {
+				/* We start again, but should instead look for default. */
+				tp->cur_index = tp->mtable->leafcount - 1;
+			}
+			dev->if_port = tp->mtable->mleaf[tp->cur_index].media;
+			if (tulip_media_cap[dev->if_port] & MediaIsFD)
+				goto select_next_media; /* Skip FD entries. */
+			if (tulip_debug > 1)
+				printk(KERN_DEBUG "%s: No link beat on media %s,"
+					   " trying transceiver type %s.\n",
+					   dev->name, medianame[mleaf->media & 15],
+					   medianame[tp->mtable->mleaf[tp->cur_index].media]);
+			tulip_select_media(dev, 0);
+			/* Restart the transmit process. */
+			tulip_outl_CSR6(tp, tp->csr6 | 0x0002);
+			tulip_outl_CSR6(tp, tp->csr6 | 0x2002);
+			next_tick = (24*HZ)/10;
+			break;
+		}
+		case 1:  case 3:		/* 21140, 21142 MII */
+		actually_mii:
+			tulip_check_duplex(dev);
+			next_tick = 60*HZ;
+			break;
+		case 2:					/* 21142 serial block has no link beat. */
+		default:
+			break;
+		}
+	}
+	break;
+	}
+	tp->timer.expires = RUN_AT(next_tick);
+	add_timer(&tp->timer);
+}
+
+
+void mxic_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int next_tick = 60*HZ;
+
+	if (tulip_debug > 3) {
+		printk(KERN_INFO"%s: MXIC negotiation status %8.8x.\n", dev->name,
+			   inl(ioaddr + CSR12));
+	}
+	if (next_tick) {
+		tp->timer.expires = RUN_AT(next_tick);
+		add_timer(&tp->timer);
+	}
+}
+
+
+void comet_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int next_tick = 60*HZ;
+
+	if (tulip_debug > 1)
+		printk(KERN_DEBUG "%s: Comet link status %4.4x partner capability "
+			   "%4.4x.\n",
+			   dev->name, inl(ioaddr + 0xB8), inl(ioaddr + 0xC8));
+	tp->timer.expires = RUN_AT(next_tick);
+	add_timer(&tp->timer);
+}
+
diff -u --recursive --new-file v2.3.47/linux/drivers/net/tulip/tulip.h linux/drivers/net/tulip/tulip.h
--- v2.3.47/linux/drivers/net/tulip/tulip.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/tulip/tulip.h	Fri Feb 25 15:16:37 2000
@@ -0,0 +1,342 @@
+/*
+	drivers/net/tulip/tulip.h
+
+	Copyright 2000  The Linux Kernel Team
+	Written/copyright 1994-1999 by Donald Becker.
+
+	This software may be used and distributed according to the terms
+	of the GNU Public License, incorporated herein by reference.
+
+*/
+
+#ifndef __NET_TULIP_H__
+#define __NET_TULIP_H__
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/netdevice.h>
+#include <linux/timer.h>
+
+
+struct tulip_chip_table {
+	char *chip_name;
+	int io_size;
+	int valid_intrs;	/* CSR7 interrupt enable settings */
+	int flags;
+	void (*media_timer) (unsigned long data);
+};
+
+
+enum tbl_flag {
+	HAS_MII = 1,
+	HAS_MEDIA_TABLE = 2,
+	CSR12_IN_SROM = 4,
+	ALWAYS_CHECK_MII = 8,
+	HAS_ACPI = 0x10,
+	MC_HASH_ONLY = 0x20,	/* Hash-only multicast filter. */
+	HAS_PNICNWAY = 0x80,
+	HAS_NWAY143 = 0x40,	/* Uses internal NWay xcvr. */
+	HAS_8023X = 0x100,
+};
+
+
+/* chip types.  careful!  order is VERY IMPORTANT here, as these
+ * are used throughout the driver as indices into arrays */
+/* Note 21142 == 21143. */
+enum chips {
+	DC21040 = 0,
+	DC21041 = 1,
+	DC21140 = 2,
+	DC21142 = 3, DC21143 = 3,
+	LC82C168,
+	NGMC169,
+	MX98713,
+	MX98715,
+	MX98725,
+	AX88140,
+	PNIC2,
+	COMET,
+	COMPEX9881,
+	I21145,
+	X3201_3,
+};
+
+
+enum MediaIs {
+	MediaIsFD = 1,
+	MediaAlwaysFD = 2,
+	MediaIsMII = 4,
+	MediaIsFx = 8,
+	MediaIs100 = 16
+};
+
+
+/* Offsets to the Command and Status Registers, "CSRs".  All accesses
+   must be longword instructions and quadword aligned. */
+enum tulip_offsets {
+	CSR0 = 0,
+	CSR1 = 0x08,
+	CSR2 = 0x10,
+	CSR3 = 0x18,
+	CSR4 = 0x20,
+	CSR5 = 0x28,
+	CSR6 = 0x30,
+	CSR7 = 0x38,
+	CSR8 = 0x40,
+	CSR9 = 0x48,
+	CSR10 = 0x50,
+	CSR11 = 0x58,
+	CSR12 = 0x60,
+	CSR13 = 0x68,
+	CSR14 = 0x70,
+	CSR15 = 0x78
+};
+
+
+/* The bits in the CSR5 status registers, mostly interrupt sources. */
+enum status_bits {
+	TimerInt = 0x800,
+	SytemError = 0x2000,
+	TPLnkFail = 0x1000,
+	TPLnkPass = 0x10,
+	NormalIntr = 0x10000,
+	AbnormalIntr = 0x8000,
+	RxJabber = 0x200,
+	RxDied = 0x100,
+	RxNoBuf = 0x80,
+	RxIntr = 0x40,
+	TxFIFOUnderflow = 0x20,
+	TxJabber = 0x08,
+	TxNoBuf = 0x04,
+	TxDied = 0x02,
+	TxIntr = 0x01,
+};
+
+
+/* The Tulip Rx and Tx buffer descriptors. */
+struct tulip_rx_desc {
+	s32 status;
+	s32 length;
+	u32 buffer1;
+	u32 buffer2;
+};
+
+
+struct tulip_tx_desc {
+	s32 status;
+	s32 length;
+	u32 buffer1;
+	u32 buffer2;		/* We use only buffer 1.  */
+};
+
+
+enum desc_status_bits {
+	DescOwned = 0x80000000,
+	RxDescFatalErr = 0x8000,
+	RxWholePkt = 0x0300,
+};
+
+
+/* Keep the ring sizes a power of two for efficiency.
+   Making the Tx ring too large decreases the effectiveness of channel
+   bonding and packet priority.
+   There are no ill effects from too-large receive rings. */
+#define TX_RING_SIZE	16
+#define RX_RING_SIZE	32
+
+
+#define PKT_BUF_SZ		1536	/* Size of each temporary Rx buffer. */
+
+
+/* Ring-wrap flag in length field, use for last ring entry.
+	0x01000000 means chain on buffer2 address,
+	0x02000000 means use the ring start address in CSR2/3.
+   Note: Some work-alike chips do not function correctly in chained mode.
+   The ASIX chip works only in chained mode.
+   Thus we indicates ring mode, but always write the 'next' field for
+   chained mode as well.
+*/
+#define DESC_RING_WRAP 0x02000000
+
+
+/*  EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK	0x02	/* EEPROM shift clock. */
+#define EE_CS			0x01	/* EEPROM chip select. */
+#define EE_DATA_WRITE	0x04	/* Data from the Tulip to EEPROM. */
+#define EE_WRITE_0		0x01
+#define EE_WRITE_1		0x05
+#define EE_DATA_READ	0x08	/* Data from the EEPROM chip. */
+#define EE_ENB			(0x4800 | EE_CS)
+
+/* Delay between EEPROM clock transitions.
+   Even at 33Mhz current PCI implementations don't overrun the EEPROM clock.
+   We add a bus turn-around to insure that this remains true. */
+#define eeprom_delay()	inl(ee_addr)
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_READ_CMD		(6)
+
+#define EEPROM_SIZE 128 	/* 2 << EEPROM_ADDRLEN */
+
+
+/* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
+   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
+   "overclocking" issues or future 66Mhz PCI. */
+#define mdio_delay() inl(mdio_addr)
+
+/* Read and write the MII registers using software-generated serial
+   MDIO protocol.  It is just different enough from the EEPROM protocol
+   to not share code.  The maxium data clock rate is 2.5 Mhz. */
+#define MDIO_SHIFT_CLK	0x10000
+#define MDIO_DATA_WRITE0 0x00000
+#define MDIO_DATA_WRITE1 0x20000
+#define MDIO_ENB		0x00000		/* Ignore the 0x02000 databook setting. */
+#define MDIO_ENB_IN		0x40000
+#define MDIO_DATA_READ	0x80000
+
+
+#define RUN_AT(x) (jiffies + (x))
+
+
+#if defined(__i386__)			/* AKA get_unaligned() */
+#define get_u16(ptr) (*(u16 *)(ptr))
+#else
+#define get_u16(ptr) (((u8*)(ptr))[0] + (((u8*)(ptr))[1]<<8))
+#endif
+
+
+/* Condensed operations for readability. */
+#define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
+#define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
+
+
+struct medialeaf {
+	u8 type;
+	u8 media;
+	unsigned char *leafdata;
+};
+
+
+struct mediatable {
+	u16 defaultmedia;
+	u8 leafcount;
+	u8 csr12dir;		/* General purpose pin directions. */
+	unsigned has_mii:1;
+	unsigned has_nonmii:1;
+	unsigned has_reset:6;
+	u32 csr15dir;
+	u32 csr15val;		/* 21143 NWay setting. */
+	struct medialeaf mleaf[0];
+};
+
+
+struct mediainfo {
+	struct mediainfo *next;
+	int info_type;
+	int index;
+	unsigned char *info;
+};
+
+
+struct tulip_private {
+	const char *product_name;
+	struct net_device *next_module;
+	struct tulip_rx_desc rx_ring[RX_RING_SIZE];
+	struct tulip_tx_desc tx_ring[TX_RING_SIZE];
+	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
+	struct sk_buff *tx_skbuff[TX_RING_SIZE];
+	/* The addresses of receive-in-place skbuffs. */
+	struct sk_buff *rx_skbuff[RX_RING_SIZE];
+	char *rx_buffs;		/* Address of temporary Rx buffers. */
+	u16 setup_frame[96];	/* Pseudo-Tx frame to init address table. */
+	int chip_id;
+	int revision;
+	int flags;
+	struct net_device_stats stats;
+	struct timer_list timer;	/* Media selection timer. */
+	spinlock_t lock;
+	unsigned int cur_rx, cur_tx;	/* The next free ring entry */
+	unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
+	unsigned int tx_full:1;	/* The Tx queue is full. */
+	unsigned int full_duplex:1;	/* Full-duplex operation requested. */
+	unsigned int full_duplex_lock:1;
+	unsigned int fake_addr:1;	/* Multiport board faked address. */
+	unsigned int default_port:4;	/* Last dev->if_port value. */
+	unsigned int media2:4;	/* Secondary monitored media port. */
+	unsigned int medialock:1;	/* Don't sense media type. */
+	unsigned int mediasense:1;	/* Media sensing in progress. */
+	unsigned int nway:1, nwayset:1;		/* 21143 internal NWay. */
+	unsigned int csr0;	/* CSR0 setting. */
+	unsigned int csr6;	/* Current CSR6 control settings. */
+	unsigned char eeprom[EEPROM_SIZE];	/* Serial EEPROM contents. */
+	void (*link_change) (struct net_device * dev, int csr5);
+	u16 to_advertise;	/* NWay capabilities advertised.  */
+	u16 lpar;		/* 21143 Link partner ability. */
+	u16 advertising[4];
+	signed char phys[4], mii_cnt;	/* MII device addresses. */
+	struct mediatable *mtable;
+	int cur_index;		/* Current media index. */
+	int saved_if_port;
+	struct pci_dev *pdev;
+	int ttimer;
+	int susp_rx;
+	unsigned long nir;
+	unsigned long base_addr;
+	int pad0, pad1;		/* Used for 8-byte alignment */
+};
+
+
+struct eeprom_fixup {
+	char *name;
+	unsigned char addr0;
+	unsigned char addr1;
+	unsigned char addr2;
+	u16 newtable[32];	/* Max length below. */
+};
+
+
+/* 21142.c */
+extern u16 t21142_csr14[];
+void t21142_timer(unsigned long data);
+void t21142_start_nway(struct net_device *dev);
+void t21142_lnk_change(struct net_device *dev, int csr5);
+
+/* eeprom.c */
+void tulip_parse_eeprom(struct net_device *dev);
+int tulip_read_eeprom(long ioaddr, int location, int addr_len);
+
+/* interrupt.c */
+extern int tulip_max_interrupt_work;
+extern int tulip_rx_copybreak;
+void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+
+/* media.c */
+int tulip_mdio_read(struct net_device *dev, int phy_id, int location);
+void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int value);
+void tulip_select_media(struct net_device *dev, int startup);
+int tulip_check_duplex(struct net_device *dev);
+
+/* pnic.c */
+void pnic_do_nway(struct net_device *dev);
+void pnic_lnk_change(struct net_device *dev, int csr5);
+void pnic_timer(unsigned long data);
+
+/* timer.c */
+void tulip_timer(unsigned long data);
+void mxic_timer(unsigned long data);
+void comet_timer(unsigned long data);
+
+/* tulip_core.c */
+extern int tulip_debug;
+extern const char * const medianame[];
+extern const char tulip_media_cap[];
+extern struct tulip_chip_table tulip_tbl[];
+extern u8 t21040_csr13[];
+extern u16 t21041_csr13[];
+extern u16 t21041_csr14[];
+extern u16 t21041_csr15[];
+void tulip_outl_CSR6 (struct tulip_private *tp, u32 newcsr6);
+
+
+#endif /* __NET_TULIP_H__ */
diff -u --recursive --new-file v2.3.47/linux/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c
--- v2.3.47/linux/drivers/net/tulip/tulip_core.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/tulip/tulip_core.c	Fri Feb 25 17:38:43 2000
@@ -0,0 +1,1391 @@
+/* tulip_core.c: A DEC 21040-family ethernet driver for Linux. */
+
+/*
+	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
+	Copyright 2000  The Linux Kernel Team
+	Written/copyright 1994-1999 by Donald Becker.
+
+	This software may be used and distributed according to the terms
+	of the GNU Public License, incorporated herein by reference.
+	
+	Please read Documentation/networking/tulip.txt for more
+	information.
+
+	For this specific driver variant please use linux-kernel for 
+	bug reports.
+
+	Additional information available at
+	http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html
+
+*/
+
+static const char version[] = "Linux Tulip driver version 0.9.3 (Feb 23, 2000)\n";
+
+#include <linux/module.h>
+#include "tulip.h"
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/unaligned.h>
+
+
+/* A few user-configurable values. */
+
+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+static int max_interrupt_work = 25;
+
+#define MAX_UNITS 8
+/* Used to pass the full-duplex flag, etc. */
+static int full_duplex[MAX_UNITS] = {0, };
+static int options[MAX_UNITS] = {0, };
+static int mtu[MAX_UNITS] = {0, };			/* Jumbo MTU for interfaces. */
+
+/*  The possible media types that can be set in options[] are: */
+const char * const medianame[] = {
+	"10baseT", "10base2", "AUI", "100baseTx",
+	"10baseT-FD", "100baseTx-FD", "100baseT4", "100baseFx",
+	"100baseFx-FD", "MII 10baseT", "MII 10baseT-FD", "MII",
+	"10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FD", "MII 100baseT4",
+};
+
+/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
+#ifdef __alpha__
+static int rx_copybreak = 1518;
+#else
+static int rx_copybreak = 100;
+#endif
+
+/*
+  Set the bus performance register.
+	Typical: Set 16 longword cache alignment, no burst limit.
+	Cache alignment bits 15:14	     Burst length 13:8
+		0000	No alignment  0x00000000 unlimited		0800 8 longwords
+		4000	8  longwords		0100 1 longword		1000 16 longwords
+		8000	16 longwords		0200 2 longwords	2000 32 longwords
+		C000	32  longwords		0400 4 longwords
+	Warning: many older 486 systems are broken and require setting 0x00A04800
+	   8 longword cache alignment, 8 longword burst.
+	ToDo: Non-Intel setting could be better.
+*/
+
+#if defined(__alpha__)
+static int csr0 = 0x01A00000 | 0xE000;
+#elif defined(__i386__) || defined(__powerpc__) || defined(__sparc__)
+static int csr0 = 0x01A00000 | 0x8000;
+#else
+#warning Processor architecture undefined!
+static int csr0 = 0x00A00000 | 0x4800;
+#endif
+
+/* Operational parameters that usually are not changed. */
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  (4*HZ)
+
+
+/* Kernel compatibility defines, some common to David Hind's PCMCIA package.
+   This is only in the support-all-kernels source code. */
+
+MODULE_AUTHOR("The Linux Kernel Team");
+MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver");
+MODULE_PARM(tulip_debug, "i");
+MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(csr0, "i");
+MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+
+#define TULIP_MODULE_NAME "tulip"
+#define PFX TULIP_MODULE_NAME ": "
+
+#ifdef TULIP_DEBUG
+int tulip_debug = TULIP_DEBUG;
+#else
+int tulip_debug = 1;
+#endif
+
+
+
+/*
+ * This table use during operation for capabilities and media timer.
+ *
+ * It is indexed via the values in 'enum chips'
+ */
+
+struct tulip_chip_table tulip_tbl[] = {
+  { "Digital DC21040 Tulip", 128, 0x0001ebef, 0, tulip_timer },
+  { "Digital DC21041 Tulip", 128, 0x0001ebff, HAS_MEDIA_TABLE, tulip_timer },
+  { "Digital DS21140 Tulip", 128, 0x0001ebef,
+	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, tulip_timer },
+  { "Digital DS21143 Tulip", 128, 0x0801fbff,
+	HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY143,
+	t21142_timer },
+  { "Lite-On 82c168 PNIC", 256, 0x0001ebef,
+	HAS_MII | HAS_PNICNWAY, pnic_timer },
+  { "NETGEAR NGMC169 MAC", 256, 0x0001ebef,
+	HAS_MII | HAS_PNICNWAY, pnic_timer },
+  { "Macronix 98713 PMAC", 128, 0x0001ebef,
+	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer },
+  { "Macronix 98715 PMAC", 256, 0x0001ebef,
+	HAS_MEDIA_TABLE, mxic_timer },
+  { "Macronix 98725 PMAC", 256, 0x0001ebef,
+	HAS_MEDIA_TABLE, mxic_timer },
+  { "ASIX AX88140", 128, 0x0001fbff,
+	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY, tulip_timer },
+  { "Lite-On PNIC-II", 256, 0x0801fbff,
+	HAS_MII | HAS_NWAY143 | HAS_8023X, t21142_timer },
+  { "ADMtek Comet", 256, 0x0001abef,
+	MC_HASH_ONLY, comet_timer },
+  { "Compex 9881 PMAC", 128, 0x0001ebef,
+	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer },
+  { "Intel DS21145 Tulip", 128, 0x0801fbff,
+	HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_NWAY143,
+	t21142_timer },
+  { "Xircom tulip work-alike", 128, 0x0801fbff,
+	HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY143,
+	t21142_timer },
+  {0},
+};
+
+
+static struct pci_device_id tulip_pci_tbl[] __devinitdata = {
+	{ 0x1011, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21040 },
+	{ 0x1011, 0x0014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21041 },
+	{ 0x1011, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21140 },
+	{ 0x1011, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21143 },
+	{ 0x11AD, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, LC82C168 },
+	{ 0x1385, 0xf004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NGMC169 },
+	{ 0x10d9, 0x0512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98713 },
+	{ 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
+	{ 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98725 },
+	{ 0x125B, 0x1400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AX88140 },
+	{ 0x11AD, 0xc115, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PNIC2 },
+	{ 0x1317, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+	{ 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 },
+	{ 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 },
+	{ 0x115d, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, X3201_3 },
+	{0},
+};
+MODULE_DEVICE_TABLE(pci,tulip_pci_tbl);
+
+
+/* A full-duplex map for media types. */
+const char tulip_media_cap[] =
+{0,0,0,16,  3,19,16,24,  27,4,7,5, 0,20,23,20 };
+u8 t21040_csr13[] = {2,0x0C,8,4,  4,0,0,0, 0,0,0,0, 4,0,0,0};
+
+/* 21041 transceiver register settings: 10-T, 10-2, AUI, 10-T, 10T-FD*/
+u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, };
+u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
+u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
+
+
+static void tulip_tx_timeout(struct net_device *dev);
+static void tulip_init_ring(struct net_device *dev);
+static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static int tulip_open(struct net_device *dev);
+static int tulip_close(struct net_device *dev);
+static void tulip_up(struct net_device *dev);
+static void tulip_down(struct net_device *dev);
+static struct net_device_stats *tulip_get_stats(struct net_device *dev);
+static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static void set_rx_mode(struct net_device *dev);
+
+
+/* The Xircom cards are picky about when certain bits in CSR6 can be
+   manipulated.  Keith Owens <kaos@ocs.com.au>. */
+
+void tulip_outl_CSR6 (struct tulip_private *tp, u32 newcsr6)
+{
+	long ioaddr = tp->base_addr;
+	const int strict_bits = 0x0060e202;
+	int csr5, csr5_22_20, csr5_19_17, currcsr6, attempts = 200;
+
+	/* common path */
+	if (tp->chip_id != X3201_3) {
+		outl (newcsr6, ioaddr + CSR6);
+		return;
+	}
+
+	newcsr6 &= 0x726cfeca;	/* mask out the reserved CSR6 bits that always */
+	/* read 0 on the Xircom cards */
+	newcsr6 |= 0x320c0000;	/* or in the reserved bits that always read 1 */
+	currcsr6 = inl (ioaddr + CSR6);
+	if (((newcsr6 & strict_bits) == (currcsr6 & strict_bits)) ||
+	    ((currcsr6 & ~0x2002) == 0))
+		goto out_write;
+
+	/* make sure the transmitter and receiver are stopped first */
+	currcsr6 &= ~0x2002;
+	while (1) {
+		csr5 = inl (ioaddr + CSR5);
+		if (csr5 == 0xffffffff)
+			break;	/* cannot read csr5, card removed? */
+		csr5_22_20 = csr5 & 0x700000;
+		csr5_19_17 = csr5 & 0x0e0000;
+		if ((csr5_22_20 == 0 || csr5_22_20 == 0x600000) &&
+		    (csr5_19_17 == 0 || csr5_19_17 == 0x80000 || csr5_19_17 == 0xc0000))
+			break;	/* both are stopped or suspended */
+		if (!--attempts) {
+			printk (KERN_INFO "tulip.c: tulip_outl_CSR6 too many attempts,"
+				"csr5=0x%08x\n", csr5);
+			goto out_write;
+		}
+		outl (currcsr6, ioaddr + CSR6);
+		udelay (1);
+	}
+
+out_write:
+	/* now it is safe to change csr6 */
+	outl (newcsr6, ioaddr + CSR6);
+}
+
+
+static void tulip_up(struct net_device *dev)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int next_tick = 3*HZ;
+	int i;
+
+	/* Wake the chip from sleep/snooze mode. */
+	if (tp->flags & HAS_ACPI)
+		pci_write_config_dword(tp->pdev, 0x40, 0);
+
+	/* On some chip revs we must set the MII/SYM port before the reset!? */
+	if (tp->mii_cnt  ||  (tp->mtable  &&  tp->mtable->has_mii))
+		tulip_outl_CSR6 (tp, 0x00040000);
+
+	/* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
+	outl(0x00000001, ioaddr + CSR0);
+
+	/* Deassert reset.
+	   Wait the specified 50 PCI cycles after a reset by initializing
+	   Tx and Rx queues and the address filter list. */
+	outl(tp->csr0, ioaddr + CSR0);
+
+	if (tulip_debug > 1)
+		printk(KERN_DEBUG "%s: tulip_up(), irq==%d.\n", dev->name, dev->irq);
+
+	if (tp->flags & MC_HASH_ONLY) {
+		u32 addr_low = cpu_to_le32(get_unaligned((u32 *)dev->dev_addr));
+		u32 addr_high = cpu_to_le32(get_unaligned((u16 *)(dev->dev_addr+4)));
+		if (tp->chip_id == AX88140) {
+			outl(0, ioaddr + CSR13);
+			outl(addr_low,  ioaddr + CSR14);
+			outl(1, ioaddr + CSR13);
+			outl(addr_high, ioaddr + CSR14);
+		} else if (tp->chip_id == COMET) {
+			outl(addr_low,  ioaddr + 0xA4);
+			outl(addr_high, ioaddr + 0xA8);
+			outl(0, ioaddr + 0xAC);
+			outl(0, ioaddr + 0xB0);
+		}
+	} else {
+		/* This is set_rx_mode(), but without starting the transmitter. */
+		u16 *eaddrs = (u16 *)dev->dev_addr;
+		u16 *setup_frm = &tp->setup_frame[15*6];
+
+		/* 21140 bug: you must add the broadcast address. */
+		memset(tp->setup_frame, 0xff, sizeof(tp->setup_frame));
+		/* Fill the final entry of the table with our physical address. */
+		*setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
+		*setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
+		*setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
+		/* Put the setup frame on the Tx list. */
+		tp->tx_ring[0].length = cpu_to_le32(0x08000000 | 192);
+		tp->tx_ring[0].buffer1 = virt_to_le32desc(tp->setup_frame);
+		tp->tx_ring[0].status = cpu_to_le32(DescOwned);
+
+		tp->cur_tx++;
+	}
+
+	outl(virt_to_bus(tp->rx_ring), ioaddr + CSR3);
+	outl(virt_to_bus(tp->tx_ring), ioaddr + CSR4);
+
+	tp->saved_if_port = dev->if_port;
+	if (dev->if_port == 0)
+		dev->if_port = tp->default_port;
+
+	/* Allow selecting a default media. */
+	i = 0;
+	if (tp->mtable == NULL)
+		goto media_picked;
+	if (dev->if_port) {
+		int looking_for = tulip_media_cap[dev->if_port] & MediaIsMII ? 11 :
+			(dev->if_port == 12 ? 0 : dev->if_port);
+		for (i = 0; i < tp->mtable->leafcount; i++)
+			if (tp->mtable->mleaf[i].media == looking_for) {
+				printk(KERN_INFO "%s: Using user-specified media %s.\n",
+					   dev->name, medianame[dev->if_port]);
+				goto media_picked;
+			}
+	}
+	if ((tp->mtable->defaultmedia & 0x0800) == 0) {
+		int looking_for = tp->mtable->defaultmedia & 15;
+		for (i = 0; i < tp->mtable->leafcount; i++)
+			if (tp->mtable->mleaf[i].media == looking_for) {
+				printk(KERN_INFO "%s: Using EEPROM-set media %s.\n",
+					   dev->name, medianame[looking_for]);
+				goto media_picked;
+			}
+	}
+	/* Start sensing first non-full-duplex media. */
+	for (i = tp->mtable->leafcount - 1;
+		 (tulip_media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--)
+		;
+media_picked:
+
+	tp->csr6 = 0;
+	tp->cur_index = i;
+	tp->nwayset = 0;
+	if (dev->if_port == 0  && tp->chip_id == DC21041) {
+		tp->nway = 1;
+	}
+	if (dev->if_port == 0  &&  tp->chip_id == DC21142) {
+		if (tp->mii_cnt) {
+			tulip_select_media(dev, 1);
+			if (tulip_debug > 1)
+				printk(KERN_INFO "%s: Using MII transceiver %d, status "
+					   "%4.4x.\n",
+					   dev->name, tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1));
+			tulip_outl_CSR6(tp, 0x82020000);
+			tp->csr6 = 0x820E0000;
+			dev->if_port = 11;
+			outl(0x0000, ioaddr + CSR13);
+			outl(0x0000, ioaddr + CSR14);
+		} else
+			t21142_start_nway(dev);
+	} else if (tp->chip_id == PNIC2) {
+		t21142_start_nway(dev);
+	} else if (tp->chip_id == LC82C168  &&  ! tp->medialock) {
+		if (tp->mii_cnt) {
+			dev->if_port = 11;
+			tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0);
+			outl(0x0001, ioaddr + CSR15);
+		} else if (inl(ioaddr + CSR5) & TPLnkPass)
+			pnic_do_nway(dev);
+		else {
+			/* Start with 10mbps to do autonegotiation. */
+			outl(0x32, ioaddr + CSR12);
+			tp->csr6 = 0x00420000;
+			outl(0x0001B078, ioaddr + 0xB8);
+			outl(0x0201B078, ioaddr + 0xB8);
+			next_tick = 1*HZ;
+		}
+	} else if ((tp->chip_id == MX98713 || tp->chip_id == COMPEX9881)
+			   && ! tp->medialock) {
+		dev->if_port = 0;
+		tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0);
+		outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
+	} else if (tp->chip_id == MX98715 || tp->chip_id == MX98725) {
+		/* Provided by BOLO, Macronix - 12/10/1998. */
+		dev->if_port = 0;
+		tp->csr6 = 0x01a80200;
+		outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
+		outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0);
+	} else if (tp->chip_id == DC21143  &&
+			   tulip_media_cap[dev->if_port] & MediaIsMII) {
+		/* We must reset the media CSRs when we force-select MII mode. */
+		outl(0x0000, ioaddr + CSR13);
+		outl(0x0000, ioaddr + CSR14);
+		outl(0x0008, ioaddr + CSR15);
+	} else if (tp->chip_id == COMET) {
+		dev->if_port = 0;
+		tp->csr6 = 0x00040000;
+	} else if (tp->chip_id == AX88140) {
+		tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100;
+	} else
+		tulip_select_media(dev, 1);
+
+	/* Start the chip's Tx to process setup frame. */
+	tulip_outl_CSR6(tp, tp->csr6);
+	tulip_outl_CSR6(tp, tp->csr6 | 0x2000);
+
+	/* Enable interrupts by setting the interrupt mask. */
+	outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5);
+	outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
+	tulip_outl_CSR6(tp, tp->csr6 | 0x2002);
+	outl(0, ioaddr + CSR2);		/* Rx poll demand */
+
+	if (tulip_debug > 2) {
+		printk(KERN_DEBUG "%s: Done tulip_open(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n",
+			   dev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR5),
+			   inl(ioaddr + CSR6));
+	}
+	/* Set the timer to switch to check for link beat and perhaps switch
+	   to an alternate media type. */
+	init_timer(&tp->timer);
+	tp->timer.expires = RUN_AT(next_tick);
+	tp->timer.data = (unsigned long)dev;
+	tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
+	add_timer(&tp->timer);
+
+	netif_device_attach(dev);
+}
+
+
+static int
+tulip_open(struct net_device *dev)
+{
+	MOD_INC_USE_COUNT;
+	
+	if (request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev)) {
+		MOD_DEC_USE_COUNT;
+		return -EBUSY;
+	}
+
+	tulip_init_ring (dev);
+	
+	tulip_up (dev);
+	
+	return 0;
+}
+
+
+static void tulip_tx_timeout(struct net_device *dev)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	unsigned long flags;
+	
+	spin_lock_irqsave (&tp->lock, flags);
+
+	if (tulip_media_cap[dev->if_port] & MediaIsMII) {
+		/* Do nothing -- the media monitor should handle this. */
+		if (tulip_debug > 1)
+			printk(KERN_WARNING "%s: Transmit timeout using MII device.\n",
+				   dev->name);
+	} else if (tp->chip_id == DC21040) {
+		if ( !tp->medialock  &&  inl(ioaddr + CSR12) & 0x0002) {
+			dev->if_port = (dev->if_port == 2 ? 0 : 2);
+			printk(KERN_INFO "%s: 21040 transmit timed out, switching to "
+				   "%s.\n",
+				   dev->name, medianame[dev->if_port]);
+			tulip_select_media(dev, 0);
+		}
+		goto out;
+	} else if (tp->chip_id == DC21041) {
+		int csr12 = inl(ioaddr + CSR12);
+
+		printk(KERN_WARNING "%s: 21041 transmit timed out, status %8.8x, "
+			   "CSR12 %8.8x, CSR13 %8.8x, CSR14 %8.8x, resetting...\n",
+			   dev->name, inl(ioaddr + CSR5), csr12,
+			   inl(ioaddr + CSR13), inl(ioaddr + CSR14));
+		tp->mediasense = 1;
+		if ( ! tp->medialock) {
+			if (dev->if_port == 1 || dev->if_port == 2)
+				if (csr12 & 0x0004) {
+					dev->if_port = 2 - dev->if_port;
+				} else
+					dev->if_port = 0;
+			else
+				dev->if_port = 1;
+			tulip_select_media(dev, 0);
+		}
+	} else if (tp->chip_id == DC21140 || tp->chip_id == DC21142
+			   || tp->chip_id == MX98713 || tp->chip_id == COMPEX9881) {
+		printk(KERN_WARNING "%s: 21140 transmit timed out, status %8.8x, "
+			   "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
+			   dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR12),
+			   inl(ioaddr + CSR13), inl(ioaddr + CSR14), inl(ioaddr + CSR15));
+		if ( ! tp->medialock  &&  tp->mtable) {
+			do
+				--tp->cur_index;
+			while (tp->cur_index >= 0
+				   && (tulip_media_cap[tp->mtable->mleaf[tp->cur_index].media]
+					   & MediaIsFD));
+			if (--tp->cur_index < 0) {
+				/* We start again, but should instead look for default. */
+				tp->cur_index = tp->mtable->leafcount - 1;
+			}
+			tulip_select_media(dev, 0);
+			printk(KERN_WARNING "%s: transmit timed out, switching to %s "
+				   "media.\n", dev->name, medianame[dev->if_port]);
+		}
+	} else {
+		printk(KERN_WARNING "%s: Transmit timed out, status %8.8x, CSR12 "
+			   "%8.8x, resetting...\n",
+			   dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR12));
+		dev->if_port = 0;
+	}
+
+#if defined(way_too_many_messages)
+	if (tulip_debug > 3) {
+		int i;
+		for (i = 0; i < RX_RING_SIZE; i++) {
+			u8 *buf = (u8 *)(tp->rx_ring[i].buffer1);
+			int j;
+			printk(KERN_DEBUG "%2d: %8.8x %8.8x %8.8x %8.8x  "
+				   "%2.2x %2.2x %2.2x.\n",
+				   i, (unsigned int)tp->rx_ring[i].status,
+				   (unsigned int)tp->rx_ring[i].length,
+				   (unsigned int)tp->rx_ring[i].buffer1,
+				   (unsigned int)tp->rx_ring[i].buffer2,
+				   buf[0], buf[1], buf[2]);
+			for (j = 0; buf[j] != 0xee && j < 1600; j++)
+				if (j < 100) printk(" %2.2x", buf[j]);
+			printk(" j=%d.\n", j);
+		}
+		printk(KERN_DEBUG "  Rx ring %8.8x: ", (int)tp->rx_ring);
+		for (i = 0; i < RX_RING_SIZE; i++)
+			printk(" %8.8x", (unsigned int)tp->rx_ring[i].status);
+		printk("\n" KERN_DEBUG "  Tx ring %8.8x: ", (int)tp->tx_ring);
+		for (i = 0; i < TX_RING_SIZE; i++)
+			printk(" %8.8x", (unsigned int)tp->tx_ring[i].status);
+		printk("\n");
+	}
+#endif
+
+	/* Stop and restart the chip's Tx processes . */
+	tulip_outl_CSR6(tp, tp->csr6 | 0x0002);
+	tulip_outl_CSR6(tp, tp->csr6 | 0x2002);
+	/* Trigger an immediate transmit demand. */
+	outl(0, ioaddr + CSR1);
+
+	tp->stats.tx_errors++;
+
+out:
+	dev->trans_start = jiffies;
+	netif_start_queue (dev);
+	spin_unlock_irqrestore (&tp->lock, flags);
+}
+
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void tulip_init_ring(struct net_device *dev)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	int i;
+
+	tp->tx_full = 0;
+	tp->cur_rx = tp->cur_tx = 0;
+	tp->dirty_rx = tp->dirty_tx = 0;
+	tp->susp_rx = 0;
+	tp->ttimer = 0;
+	tp->nir = 0;
+
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		tp->rx_ring[i].status = 0x00000000;
+		tp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ);
+		tp->rx_ring[i].buffer2 = virt_to_le32desc(&tp->rx_ring[i+1]);
+		tp->rx_skbuff[i] = NULL;
+	}
+	/* Mark the last entry as wrapping the ring. */
+	tp->rx_ring[i-1].length = cpu_to_le32(PKT_BUF_SZ | DESC_RING_WRAP);
+	tp->rx_ring[i-1].buffer2 = virt_to_le32desc(&tp->rx_ring[0]);
+
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		/* Note the receive buffer must be longword aligned.
+		   dev_alloc_skb() provides 16 byte alignment.  But do *not*
+		   use skb_reserve() to align the IP header! */
+		struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ);
+		tp->rx_skbuff[i] = skb;
+		if (skb == NULL)
+			break;
+		skb->dev = dev;			/* Mark as being used by this device. */
+		tp->rx_ring[i].status = cpu_to_le32(DescOwned);	/* Owned by Tulip chip */
+		tp->rx_ring[i].buffer1 = virt_to_le32desc(skb->tail);
+	}
+	tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
+
+	/* The Tx buffer descriptor is filled in as needed, but we
+	   do need to clear the ownership bit. */
+	for (i = 0; i < TX_RING_SIZE; i++) {
+		tp->tx_skbuff[i] = 0;
+		tp->tx_ring[i].status = 0x00000000;
+		tp->tx_ring[i].buffer2 = virt_to_le32desc(&tp->tx_ring[i+1]);
+	}
+	tp->tx_ring[i-1].buffer2 = virt_to_le32desc(&tp->tx_ring[0]);
+}
+
+static int
+tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	int entry;
+	u32 flag;
+	unsigned long cpuflags;
+
+	/* Caution: the write order is important here, set the field
+	   with the ownership bits last. */
+
+	spin_lock_irqsave(&tp->lock, cpuflags);
+
+	/* Calculate the next Tx descriptor entry. */
+	entry = tp->cur_tx % TX_RING_SIZE;
+
+	tp->tx_skbuff[entry] = skb;
+	tp->tx_ring[entry].buffer1 = virt_to_le32desc(skb->data);
+
+	if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE/2) {/* Typical path */
+		flag = 0x60000000; /* No interrupt */
+	} else if (tp->cur_tx - tp->dirty_tx == TX_RING_SIZE/2) {
+		flag = 0xe0000000; /* Tx-done intr. */
+	} else if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE - 2) {
+		flag = 0x60000000; /* No Tx-done intr. */
+	} else {		/* Leave room for set_rx_mode() to fill entries. */
+		tp->tx_full = 1;
+		flag = 0xe0000000; /* Tx-done intr. */
+		netif_stop_queue(dev);
+	}
+	if (entry == TX_RING_SIZE-1)
+		flag = 0xe0000000 | DESC_RING_WRAP;
+
+	tp->tx_ring[entry].length = cpu_to_le32(skb->len | flag);
+	tp->tx_ring[entry].status = cpu_to_le32(DescOwned);
+	tp->cur_tx++;
+
+	/* Trigger an immediate transmit demand. */
+	outl(0, dev->base_addr + CSR1);
+
+	spin_unlock_irqrestore(&tp->lock, cpuflags);
+
+	dev->trans_start = jiffies;
+
+	return 0;
+}
+
+static void tulip_down (struct net_device *dev)
+{
+	long ioaddr = dev->base_addr;
+	struct tulip_private *tp = (struct tulip_private *) dev->priv;
+	unsigned long flags;
+
+	netif_device_detach (dev);
+
+	del_timer (&tp->timer);
+
+	spin_lock_irqsave (&tp->lock, flags);
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	outl (0x00000000, ioaddr + CSR7);
+
+	/* Stop the Tx and Rx processes. */
+	tulip_outl_CSR6 (tp, inl (ioaddr + CSR6) & ~0x2002);
+
+	/* 21040 -- Leave the card in 10baseT state. */
+	if (tp->chip_id == DC21040)
+		outl (0x00000004, ioaddr + CSR13);
+
+	if (inl (ioaddr + CSR6) != 0xffffffff)
+		tp->stats.rx_missed_errors += inl (ioaddr + CSR8) & 0xffff;
+
+	spin_unlock_irqrestore (&tp->lock, flags);
+
+	dev->if_port = tp->saved_if_port;
+
+	/* Leave the driver in snooze, not sleep, mode. */
+	if (tp->flags & HAS_ACPI)
+		pci_write_config_dword (tp->pdev, 0x40, 0x40000000);
+}
+  
+  
+static int tulip_close (struct net_device *dev)
+{
+	long ioaddr = dev->base_addr;
+	struct tulip_private *tp = (struct tulip_private *) dev->priv;
+	int i;
+
+	tulip_down (dev);
+
+	if (tulip_debug > 1)
+		printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
+			dev->name, inl (ioaddr + CSR5));
+
+	free_irq (dev->irq, dev);
+
+	/* Free all the skbuffs in the Rx queue. */
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		struct sk_buff *skb = tp->rx_skbuff[i];
+		tp->rx_skbuff[i] = 0;
+		tp->rx_ring[i].status = 0;	/* Not owned by Tulip chip. */
+		tp->rx_ring[i].length = 0;
+		tp->rx_ring[i].buffer1 = 0xBADF00D0;	/* An invalid address. */
+		if (skb) {
+			dev_kfree_skb (skb);
+		}
+	}
+	for (i = 0; i < TX_RING_SIZE; i++) {
+		if (tp->tx_skbuff[i])
+			dev_kfree_skb (tp->tx_skbuff[i]);
+		tp->tx_skbuff[i] = 0;
+	}
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+static struct enet_statistics *tulip_get_stats(struct net_device *dev)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+
+	if (netif_running(dev)) {
+		unsigned long flags;
+
+		spin_lock_irqsave (&tp->lock, flags);
+
+		tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
+
+		spin_unlock_irqrestore(&tp->lock, flags);
+	}
+
+	return &tp->stats;
+}
+
+
+/* Provide ioctl() calls to examine the MII xcvr state. */
+static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	u16 *data = (u16 *)&rq->ifr_data;
+	int phy = tp->phys[0] & 0x1f;
+	long flags;
+
+	switch(cmd) {
+	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
+		if (tp->mii_cnt)
+			data[0] = phy;
+		else if (tp->flags & HAS_NWAY143)
+			data[0] = 32;
+		else if (tp->chip_id == COMET)
+			data[0] = 1;
+		else
+			return -ENODEV;
+	case SIOCDEVPRIVATE+1:		/* Read the specified MII register. */
+		if (data[0] == 32  &&  (tp->flags & HAS_NWAY143)) {
+			int csr12 = inl(ioaddr + CSR12);
+			int csr14 = inl(ioaddr + CSR14);
+			switch (data[1]) {
+			case 0: {
+				data[3] = (csr14<<5) & 0x1000;
+				break; }
+			case 1:
+				data[3] = 0x7848 + ((csr12&0x7000) == 0x5000 ? 0x20 : 0)
+					+ (csr12&0x06 ? 0x04 : 0);
+				break;
+			case 4: {
+				data[3] = ((csr14>>9)&0x07C0) +
+					((inl(ioaddr + CSR6)>>3)&0x0040) + ((csr14>>1)&0x20) + 1;
+				break;
+			}
+			case 5: data[3] = csr12 >> 16; break;
+			default: data[3] = 0; break;
+			}
+		} else {
+			spin_lock_irqsave (&tp->lock, flags);
+			data[3] = tulip_mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);
+			spin_unlock_irqrestore (&tp->lock, flags);
+		}
+		return 0;
+	case SIOCDEVPRIVATE+2:		/* Write the specified MII register */
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		if (data[0] == 32  &&  (tp->flags & HAS_NWAY143)) {
+			if (data[1] == 5)
+				tp->to_advertise = data[2];
+		} else {
+			spin_lock_irqsave (&tp->lock, flags);
+			tulip_mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+			spin_unlock_irqrestore(&tp->lock, flags);
+		}
+		return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+
+/* Set or clear the multicast filter for this adaptor.
+   Note that we only use exclusion around actually queueing the
+   new frame, not around filling tp->setup_frame.  This is non-deterministic
+   when re-entered but still correct. */
+
+/* The little-endian AUTODIN32 ethernet CRC calculation.
+   N.B. Do not use for bulk data, use a table-based routine instead.
+   This is common code and should be moved to net/core/crc.c */
+static unsigned const ethernet_polynomial_le = 0xedb88320U;
+static inline u32 ether_crc_le(int length, unsigned char *data)
+{
+	u32 crc = 0xffffffff;	/* Initial value. */
+	while(--length >= 0) {
+		unsigned char current_octet = *data++;
+		int bit;
+		for (bit = 8; --bit >= 0; current_octet >>= 1) {
+			if ((crc ^ current_octet) & 1) {
+				crc >>= 1;
+				crc ^= ethernet_polynomial_le;
+			} else
+				crc >>= 1;
+		}
+	}
+	return crc;
+}
+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc(int length, unsigned char *data)
+{
+    int crc = -1;
+
+    while(--length >= 0) {
+		unsigned char current_octet = *data++;
+		int bit;
+		for (bit = 0; bit < 8; bit++, current_octet >>= 1)
+			crc = (crc << 1) ^
+				((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
+    }
+    return crc;
+}
+
+static void set_rx_mode(struct net_device *dev)
+{
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int csr6 = inl(ioaddr + CSR6) & ~0x00D5;
+
+	tp->csr6 &= ~0x00D5;
+	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
+		tp->csr6 |= 0x00C0;
+		csr6 |= 0x00C0;
+		/* Unconditionally log net taps. */
+		printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name);
+	} else if ((dev->mc_count > 1000)  ||  (dev->flags & IFF_ALLMULTI)) {
+		/* Too many to filter well -- accept all multicasts. */
+		tp->csr6 |= 0x0080;
+		csr6 |= 0x0080;
+	} else	if (tp->flags & MC_HASH_ONLY) {
+		/* Some work-alikes have only a 64-entry hash filter table. */
+		/* Should verify correctness on big-endian/__powerpc__ */
+		struct dev_mc_list *mclist;
+		int i;
+		u32 mc_filter[2];		 /* Multicast hash filter */
+		if (dev->mc_count > 64) {		/* Arbitrary non-effective limit. */
+			tp->csr6 |= 0x0080;
+			csr6 |= 0x0080;
+		} else {
+			mc_filter[1] = mc_filter[0] = 0;
+			for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+				 i++, mclist = mclist->next)
+				set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26, mc_filter);
+			if (tp->chip_id == AX88140) {
+				outl(2, ioaddr + CSR13);
+				outl(mc_filter[0], ioaddr + CSR14);
+				outl(3, ioaddr + CSR13);
+				outl(mc_filter[1], ioaddr + CSR14);
+			} else if (tp->chip_id == COMET) { /* Has a simple hash filter. */
+				outl(mc_filter[0], ioaddr + 0xAC);
+				outl(mc_filter[1], ioaddr + 0xB0);
+			}
+		}
+	} else {
+		u16 *eaddrs, *setup_frm = tp->setup_frame;
+		struct dev_mc_list *mclist;
+		u32 tx_flags = 0x08000000 | 192;
+		int i;
+		unsigned long flags;
+
+		/* Note that only the low-address shortword of setup_frame is valid!
+		   The values are doubled for big-endian architectures. */
+		if (dev->mc_count > 14) { /* Must use a multicast hash table. */
+			u16 hash_table[32];
+			tx_flags = 0x08400000 | 192;		/* Use hash filter. */
+			memset(hash_table, 0, sizeof(hash_table));
+			set_bit(255, hash_table); 			/* Broadcast entry */
+			/* This should work on big-endian machines as well. */
+			for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+				 i++, mclist = mclist->next)
+				set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff,
+						hash_table);
+			for (i = 0; i < 32; i++)
+				*setup_frm++ = *setup_frm++ = hash_table[i];
+			setup_frm = &tp->setup_frame[13*6];
+		} else {
+			/* We have <= 14 addresses so we can use the wonderful
+			   16 address perfect filtering of the Tulip. */
+			for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
+				 i++, mclist = mclist->next) {
+				eaddrs = (u16 *)mclist->dmi_addr;
+				*setup_frm++ = *setup_frm++ = *eaddrs++;
+				*setup_frm++ = *setup_frm++ = *eaddrs++;
+				*setup_frm++ = *setup_frm++ = *eaddrs++;
+			}
+			/* Fill the unused entries with the broadcast address. */
+			memset(setup_frm, 0xff, (15-i)*12);
+			setup_frm = &tp->setup_frame[15*6];
+		}
+
+		/* Fill the final entry with our physical address. */
+		eaddrs = (u16 *)dev->dev_addr;
+		*setup_frm++ = *setup_frm++ = eaddrs[0];
+		*setup_frm++ = *setup_frm++ = eaddrs[1];
+		*setup_frm++ = *setup_frm++ = eaddrs[2];
+
+		spin_lock_irqsave(&tp->lock, flags);
+
+		if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) {
+			/* Same setup recently queued, we need not add it. */
+		} else {
+			unsigned int entry;
+
+			/* Now add this frame to the Tx list. */
+
+			entry = tp->cur_tx++ % TX_RING_SIZE;
+
+			if (entry != 0) {
+				/* Avoid a chip errata by prefixing a dummy entry. */
+				tp->tx_skbuff[entry] = 0;
+				tp->tx_ring[entry].length =
+					(entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0;
+				tp->tx_ring[entry].buffer1 = 0;
+				tp->tx_ring[entry].status = cpu_to_le32(DescOwned);
+				entry = tp->cur_tx++ % TX_RING_SIZE;
+			}
+
+			tp->tx_skbuff[entry] = 0;
+			/* Put the setup frame on the Tx list. */
+			if (entry == TX_RING_SIZE-1)
+				tx_flags |= DESC_RING_WRAP;		/* Wrap ring. */
+			tp->tx_ring[entry].length = cpu_to_le32(tx_flags);
+			tp->tx_ring[entry].buffer1 = virt_to_le32desc(tp->setup_frame);
+			tp->tx_ring[entry].status = cpu_to_le32(DescOwned);
+			if (tp->cur_tx - tp->dirty_tx >= TX_RING_SIZE - 2) {
+				netif_stop_queue(dev);
+				tp->tx_full = 1;
+			}
+
+			/* Trigger an immediate transmit demand. */
+			outl(0, ioaddr + CSR1);
+
+		}
+
+		spin_unlock_irqrestore(&tp->lock, flags);
+	}
+	tulip_outl_CSR6(tp, csr6 | 0x0000);
+}
+
+
+static int __devinit tulip_init_one (struct pci_dev *pdev,
+				     const struct pci_device_id *ent)
+{
+	static int did_version = 0;			/* Already printed version info. */
+	struct tulip_private *tp;
+	/* See note below on the multiport cards. */
+	static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'};
+	static int last_irq = 0;
+	static int multiport_cnt = 0;		/* For four-port boards w/one EEPROM */
+	u8 chip_rev;
+	int i, irq;
+	unsigned short sum;
+	u8 ee_data[EEPROM_SIZE];
+	struct net_device *dev;
+	long ioaddr;
+	static int board_idx = -1;
+	int chip_idx = ent->driver_data;
+	
+	board_idx++;
+
+	if (tulip_debug > 0  &&  did_version++ == 0)
+		printk (KERN_INFO "%s", version);
+
+        if( pdev->subsystem_vendor == 0x1376 ){
+		printk (KERN_ERR PFX "skipping LMC card.\n");
+		return -ENODEV;
+	}
+	
+	ioaddr = pci_resource_start (pdev, 0);
+	irq = pdev->irq;
+
+	/* init_etherdev ensures qword aligned structures */
+	dev = init_etherdev (NULL, sizeof (*tp));
+	if (!dev) {
+		printk (KERN_ERR PFX "ether device alloc failed, aborting\n");
+		return -ENOMEM;
+	}
+
+	/* We do a request_region() only to register /proc/ioports info. */
+	/* Note that proper size is tulip_tbl[chip_idx].chip_name, but... */
+	if (!request_region (ioaddr, tulip_tbl[chip_idx].io_size, dev->name)) {
+		printk (KERN_ERR PFX "I/O ports (0x%x@0x%lx) unavailable, "
+			"aborting\n", tulip_tbl[chip_idx].io_size, ioaddr);
+		goto err_out_free_netdev;
+	}
+
+	if (pci_enable_device(pdev)) {
+		printk (KERN_ERR PFX "cannot enable PCI device (id %04x:%04x, "
+			"bus %d, devfn %d), aborting\n",
+			pdev->vendor, pdev->device,
+			pdev->bus->number, pdev->devfn);
+		goto err_out_free_netdev;
+	}
+
+	pci_set_master(pdev);
+
+	pci_read_config_byte (pdev, PCI_REVISION_ID, &chip_rev);
+
+	/*
+	 * initialize priviate data structure 'tp'
+	 * it is zeroed and aligned in init_etherdev
+	 */
+	tp = dev->priv;
+
+	tp->chip_id = chip_idx;
+	tp->flags = tulip_tbl[chip_idx].flags;
+	tp->pdev = pdev;
+	tp->base_addr = ioaddr;
+	tp->revision = chip_rev;
+	spin_lock_init(&tp->lock);
+
+#ifdef TULIP_FULL_DUPLEX
+	tp->full_duplex = 1;
+	tp->full_duplex_lock = 1;
+#endif
+#ifdef TULIP_DEFAULT_MEDIA
+	tp->default_port = TULIP_DEFAULT_MEDIA;
+#endif
+#ifdef TULIP_NO_MEDIA_SWITCH
+	tp->medialock = 1;
+#endif
+
+	printk(KERN_INFO "%s: %s rev %d at %#3lx,",
+		   dev->name, tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr);
+
+	/* Stop the chip's Tx and Rx processes. */
+	tulip_outl_CSR6(tp, inl(ioaddr + CSR6) & ~0x2002);
+	/* Clear the missed-packet counter. */
+	(volatile int)inl(ioaddr + CSR8);
+
+	if (chip_idx == DC21041  &&  inl(ioaddr + CSR9) & 0x8000) {
+		printk(" 21040 compatible mode,");
+		chip_idx = DC21040;
+	}
+
+	/* The station address ROM is read byte serially.  The register must
+	   be polled, waiting for the value to be read bit serially from the
+	   EEPROM.
+	   */
+	sum = 0;
+	if (chip_idx == DC21040) {
+		outl(0, ioaddr + CSR9);		/* Reset the pointer with a dummy write. */
+		for (i = 0; i < 6; i++) {
+			int value, boguscnt = 100000;
+			do
+				value = inl(ioaddr + CSR9);
+			while (value < 0  && --boguscnt > 0);
+			dev->dev_addr[i] = value;
+			sum += value & 0xff;
+		}
+	} else if (chip_idx == LC82C168) {
+		for (i = 0; i < 3; i++) {
+			int value, boguscnt = 100000;
+			outl(0x600 | i, ioaddr + 0x98);
+			do
+				value = inl(ioaddr + CSR9);
+			while (value < 0  && --boguscnt > 0);
+			put_unaligned(le16_to_cpu(value), ((u16*)dev->dev_addr) + i);
+			sum += value & 0xffff;
+		}
+	} else if (chip_idx == COMET) {
+		/* No need to read the EEPROM. */
+		put_unaligned(inl(ioaddr + 0xA4), (u32 *)dev->dev_addr);
+		put_unaligned(inl(ioaddr + 0xA8), (u16 *)(dev->dev_addr + 4));
+		for (i = 0; i < 6; i ++)
+			sum += dev->dev_addr[i];
+	} else {
+		/* A serial EEPROM interface, we read now and sort it out later. */
+		int sa_offset = 0;
+		int ee_addr_size = tulip_read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
+
+		for (i = 0; i < sizeof(ee_data)/2; i++)
+			((u16 *)ee_data)[i] =
+				le16_to_cpu(tulip_read_eeprom(ioaddr, i, ee_addr_size));
+
+		/* DEC now has a specification (see Notes) but early board makers
+		   just put the address in the first EEPROM locations. */
+		/* This does  memcmp(eedata, eedata+16, 8) */
+		for (i = 0; i < 8; i ++)
+			if (ee_data[i] != ee_data[16+i])
+				sa_offset = 20;
+		if (ee_data[0] == 0xff  &&  ee_data[1] == 0xff &&  ee_data[2] == 0) {
+			sa_offset = 2;		/* Grrr, damn Matrox boards. */
+			multiport_cnt = 4;
+		}
+		for (i = 0; i < 6; i ++) {
+			dev->dev_addr[i] = ee_data[i + sa_offset];
+			sum += ee_data[i + sa_offset];
+		}
+	}
+	/* Lite-On boards have the address byte-swapped. */
+	if ((dev->dev_addr[0] == 0xA0  ||  dev->dev_addr[0] == 0xC0)
+		&&  dev->dev_addr[1] == 0x00)
+		for (i = 0; i < 6; i+=2) {
+			char tmp = dev->dev_addr[i];
+			dev->dev_addr[i] = dev->dev_addr[i+1];
+			dev->dev_addr[i+1] = tmp;
+		}
+	/* On the Zynx 315 Etherarray and other multiport boards only the
+	   first Tulip has an EEPROM.
+	   The addresses of the subsequent ports are derived from the first.
+	   Many PCI BIOSes also incorrectly report the IRQ line, so we correct
+	   that here as well. */
+	if (sum == 0  || sum == 6*0xff) {
+		printk(" EEPROM not present,");
+		for (i = 0; i < 5; i++)
+			dev->dev_addr[i] = last_phys_addr[i];
+		dev->dev_addr[i] = last_phys_addr[i] + 1;
+#if defined(__i386__)		/* Patch up x86 BIOS bug. */
+		if (last_irq)
+			irq = last_irq;
+#endif
+	}
+
+	for (i = 0; i < 6; i++)
+		printk("%c%2.2X", i ? ':' : ' ', last_phys_addr[i] = dev->dev_addr[i]);
+	printk(", IRQ %d.\n", irq);
+	last_irq = irq;
+
+	pdev->driver_data = dev;
+	dev->base_addr = ioaddr;
+	dev->irq = irq;
+	tp->csr0 = csr0;
+
+	/* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles.
+	   And the ASIX must have a burst limit or horrible things happen. */
+	if (chip_idx == DC21143  &&  chip_rev == 65)
+		tp->csr0 &= ~0x01000000;
+	else if (chip_idx == AX88140)
+		tp->csr0 |= 0x2000;
+
+	/* The lower four bits are the media type. */
+	if (board_idx >= 0  &&  board_idx < MAX_UNITS) {
+		tp->default_port = options[board_idx] & 15;
+		if ((options[board_idx] & 0x90) || full_duplex[board_idx] > 0)
+			tp->full_duplex = 1;
+		if (mtu[board_idx] > 0)
+			dev->mtu = mtu[board_idx];
+	}
+	if (dev->mem_start)
+		tp->default_port = dev->mem_start;
+	if (tp->default_port) {
+		tp->medialock = 1;
+		if (tulip_media_cap[tp->default_port] & MediaAlwaysFD)
+			tp->full_duplex = 1;
+	}
+	if (tp->full_duplex)
+		tp->full_duplex_lock = 1;
+
+	if (tulip_media_cap[tp->default_port] & MediaIsMII) {
+		u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 };
+		tp->to_advertise = media2advert[tp->default_port - 9];
+	} else if (tp->flags & HAS_8023X)
+		tp->to_advertise = 0x05e1;
+	else 
+		tp->to_advertise = 0x01e1;
+
+	/* This is logically part of probe1(), but too complex to write inline. */
+	if (tp->flags & HAS_MEDIA_TABLE) {
+		memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom));
+		tulip_parse_eeprom(dev);
+	}
+
+	if ((tp->flags & ALWAYS_CHECK_MII) ||
+		(tp->mtable  &&  tp->mtable->has_mii) ||
+		( ! tp->mtable  &&  (tp->flags & HAS_MII))) {
+		int phy, phy_idx;
+		if (tp->mtable  &&  tp->mtable->has_mii) {
+			for (i = 0; i < tp->mtable->leafcount; i++)
+				if (tp->mtable->mleaf[i].media == 11) {
+					tp->cur_index = i;
+					tp->saved_if_port = dev->if_port;
+					tulip_select_media(dev, 1);
+					dev->if_port = tp->saved_if_port;
+					break;
+				}
+		}
+		/* Find the connected MII xcvrs.
+		   Doing this in open() would allow detecting external xcvrs later,
+		   but takes much time. */
+		for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys);
+			 phy++) {
+			int mii_status = tulip_mdio_read(dev, phy, 1);
+			if ((mii_status & 0x8301) == 0x8001 ||
+				((mii_status & 0x8000) == 0  && (mii_status & 0x7800) != 0)) {
+				int mii_reg0 = tulip_mdio_read(dev, phy, 0);
+				int mii_advert = tulip_mdio_read(dev, phy, 4);
+				int reg4 = ((mii_status>>6) & tp->to_advertise) | 1;
+				tp->phys[phy_idx] = phy;
+				tp->advertising[phy_idx++] = reg4;
+				printk(KERN_INFO "%s:  MII transceiver #%d "
+					   "config %4.4x status %4.4x advertising %4.4x.\n",
+					   dev->name, phy, mii_reg0, mii_status, mii_advert);
+				/* Fixup for DLink with miswired PHY. */
+				if (mii_advert != reg4) {
+					printk(KERN_DEBUG "%s:  Advertising %4.4x on PHY %d,"
+						   " previously advertising %4.4x.\n",
+						   dev->name, reg4, phy, mii_advert);
+					printk(KERN_DEBUG "%s:  Advertising %4.4x (to advertise"
+						   " is %4.4x).\n",
+						   dev->name, reg4, tp->to_advertise);
+					tulip_mdio_write(dev, phy, 4, reg4);
+				}
+				/* Enable autonegotiation: some boards default to off. */
+				tulip_mdio_write(dev, phy, 0, mii_reg0 |
+						   (tp->full_duplex ? 0x1100 : 0x1000) |
+						   (tulip_media_cap[tp->default_port]&MediaIs100 ? 0x2000:0));
+			}
+		}
+		tp->mii_cnt = phy_idx;
+		if (tp->mtable  &&  tp->mtable->has_mii  &&  phy_idx == 0) {
+			printk(KERN_INFO "%s: ***WARNING***: No MII transceiver found!\n",
+				   dev->name);
+			tp->phys[0] = 1;
+		}
+	}
+
+	/* The Tulip-specific entries in the device structure. */
+	dev->open = tulip_open;
+	dev->hard_start_xmit = tulip_start_xmit;
+	dev->tx_timeout = tulip_tx_timeout;
+	dev->watchdog_timeo = TX_TIMEOUT;
+	dev->stop = tulip_close;
+	dev->get_stats = tulip_get_stats;
+	dev->do_ioctl = private_ioctl;
+	dev->set_multicast_list = set_rx_mode;
+
+	if ((tp->flags & HAS_NWAY143)  || tp->chip_id == DC21041)
+		tp->link_change = t21142_lnk_change;
+	else if (tp->flags & HAS_PNICNWAY)
+		tp->link_change = pnic_lnk_change;
+
+	/* Reset the xcvr interface and turn on heartbeat. */
+	switch (chip_idx) {
+	case DC21041:
+		tp->to_advertise = 0x0061;
+		outl(0x00000000, ioaddr + CSR13);
+		outl(0xFFFFFFFF, ioaddr + CSR14);
+		outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */
+		tulip_outl_CSR6(tp, inl(ioaddr + CSR6) | 0x0200);
+		outl(0x0000EF05, ioaddr + CSR13);
+		break;
+	case DC21040:
+		outl(0x00000000, ioaddr + CSR13);
+		outl(0x00000004, ioaddr + CSR13);
+		break;
+	case DC21140:
+	default:
+		if (tp->mtable)
+			outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12);
+		break;
+	case DC21142:
+	case PNIC2:
+		if (tp->mii_cnt  ||  tulip_media_cap[dev->if_port] & MediaIsMII) {
+			tulip_outl_CSR6(tp, 0x82020000);
+			outl(0x0000, ioaddr + CSR13);
+			outl(0x0000, ioaddr + CSR14);
+			tulip_outl_CSR6(tp, 0x820E0000);
+		} else
+			t21142_start_nway(dev);
+		break;
+	case LC82C168:
+		if ( ! tp->mii_cnt) {
+			tp->nway = 1;
+			tp->nwayset = 0;
+			tulip_outl_CSR6(tp, 0x00420000);
+			outl(0x30, ioaddr + CSR12);
+			tulip_outl_CSR6(tp, 0x0001F078);
+			tulip_outl_CSR6(tp, 0x0201F078); /* Turn on autonegotiation. */
+		}
+		break;
+	case MX98713: case COMPEX9881:
+		tulip_outl_CSR6(tp, 0x00000000);
+		outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */
+		outl(0x00000001, ioaddr + CSR13);
+		break;
+	case MX98715: case MX98725:
+		tulip_outl_CSR6(tp, 0x01a80000);
+		outl(0xFFFFFFFF, ioaddr + CSR14);
+		outl(0x00001000, ioaddr + CSR12);
+		break;
+	case COMET:
+		/* No initialization necessary. */
+		break;
+	}
+
+	/* put the chip in snooze mode until opened */
+	if (tulip_tbl[chip_idx].flags & HAS_ACPI)
+		pci_write_config_dword(pdev, 0x40, 0x40000000);
+
+	return 0;
+
+err_out_free_netdev:
+	unregister_netdev (dev);
+	kfree (dev);
+	return -ENODEV;
+}
+
+
+static void tulip_suspend (struct pci_dev *pdev)
+{
+	struct net_device *dev = pdev->driver_data;
+
+	if (dev && netif_device_present (dev))
+		tulip_down (dev);
+}
+
+
+static void tulip_resume (struct pci_dev *pdev)
+{
+	struct net_device *dev = pdev->driver_data;
+
+	if (dev && !netif_device_present (dev))
+		tulip_up (dev);
+}
+
+
+static void __devexit tulip_remove_one (struct pci_dev *pdev)
+{
+	struct net_device *dev = pdev->driver_data;
+
+	if (dev) {
+		struct tulip_private *tp = (struct tulip_private *)dev->priv;
+		unregister_netdev(dev);
+		release_region(dev->base_addr,
+			       tulip_tbl[tp->chip_id].io_size);
+		kfree(dev);
+	}
+}
+
+
+static struct pci_driver tulip_driver = {
+	name:		TULIP_MODULE_NAME,
+	id_table:	tulip_pci_tbl,
+	probe:		tulip_init_one,
+	remove:		tulip_remove_one,
+	suspend:	tulip_suspend,
+	resume:		tulip_resume,
+};
+
+
+static int __init tulip_init (void)
+{
+	/* copy module parms into globals */
+	tulip_rx_copybreak = rx_copybreak;
+	tulip_max_interrupt_work = max_interrupt_work;
+	
+	/* probe for and init boards */
+	return pci_module_init (&tulip_driver);
+}
+
+
+static void __exit tulip_cleanup (void)
+{
+	pci_unregister_driver (&tulip_driver);
+}
+
+
+module_init(tulip_init);
+module_exit(tulip_cleanup);
diff -u --recursive --new-file v2.3.47/linux/drivers/net/tulip.c linux/drivers/net/tulip.c
--- v2.3.47/linux/drivers/net/tulip.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/net/tulip.c	Wed Dec 31 16:00:00 1969
@@ -1,3159 +0,0 @@
-/* tulip.c: A DEC 21040-family ethernet driver for Linux. */
-/*
-	Copyright 2000  The Linux Kernel Team
-	Written/copyright 1994-1999 by Donald Becker.
-
-	This software may be used and distributed according to the terms
-	of the GNU Public License, incorporated herein by reference.
-
-	This driver is for the Digital "Tulip" Ethernet adapter interface.
-	It should work with most DEC 21*4*-based chips/ethercards, as well as
-	with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and ASIX.
-
-	The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
-	Center of Excellence in Space Data and Information Sciences
-	   Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
-	Additional information available at
-	http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html
-	
-	For this specific driver variant please use linux-kernel for 
-	bug reports.
-
-
-				Theory of Operation
-
-I. Board Compatibility
-
-This device driver is designed for the DECchip "Tulip", Digital's
-single-chip ethernet controllers for PCI.  Supported members of the family
-are the 21040, 21041, 21140, 21140A, 21142, and 21143.  Similar work-alike
-chips from Lite-On, Macronics, ASIX, Compex and other listed below are also
-supported. 
-
-These chips are used on at least 140 unique PCI board designs.  The great
-number of chips and board designs supported is the reason for the
-driver size and complexity.  Almost of the increasing complexity is in the
-board configuration and media selection code.  There is very little
-increasing in the operational critical path length.
-
-II. Board-specific settings
-
-PCI bus devices are configured by the system at boot time, so no jumpers
-need to be set on the board.  The system BIOS preferably should assign the
-PCI INTA signal to an otherwise unused system IRQ line.
-
-Some boards have EEPROMs tables with default media entry.  The factory default
-is usually "autoselect".  This should only be overridden when using
-transceiver connections without link beat e.g. 10base2 or AUI, or (rarely!)
-for forcing full-duplex when used with old link partners that do not do
-autonegotiation. 
-
-III. Driver operation
-
-IIIa. Ring buffers
-
-The Tulip can use either ring buffers or lists of Tx and Rx descriptors.
-This driver uses statically allocated rings of Rx and Tx descriptors, set at
-compile time by RX/TX_RING_SIZE.  This version of the driver allocates skbuffs
-for the Rx ring buffers at open() time and passes the skb->data field to the
-Tulip as receive data buffers.  When an incoming frame is less than
-RX_COPYBREAK bytes long, a fresh skbuff is allocated and the frame is
-copied to the new skbuff.  When the incoming frame is larger, the skbuff is
-passed directly up the protocol stack and replaced by a newly allocated
-skbuff.
-
-The RX_COPYBREAK value is chosen to trade-off the memory wasted by
-using a full-sized skbuff for small frames vs. the copying costs of larger
-frames.  For small frames the copying cost is negligible (esp. considering
-that we are pre-loading the cache with immediately useful header
-information).  For large frames the copying cost is non-trivial, and the
-larger copy might flush the cache of useful data.  A subtle aspect of this
-choice is that the Tulip only receives into longword aligned buffers, thus
-the IP header at offset 14 isn't longword aligned for further processing.
-Copied frames are put into the new skbuff at an offset of "+2", thus copying
-has the beneficial effect of aligning the IP header and preloading the
-cache.
-
-IIIC. Synchronization
-The driver runs as two independent, single-threaded flows of control.  One
-is the send-packet routine, which enforces single-threaded use by the
-dev->tbusy flag.  The other thread is the interrupt handler, which is single
-threaded by the hardware and other software.
-
-The send packet thread has partial control over the Tx ring and 'dev->tbusy'
-flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
-queue slot is empty, it clears the tbusy flag when finished otherwise it sets
-the 'tp->tx_full' flag.
-
-The interrupt handler has exclusive control over the Rx ring and records stats
-from the Tx ring.  (The Tx-done interrupt can't be selectively turned off, so
-we can't avoid the interrupt overhead by having the Tx routine reap the Tx
-stats.)	 After reaping the stats, it marks the queue entry as empty by setting
-the 'base' to zero.	 Iff the 'tp->tx_full' flag is set, it clears both the
-tx_full and tbusy flags.
-
-IV. Notes
-
-Thanks to Duke Kamstra of SMC for long ago providing an EtherPower board.
-Greg LaPolla at Linksys provided PNIC and other Linksys boards.
-Znyx provided a four-port card for testing.
-
-IVb. References
-
-http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
-http://www.digital.com  (search for current 21*4* datasheets and "21X4 SROM")
-http://www.national.com/pf/DP/DP83840A.html
-http://www.asix.com.tw/pmac.htm
-http://www.admtek.com.tw/
-
-IVc. Errata
-
-The old DEC databooks were light on details.
-The 21040 databook claims that CSR13, CSR14, and CSR15 should each be the last
-register of the set CSR12-15 written.  Hmmm, now how is that possible?
-
-The DEC SROM format is very badly designed not precisely defined, leading to
-part of the media selection junkheap below.  Some boards do not have EEPROM
-media tables and need to be patched up.  Worse, other boards use the DEC
-design kit media table when it isn't correct for their board.
-
-We cannot use MII interrupts because there is no defined GPIO pin to attach
-them.  The MII transceiver status is polled using an kernel timer.
-
-*/
-
-static const char version[] = "Linux Tulip driver version 0.9.2 (Feb 15, 2000)\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-#include <asm/processor.h>		/* Processor type for cache alignment. */
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/unaligned.h>
-#include <asm/delay.h>
-
-
-/* A few user-configurable values. */
-
-/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 25;
-
-#define MAX_UNITS 8
-/* Used to pass the full-duplex flag, etc. */
-static int full_duplex[MAX_UNITS] = {0, };
-static int options[MAX_UNITS] = {0, };
-static int mtu[MAX_UNITS] = {0, };			/* Jumbo MTU for interfaces. */
-
-/*  The possible media types that can be set in options[] are: */
-static const char * const medianame[] = {
-	"10baseT", "10base2", "AUI", "100baseTx",
-	"10baseT-FD", "100baseTx-FD", "100baseT4", "100baseFx",
-	"100baseFx-FD", "MII 10baseT", "MII 10baseT-FD", "MII",
-	"10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FD", "MII 100baseT4",
-};
-
-/* Set if the PCI BIOS detects the chips on a multiport board backwards. */
-#ifdef REVERSE_PROBE_ORDER
-static int reverse_probe = 1;
-#else
-static int reverse_probe = 0;
-#endif
-
-/* Keep the ring sizes a power of two for efficiency.
-   Making the Tx ring too large decreases the effectiveness of channel
-   bonding and packet priority.
-   There are no ill effects from too-large receive rings. */
-#define TX_RING_SIZE	16
-#define RX_RING_SIZE	32
-
-/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
-#ifdef __alpha__
-static int rx_copybreak = 1518;
-#else
-static int rx_copybreak = 100;
-#endif
-
-/*
-  Set the bus performance register.
-	Typical: Set 16 longword cache alignment, no burst limit.
-	Cache alignment bits 15:14	     Burst length 13:8
-		0000	No alignment  0x00000000 unlimited		0800 8 longwords
-		4000	8  longwords		0100 1 longword		1000 16 longwords
-		8000	16 longwords		0200 2 longwords	2000 32 longwords
-		C000	32  longwords		0400 4 longwords
-	Warning: many older 486 systems are broken and require setting 0x00A04800
-	   8 longword cache alignment, 8 longword burst.
-	ToDo: Non-Intel setting could be better.
-*/
-
-#if defined(__alpha__)
-static int csr0 = 0x01A00000 | 0xE000;
-#elif defined(__i386__) || defined(__powerpc__) || defined(__sparc__)
-static int csr0 = 0x01A00000 | 0x8000;
-#else
-#warning Processor architecture undefined!
-static int csr0 = 0x00A00000 | 0x4800;
-#endif
-
-/* Operational parameters that usually are not changed. */
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT  (4*HZ)
-#define PKT_BUF_SZ		1536			/* Size of each temporary Rx buffer.*/
-/* This is a mysterious value that can be written to CSR11 in the 21040 (only)
-   to support a pre-NWay full-duplex signaling mechanism using short frames.
-   No one knows what it should be, but if left at its default value some
-   10base2(!) packets trigger a full-duplex-request interrupt. */
-#define FULL_DUPLEX_MAGIC	0x6969
-
-
-/* Kernel compatibility defines, some common to David Hind's PCMCIA package.
-   This is only in the support-all-kernels source code. */
-
-MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
-MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver");
-MODULE_PARM(debug, "i");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(reverse_probe, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(csr0, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-
-#define TULIP_MODULE_NAME "tulip"
-#define PFX TULIP_MODULE_NAME ": "
-
-#define RUN_AT(x) (jiffies + (x))
-
-/* Condensed operations for readability. */
-#define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
-#define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
-
-#define tulip_debug debug
-#ifdef TULIP_DEBUG
-static int tulip_debug = TULIP_DEBUG;
-#else
-static int tulip_debug = 1;
-#endif
-
-
-
-/* This table use during operation for capabilities and media timer. */
-
-static void tulip_timer(unsigned long data);
-static void t21142_timer(unsigned long data);
-static void mxic_timer(unsigned long data);
-static void pnic_timer(unsigned long data);
-static void comet_timer(unsigned long data);
-
-enum tbl_flag {
-	HAS_MII=1, HAS_MEDIA_TABLE=2, CSR12_IN_SROM=4, ALWAYS_CHECK_MII=8,
-	HAS_ACPI=0x10, MC_HASH_ONLY=0x20, /* Hash-only multicast filter. */
-	HAS_PNICNWAY=0x80, HAS_NWAY143=0x40,	/* Uses internal NWay xcvr. */
-	HAS_8023X=0x100,
-};
-static struct tulip_chip_table {
-	char *chip_name;
-	int io_size;
-	int valid_intrs;			/* CSR7 interrupt enable settings */
-	int flags;
-	void (*media_timer)(unsigned long data);
-} tulip_tbl[] = {
-  { "Digital DC21040 Tulip", 128, 0x0001ebef, 0, tulip_timer },
-  { "Digital DC21041 Tulip", 128, 0x0001ebff, HAS_MEDIA_TABLE, tulip_timer },
-  { "Digital DS21140 Tulip", 128, 0x0001ebef,
-	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, tulip_timer },
-  { "Digital DS21143 Tulip", 128, 0x0801fbff,
-	HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY143,
-	t21142_timer },
-  { "Lite-On 82c168 PNIC", 256, 0x0001ebef,
-	HAS_MII | HAS_PNICNWAY, pnic_timer },
-  { "Macronix 98713 PMAC", 128, 0x0001ebef,
-	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer },
-  { "Macronix 98715 PMAC", 256, 0x0001ebef,
-	HAS_MEDIA_TABLE, mxic_timer },
-  { "Macronix 98725 PMAC", 256, 0x0001ebef,
-	HAS_MEDIA_TABLE, mxic_timer },
-  { "ASIX AX88140", 128, 0x0001fbff,
-	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY, tulip_timer },
-  { "Lite-On PNIC-II", 256, 0x0801fbff,
-	HAS_MII | HAS_NWAY143 | HAS_8023X, t21142_timer },
-  { "ADMtek Comet", 256, 0x0001abef,
-	MC_HASH_ONLY, comet_timer },
-  { "Compex 9881 PMAC", 128, 0x0001ebef,
-	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer },
-  { "Intel DS21145 Tulip", 128, 0x0801fbff,
-	HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_NWAY143,
-	t21142_timer },
-  { "Xircom tulip work-alike", 128, 0x0801fbff,
-	HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY143,
-	t21142_timer },
-  {0},
-};
-/* This matches the table above.  Note 21142 == 21143. */
-enum chips {
-	DC21040=0,
-	DC21041=1,
-	DC21140=2,
-	DC21142=3, DC21143=3,
-	LC82C168,
-	MX98713,
-	MX98715,
-	MX98725,
-	AX88140,
-	PNIC2,
-	COMET,
-	COMPEX9881,
-	I21145,
-	X3201_3,
-};
-
-
-static struct pci_device_id tulip_pci_tbl[] __devinitdata = {
-	{ 0x1011, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21040 },
-	{ 0x1011, 0x0014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21041 },
-	{ 0x1011, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21140 },
-	{ 0x1011, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21143 },
-	{ 0x11AD, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, LC82C168 },
-	{ 0x10d9, 0x0512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98713 },
-	{ 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
-	{ 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98725 },
-	{ 0x125B, 0x1400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AX88140 },
-	{ 0x11AD, 0xc115, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PNIC2 },
-	{ 0x1317, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
-	{ 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 },
-	{ 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 },
-	{ 0x115d, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, X3201_3 },
-	{0},
-};
-MODULE_DEVICE_TABLE(pci,tulip_pci_tbl);
-
-
-/* A full-duplex map for media types. */
-enum MediaIs {
-	MediaIsFD = 1, MediaAlwaysFD=2, MediaIsMII=4, MediaIsFx=8,
-	MediaIs100=16};
-static const char media_cap[] =
-{0,0,0,16,  3,19,16,24,  27,4,7,5, 0,20,23,20 };
-static u8 t21040_csr13[] = {2,0x0C,8,4,  4,0,0,0, 0,0,0,0, 4,0,0,0};
-/* 21041 transceiver register settings: 10-T, 10-2, AUI, 10-T, 10T-FD*/
-static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, };
-static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
-static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
-
-static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, };
-static u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, };
-static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
-
-/* Offsets to the Command and Status Registers, "CSRs".  All accesses
-   must be longword instructions and quadword aligned. */
-enum tulip_offsets {
-	CSR0=0,    CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
-	CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
-	CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78 };
-
-/* The bits in the CSR5 status registers, mostly interrupt sources. */
-enum status_bits {
-	TimerInt=0x800, SytemError=0x2000, TPLnkFail=0x1000, TPLnkPass=0x10,
-	NormalIntr=0x10000, AbnormalIntr=0x8000,
-	RxJabber=0x200, RxDied=0x100, RxNoBuf=0x80, RxIntr=0x40,
-	TxFIFOUnderflow=0x20, TxJabber=0x08, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01,
-};
-
-/* The Tulip Rx and Tx buffer descriptors. */
-struct tulip_rx_desc {
-	s32 status;
-	s32 length;
-	u32 buffer1, buffer2;
-};
-
-struct tulip_tx_desc {
-	s32 status;
-	s32 length;
-	u32 buffer1, buffer2;				/* We use only buffer 1.  */
-};
-
-enum desc_status_bits {
-	DescOwned=0x80000000, RxDescFatalErr=0x8000, RxWholePkt=0x0300,
-};
-
-/* Ring-wrap flag in length field, use for last ring entry.
-	0x01000000 means chain on buffer2 address,
-	0x02000000 means use the ring start address in CSR2/3.
-   Note: Some work-alike chips do not function correctly in chained mode.
-   The ASIX chip works only in chained mode.
-   Thus we indicates ring mode, but always write the 'next' field for
-   chained mode as well.
-*/
-#define DESC_RING_WRAP 0x02000000
-
-#define EEPROM_SIZE 128 	/* 2 << EEPROM_ADDRLEN */
-
-struct medialeaf {
-	u8 type;
-	u8 media;
-	unsigned char *leafdata;
-};
-
-struct mediatable {
-	u16 defaultmedia;
-	u8 leafcount, csr12dir;				/* General purpose pin directions. */
-	unsigned has_mii:1, has_nonmii:1, has_reset:6;
-	u32 csr15dir, csr15val;				/* 21143 NWay setting. */
-	struct medialeaf mleaf[0];
-};
-
-struct mediainfo {
-	struct mediainfo *next;
-	int info_type;
-	int index;
-	unsigned char *info;
-};
-
-struct tulip_private {
-	char devname[8];			/* Used only for kernel debugging. */
-	const char *product_name;
-	struct net_device *next_module;
-	struct tulip_rx_desc rx_ring[RX_RING_SIZE];
-	struct tulip_tx_desc tx_ring[TX_RING_SIZE];
-	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
-	struct sk_buff* tx_skbuff[TX_RING_SIZE];
-	/* The addresses of receive-in-place skbuffs. */
-	struct sk_buff* rx_skbuff[RX_RING_SIZE];
-	char *rx_buffs;				/* Address of temporary Rx buffers. */
-	u16 setup_frame[96];		/* Pseudo-Tx frame to init address table. */
-	int chip_id;
-	int revision;
-	int flags;
-	struct net_device_stats stats;
-	struct timer_list timer;	/* Media selection timer. */
-	spinlock_t tx_lock;
-	unsigned int cur_rx, cur_tx;		/* The next free ring entry */
-	unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
-	unsigned int tx_full:1;				/* The Tx queue is full. */
-	unsigned int full_duplex:1;			/* Full-duplex operation requested. */
-	unsigned int full_duplex_lock:1;
-	unsigned int fake_addr:1;			/* Multiport board faked address. */
-	unsigned int default_port:4;		/* Last dev->if_port value. */
-	unsigned int media2:4;				/* Secondary monitored media port. */
-	unsigned int medialock:1;			/* Don't sense media type. */
-	unsigned int mediasense:1;			/* Media sensing in progress. */
-	unsigned int nway:1, nwayset:1;		/* 21143 internal NWay. */
-	unsigned int csr0;					/* CSR0 setting. */
-	unsigned int csr6;					/* Current CSR6 control settings. */
-	unsigned char eeprom[EEPROM_SIZE];	/* Serial EEPROM contents. */
-	void (*link_change)(struct net_device *dev, int csr5);
-	u16 to_advertise;					/* NWay capabilities advertised.  */
-	u16 lpar;							/* 21143 Link partner ability. */
-	u16 advertising[4];
-	signed char phys[4], mii_cnt;		/* MII device addresses. */
-	struct mediatable *mtable;
-	int cur_index;						/* Current media index. */
-	int saved_if_port;
-	struct pci_dev *pdev;
-	int ttimer;
-	int susp_rx;
-	unsigned long nir;
-	unsigned long base_addr;
-	int pad0, pad1;						/* Used for 8-byte alignment */
-};
-
-static void parse_eeprom(struct net_device *dev);
-static int read_eeprom(long ioaddr, int location, int addr_len);
-static int mdio_read(struct net_device *dev, int phy_id, int location);
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
-static void select_media(struct net_device *dev, int startup);
-/* Chip-specific media selection (timer functions prototyped above). */
-static void t21142_lnk_change(struct net_device *dev, int csr5);
-static void t21142_start_nway(struct net_device *dev);
-static void pnic_lnk_change(struct net_device *dev, int csr5);
-static void pnic_do_nway(struct net_device *dev);
-
-static void tulip_tx_timeout(struct net_device *dev);
-static void tulip_init_ring(struct net_device *dev);
-static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static int tulip_refill_rx(struct net_device *dev);
-static int tulip_rx(struct net_device *dev);
-static void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-static int tulip_open(struct net_device *dev);
-static int tulip_close(struct net_device *dev);
-static void tulip_up(struct net_device *dev);
-static void tulip_down(struct net_device *dev);
-static struct net_device_stats *tulip_get_stats(struct net_device *dev);
-static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static void set_rx_mode(struct net_device *dev);
-
-
-/* Serial EEPROM section. */
-/* The main routine to parse the very complicated SROM structure.
-   Search www.digital.com for "21X4 SROM" to get details.
-   This code is very complex, and will require changes to support
-   additional cards, so I'll be verbose about what is going on.
-   */
-
-/* Known cards that have old-style EEPROMs. */
-static struct fixups {
-  char *name;
-  unsigned char addr0, addr1, addr2;
-  u16 newtable[32];				/* Max length below. */
-} eeprom_fixups[] = {
-  {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c,
-						  0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }},
-  {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f,
-							   0x0000, 0x009E, /* 10baseT */
-							   0x0004, 0x009E, /* 10baseT-FD */
-							   0x0903, 0x006D, /* 100baseTx */
-							   0x0905, 0x006D, /* 100baseTx-FD */ }},
-  {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f,
-								 0x0107, 0x8021, /* 100baseFx */
-								 0x0108, 0x8021, /* 100baseFx-FD */
-								 0x0100, 0x009E, /* 10baseT */
-								 0x0104, 0x009E, /* 10baseT-FD */
-								 0x0103, 0x006D, /* 100baseTx */
-								 0x0105, 0x006D, /* 100baseTx-FD */ }},
-  {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513,
-							   0x1001, 0x009E, /* 10base2, CSR12 0x10*/
-							   0x0000, 0x009E, /* 10baseT */
-							   0x0004, 0x009E, /* 10baseT-FD */
-							   0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */
-							   0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}},
-  {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F,
-								  0x1B01, 0x0000, /* 10base2,   CSR12 0x1B */
-								  0x0B00, 0x009E, /* 10baseT,   CSR12 0x0B */
-								  0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */
-								  0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */
-								  0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */
-   }},
-  {0, 0, 0, 0, {}}};
-
-static const char * block_name[] = {"21140 non-MII", "21140 MII PHY",
- "21142 Serial PHY", "21142 MII PHY", "21143 SYM PHY", "21143 reset method"};
-
-#if defined(__i386__)			/* AKA get_unaligned() */
-#define get_u16(ptr) (*(u16 *)(ptr))
-#else
-#define get_u16(ptr) (((u8*)(ptr))[0] + (((u8*)(ptr))[1]<<8))
-#endif
-
-static void parse_eeprom(struct net_device *dev)
-{
-	/* The last media info list parsed, for multiport boards.  */
-	static struct mediatable *last_mediatable = NULL;
-	static unsigned char *last_ee_data = NULL;
-	static int controller_index = 0;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	unsigned char *ee_data = tp->eeprom;
-	int i;
-
-	tp->mtable = 0;
-	/* Detect an old-style (SA only) EEPROM layout:
-	   memcmp(eedata, eedata+16, 8). */
-	for (i = 0; i < 8; i ++)
-		if (ee_data[i] != ee_data[16+i])
-			break;
-	if (i >= 8) {
-		if (ee_data[0] == 0xff) {
-			if (last_mediatable) {
-				controller_index++;
-				printk(KERN_INFO "%s:  Controller %d of multiport board.\n",
-					   dev->name, controller_index);
-				tp->mtable = last_mediatable;
-				ee_data = last_ee_data;
-				goto subsequent_board;
-			} else
-				printk(KERN_INFO "%s:  Missing EEPROM, this interface may "
-					   "not work correctly!\n",
-			   dev->name);
-			return;
-		}
-	  /* Do a fix-up based on the vendor half of the station address prefix. */
-	  for (i = 0; eeprom_fixups[i].name; i++) {
-		if (dev->dev_addr[0] == eeprom_fixups[i].addr0
-			&&  dev->dev_addr[1] == eeprom_fixups[i].addr1
-			&&  dev->dev_addr[2] == eeprom_fixups[i].addr2) {
-		  if (dev->dev_addr[2] == 0xE8  &&  ee_data[0x1a] == 0x55)
-			  i++;			/* An Accton EN1207, not an outlaw Maxtech. */
-		  memcpy(ee_data + 26, eeprom_fixups[i].newtable,
-				 sizeof(eeprom_fixups[i].newtable));
-		  printk(KERN_INFO "%s: Old format EEPROM on '%s' board.  Using"
-				 " substitute media control info.\n",
-				 dev->name, eeprom_fixups[i].name);
-		  break;
-		}
-	  }
-	  if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
-		  printk(KERN_INFO "%s: Old style EEPROM with no media selection "
-				 "information.\n",
-			   dev->name);
-		return;
-	  }
-	}
-
-	controller_index = 0;
-	if (ee_data[19] > 1) {		/* Multiport board. */
-		last_ee_data = ee_data;
-	}
-subsequent_board:
-
-	if (ee_data[27] == 0) {		/* No valid media table. */
-	} else if (tp->chip_id == DC21041) {
-		unsigned char *p = (void *)ee_data + ee_data[27 + controller_index*3];
-		int media = get_u16(p);
-		int count = p[2];
-		p += 3;
-
-		printk(KERN_INFO "%s: 21041 Media table, default media %4.4x (%s).\n",
-			   dev->name, media,
-			   media & 0x0800 ? "Autosense" : medianame[media & 15]);
-		for (i = 0; i < count; i++) {
-			unsigned char media_code = *p++;
-			if (media_code & 0x40)
-				p += 6;
-			printk(KERN_INFO "%s:  21041 media #%d, %s.\n",
-				   dev->name, media_code & 15, medianame[media_code & 15]);
-		}
-	} else {
-		unsigned char *p = (void *)ee_data + ee_data[27];
-		unsigned char csr12dir = 0;
-		int count, new_advertise = 0;
-		struct mediatable *mtable;
-		u16 media = get_u16(p);
-
-		p += 2;
-		if (tp->flags & CSR12_IN_SROM)
-			csr12dir = *p++;
-		count = *p++;
-		mtable = (struct mediatable *)
-			kmalloc(sizeof(struct mediatable) + count*sizeof(struct medialeaf),
-					GFP_KERNEL);
-		if (mtable == NULL)
-			return;				/* Horrible, impossible failure. */
-		last_mediatable = tp->mtable = mtable;
-		mtable->defaultmedia = media;
-		mtable->leafcount = count;
-		mtable->csr12dir = csr12dir;
-		mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
-		mtable->csr15dir = mtable->csr15val = 0;
-
-		printk(KERN_INFO "%s:  EEPROM default media type %s.\n", dev->name,
-			   media & 0x0800 ? "Autosense" : medianame[media & 15]);
-		for (i = 0; i < count; i++) {
-			struct medialeaf *leaf = &mtable->mleaf[i];
-
-			if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */
-				leaf->type = 0;
-				leaf->media = p[0] & 0x3f;
-				leaf->leafdata = p;
-				if ((p[2] & 0x61) == 0x01)	/* Bogus, but Znyx boards do it. */
-					mtable->has_mii = 1;
-				p += 4;
-			} else {
-				leaf->type = p[1];
-				if (p[1] == 0x05) {
-					mtable->has_reset = i;
-					leaf->media = p[2] & 0x0f;
-				} else if (p[1] & 1) {
-					mtable->has_mii = 1;
-					leaf->media = 11;
-				} else {
-					mtable->has_nonmii = 1;
-					leaf->media = p[2] & 0x0f;
-					switch (leaf->media) {
-					case 0: new_advertise |= 0x0020; break;
-					case 4: new_advertise |= 0x0040; break;
-					case 3: new_advertise |= 0x0080; break;
-					case 5: new_advertise |= 0x0100; break;
-					case 6: new_advertise |= 0x0200; break;
-					}
-					if (p[1] == 2  &&  leaf->media == 0) {
-						if (p[2] & 0x40) {
-							u32 base15 = get_unaligned((u16*)&p[7]);
-							mtable->csr15dir =
-								(get_unaligned((u16*)&p[9])<<16) + base15;
-							mtable->csr15val =
-								(get_unaligned((u16*)&p[11])<<16) + base15;
-						} else {
-							mtable->csr15dir = get_unaligned((u16*)&p[3])<<16;
-							mtable->csr15val = get_unaligned((u16*)&p[5])<<16;
-						}
-					}
-				}
-				leaf->leafdata = p + 2;
-				p += (p[0] & 0x3f) + 1;
-			}
-			if (tulip_debug > 1  &&  leaf->media == 11) {
-				unsigned char *bp = leaf->leafdata;
-				printk(KERN_INFO "%s:  MII interface PHY %d, setup/reset "
-					   "sequences %d/%d long, capabilities %2.2x %2.2x.\n",
-					   dev->name, bp[0], bp[1], bp[2 + bp[1]*2],
-					   bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]);
-			}
-			printk(KERN_INFO "%s:  Index #%d - Media %s (#%d) described "
-				   "by a %s (%d) block.\n",
-				   dev->name, i, medianame[leaf->media], leaf->media,
-				   block_name[leaf->type], leaf->type);
-		}
-		if (new_advertise)
-			tp->to_advertise = new_advertise;
-	}
-}
-/* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/
-
-/*  EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK	0x02	/* EEPROM shift clock. */
-#define EE_CS			0x01	/* EEPROM chip select. */
-#define EE_DATA_WRITE	0x04	/* Data from the Tulip to EEPROM. */
-#define EE_WRITE_0		0x01
-#define EE_WRITE_1		0x05
-#define EE_DATA_READ	0x08	/* Data from the EEPROM chip. */
-#define EE_ENB			(0x4800 | EE_CS)
-
-/* Delay between EEPROM clock transitions.
-   Even at 33Mhz current PCI implementations don't overrun the EEPROM clock.
-   We add a bus turn-around to insure that this remains true. */
-#define eeprom_delay()	inl(ee_addr)
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define EE_READ_CMD		(6)
-
-/* Note: this routine returns extra data bits for size detection. */
-static int __devinit read_eeprom(long ioaddr, int location, int addr_len)
-{
-	int i;
-	unsigned retval = 0;
-	long ee_addr = ioaddr + CSR9;
-	int read_cmd = location | (EE_READ_CMD << addr_len);
-
-	outl(EE_ENB & ~EE_CS, ee_addr);
-	outl(EE_ENB, ee_addr);
-
-	/* Shift the read command bits out. */
-	for (i = 4 + addr_len; i >= 0; i--) {
-		short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
-		outl(EE_ENB | dataval, ee_addr);
-		eeprom_delay();
-		outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
-		eeprom_delay();
-		retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
-	}
-	outl(EE_ENB, ee_addr);
-
-	for (i = 16; i > 0; i--) {
-		outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
-		eeprom_delay();
-		retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
-		outl(EE_ENB, ee_addr);
-		eeprom_delay();
-	}
-
-	/* Terminate the EEPROM access. */
-	outl(EE_ENB & ~EE_CS, ee_addr);
-	return retval;
-}
-
-/* MII transceiver control section.
-   Read and write the MII registers using software-generated serial
-   MDIO protocol.  See the MII specifications or DP83840A data sheet
-   for details. */
-
-/* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
-   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
-   "overclocking" issues or future 66Mhz PCI. */
-#define mdio_delay() inl(mdio_addr)
-
-/* Read and write the MII registers using software-generated serial
-   MDIO protocol.  It is just different enough from the EEPROM protocol
-   to not share code.  The maxium data clock rate is 2.5 Mhz. */
-#define MDIO_SHIFT_CLK	0x10000
-#define MDIO_DATA_WRITE0 0x00000
-#define MDIO_DATA_WRITE1 0x20000
-#define MDIO_ENB		0x00000		/* Ignore the 0x02000 databook setting. */
-#define MDIO_ENB_IN		0x40000
-#define MDIO_DATA_READ	0x80000
-
-static int mdio_read(struct net_device *dev, int phy_id, int location)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	int i;
-	int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
-	int retval = 0;
-	long ioaddr = dev->base_addr;
-	long mdio_addr = ioaddr + CSR9;
-
-	if (tp->chip_id == LC82C168) {
-		int i = 1000;
-		outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
-		inl(ioaddr + 0xA0);
-		inl(ioaddr + 0xA0);
-		while (--i > 0)
-			if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
-				return retval & 0xffff;
-		return 0xffff;
-	}
-
-	if (tp->chip_id == COMET) {
-		if (phy_id == 1) {
-			if (location < 7)
-				return inl(ioaddr + 0xB4 + (location<<2));
-			else if (location == 17)
-				return inl(ioaddr + 0xD0);
-			else if (location >= 29 && location <= 31)
-				return inl(ioaddr + 0xD4 + ((location-29)<<2));
-		}
-		return 0xffff;
-	}
-
-	/* Establish sync by sending at least 32 logic ones. */
-	for (i = 32; i >= 0; i--) {
-		outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
-		mdio_delay();
-		outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
-	/* Shift the read command bits out. */
-	for (i = 15; i >= 0; i--) {
-		int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
-
-		outl(MDIO_ENB | dataval, mdio_addr);
-		mdio_delay();
-		outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
-	/* Read the two transition, 16 data, and wire-idle bits. */
-	for (i = 19; i > 0; i--) {
-		outl(MDIO_ENB_IN, mdio_addr);
-		mdio_delay();
-		retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
-		outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
-	return (retval>>1) & 0xffff;
-}
-
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	int i;
-	int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
-	long ioaddr = dev->base_addr;
-	long mdio_addr = ioaddr + CSR9;
-
-	if (tp->chip_id == LC82C168) {
-		int i = 1000;
-		outl(cmd, ioaddr + 0xA0);
-		do
-			if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
-				break;
-		while (--i > 0);
-		return;
-	}
-
-	if (tp->chip_id == COMET) {
-		if (phy_id != 1)
-			return;
-		if (location < 7)
-			outl(value, ioaddr + 0xB4 + (location<<2));
-		else if (location == 17)
-			outl(value, ioaddr + 0xD0);
-		else if (location >= 29 && location <= 31)
-			outl(value, ioaddr + 0xD4 + ((location-29)<<2));
-		return;
-	}
-
-	/* Establish sync by sending 32 logic ones. */
-	for (i = 32; i >= 0; i--) {
-		outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
-		mdio_delay();
-		outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
-	/* Shift the command bits out. */
-	for (i = 31; i >= 0; i--) {
-		int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
-		outl(MDIO_ENB | dataval, mdio_addr);
-		mdio_delay();
-		outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
-	/* Clear out extra bits. */
-	for (i = 2; i > 0; i--) {
-		outl(MDIO_ENB_IN, mdio_addr);
-		mdio_delay();
-		outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
-	return;
-}
-
-
-/* The Xircom cards are picky about when certain bits in CSR6 can be
-   manipulated.  Keith Owens <kaos@ocs.com.au>. */
-
-static void outl_CSR6 (struct tulip_private *tp, u32 newcsr6)
-{
-	long ioaddr = tp->base_addr;
-	const int strict_bits = 0x0060e202;
-	int csr5, csr5_22_20, csr5_19_17, currcsr6, attempts = 200;
-	long flags;
-
-	/* really a hw lock */
-	spin_lock_irqsave (&tp->tx_lock, flags);
-
-	if (tp->chip_id != X3201_3)
-		goto out_write;
-
-	newcsr6 &= 0x726cfeca;	/* mask out the reserved CSR6 bits that always */
-	/* read 0 on the Xircom cards */
-	newcsr6 |= 0x320c0000;	/* or in the reserved bits that always read 1 */
-	currcsr6 = inl (ioaddr + CSR6);
-	if (((newcsr6 & strict_bits) == (currcsr6 & strict_bits)) ||
-	    ((currcsr6 & ~0x2002) == 0))
-		goto out_write;
-
-	/* make sure the transmitter and receiver are stopped first */
-	currcsr6 &= ~0x2002;
-	while (1) {
-		csr5 = inl (ioaddr + CSR5);
-		if (csr5 == 0xffffffff)
-			break;	/* cannot read csr5, card removed? */
-		csr5_22_20 = csr5 & 0x700000;
-		csr5_19_17 = csr5 & 0x0e0000;
-		if ((csr5_22_20 == 0 || csr5_22_20 == 0x600000) &&
-		    (csr5_19_17 == 0 || csr5_19_17 == 0x80000 || csr5_19_17 == 0xc0000))
-			break;	/* both are stopped or suspended */
-		if (!--attempts) {
-			printk (KERN_INFO "tulip.c: outl_CSR6 too many attempts,"
-				"csr5=0x%08x\n", csr5);
-			goto out_write;
-		}
-		outl (currcsr6, ioaddr + CSR6);
-		udelay (1);
-	}
-
-out_write:
-	/* now it is safe to change csr6 */
-	outl (newcsr6, ioaddr + CSR6);
-
-	spin_unlock_irqrestore (&tp->lock, flags);
-}
-
-
-static void tulip_up(struct net_device *dev)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int next_tick = 3*HZ;
-	int i;
-
-	/* Wake the chip from sleep/snooze mode. */
-	if (tp->flags & HAS_ACPI)
-		pci_write_config_dword(tp->pdev, 0x40, 0);
-
-	/* On some chip revs we must set the MII/SYM port before the reset!? */
-	if (tp->mii_cnt  ||  (tp->mtable  &&  tp->mtable->has_mii))
-		outl_CSR6 (tp, 0x00040000);
-
-	/* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
-	outl(0x00000001, ioaddr + CSR0);
-
-	/* Deassert reset.
-	   Wait the specified 50 PCI cycles after a reset by initializing
-	   Tx and Rx queues and the address filter list. */
-	outl(tp->csr0, ioaddr + CSR0);
-
-	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: tulip_open() irq %d.\n", dev->name, dev->irq);
-
-	if (tp->flags & MC_HASH_ONLY) {
-		u32 addr_low = cpu_to_le32(get_unaligned((u32 *)dev->dev_addr));
-		u32 addr_high = cpu_to_le32(get_unaligned((u16 *)(dev->dev_addr+4)));
-		if (tp->chip_id == AX88140) {
-			outl(0, ioaddr + CSR13);
-			outl(addr_low,  ioaddr + CSR14);
-			outl(1, ioaddr + CSR13);
-			outl(addr_high, ioaddr + CSR14);
-		} else if (tp->chip_id == COMET) {
-			outl(addr_low,  ioaddr + 0xA4);
-			outl(addr_high, ioaddr + 0xA8);
-			outl(0, ioaddr + 0xAC);
-			outl(0, ioaddr + 0xB0);
-		}
-	} else {
-		/* This is set_rx_mode(), but without starting the transmitter. */
-		u16 *eaddrs = (u16 *)dev->dev_addr;
-		u16 *setup_frm = &tp->setup_frame[15*6];
-
-		/* 21140 bug: you must add the broadcast address. */
-		memset(tp->setup_frame, 0xff, sizeof(tp->setup_frame));
-		/* Fill the final entry of the table with our physical address. */
-		*setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
-		*setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
-		*setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
-		/* Put the setup frame on the Tx list. */
-		tp->tx_ring[0].length = cpu_to_le32(0x08000000 | 192);
-		tp->tx_ring[0].buffer1 = virt_to_le32desc(tp->setup_frame);
-		tp->tx_ring[0].status = cpu_to_le32(DescOwned);
-
-		tp->cur_tx++;
-	}
-
-	outl(virt_to_bus(tp->rx_ring), ioaddr + CSR3);
-	outl(virt_to_bus(tp->tx_ring), ioaddr + CSR4);
-
-	tp->saved_if_port = dev->if_port;
-	if (dev->if_port == 0)
-		dev->if_port = tp->default_port;
-
-	/* Allow selecting a default media. */
-	i = 0;
-	if (tp->mtable == NULL)
-		goto media_picked;
-	if (dev->if_port) {
-		int looking_for = media_cap[dev->if_port] & MediaIsMII ? 11 :
-			(dev->if_port == 12 ? 0 : dev->if_port);
-		for (i = 0; i < tp->mtable->leafcount; i++)
-			if (tp->mtable->mleaf[i].media == looking_for) {
-				printk(KERN_INFO "%s: Using user-specified media %s.\n",
-					   dev->name, medianame[dev->if_port]);
-				goto media_picked;
-			}
-	}
-	if ((tp->mtable->defaultmedia & 0x0800) == 0) {
-		int looking_for = tp->mtable->defaultmedia & 15;
-		for (i = 0; i < tp->mtable->leafcount; i++)
-			if (tp->mtable->mleaf[i].media == looking_for) {
-				printk(KERN_INFO "%s: Using EEPROM-set media %s.\n",
-					   dev->name, medianame[looking_for]);
-				goto media_picked;
-			}
-	}
-	/* Start sensing first non-full-duplex media. */
-	for (i = tp->mtable->leafcount - 1;
-		 (media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--)
-		;
-media_picked:
-
-	tp->csr6 = 0;
-	tp->cur_index = i;
-	tp->nwayset = 0;
-	if (dev->if_port == 0  && tp->chip_id == DC21041) {
-		tp->nway = 1;
-	}
-	if (dev->if_port == 0  &&  tp->chip_id == DC21142) {
-		if (tp->mii_cnt) {
-			select_media(dev, 1);
-			if (tulip_debug > 1)
-				printk(KERN_INFO "%s: Using MII transceiver %d, status "
-					   "%4.4x.\n",
-					   dev->name, tp->phys[0], mdio_read(dev, tp->phys[0], 1));
-			outl_CSR6(tp, 0x82020000);
-			tp->csr6 = 0x820E0000;
-			dev->if_port = 11;
-			outl(0x0000, ioaddr + CSR13);
-			outl(0x0000, ioaddr + CSR14);
-		} else
-			t21142_start_nway(dev);
-	} else if (tp->chip_id == PNIC2) {
-		t21142_start_nway(dev);
-	} else if (tp->chip_id == LC82C168  &&  ! tp->medialock) {
-		if (tp->mii_cnt) {
-			dev->if_port = 11;
-			tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0);
-			outl(0x0001, ioaddr + CSR15);
-		} else if (inl(ioaddr + CSR5) & TPLnkPass)
-			pnic_do_nway(dev);
-		else {
-			/* Start with 10mbps to do autonegotiation. */
-			outl(0x32, ioaddr + CSR12);
-			tp->csr6 = 0x00420000;
-			outl(0x0001B078, ioaddr + 0xB8);
-			outl(0x0201B078, ioaddr + 0xB8);
-			next_tick = 1*HZ;
-		}
-	} else if ((tp->chip_id == MX98713 || tp->chip_id == COMPEX9881)
-			   && ! tp->medialock) {
-		dev->if_port = 0;
-		tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0);
-		outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
-	} else if (tp->chip_id == MX98715 || tp->chip_id == MX98725) {
-		/* Provided by BOLO, Macronix - 12/10/1998. */
-		dev->if_port = 0;
-		tp->csr6 = 0x01a80200;
-		outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
-		outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0);
-	} else if (tp->chip_id == DC21143  &&
-			   media_cap[dev->if_port] & MediaIsMII) {
-		/* We must reset the media CSRs when we force-select MII mode. */
-		outl(0x0000, ioaddr + CSR13);
-		outl(0x0000, ioaddr + CSR14);
-		outl(0x0008, ioaddr + CSR15);
-	} else if (tp->chip_id == COMET) {
-		dev->if_port = 0;
-		tp->csr6 = 0x00040000;
-	} else if (tp->chip_id == AX88140) {
-		tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100;
-	} else
-		select_media(dev, 1);
-
-	/* Start the chip's Tx to process setup frame. */
-	outl_CSR6(tp, tp->csr6);
-	outl_CSR6(tp, tp->csr6 | 0x2000);
-
-	/* Enable interrupts by setting the interrupt mask. */
-	outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5);
-	outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
-	outl_CSR6(tp, tp->csr6 | 0x2002);
-	outl(0, ioaddr + CSR2);		/* Rx poll demand */
-
-	if (tulip_debug > 2) {
-		printk(KERN_DEBUG "%s: Done tulip_open(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n",
-			   dev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR5),
-			   inl(ioaddr + CSR6));
-	}
-	/* Set the timer to switch to check for link beat and perhaps switch
-	   to an alternate media type. */
-	init_timer(&tp->timer);
-	tp->timer.expires = RUN_AT(next_tick);
-	tp->timer.data = (unsigned long)dev;
-	tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
-	add_timer(&tp->timer);
-
-	netif_device_attach(dev);
-}
-
-
-static int
-tulip_open(struct net_device *dev)
-{
-	MOD_INC_USE_COUNT;
-	
-	if (request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev)) {
-		MOD_DEC_USE_COUNT;
-		return -EBUSY;
-	}
-
-	tulip_init_ring (dev);
-	
-	tulip_up (dev);
-	
-	return 0;
-}
-
-
-/* Set up the transceiver control registers for the selected media type. */
-static void select_media(struct net_device *dev, int startup)
-{
-	long ioaddr = dev->base_addr;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	struct mediatable *mtable = tp->mtable;
-	u32 new_csr6;
-	int i;
-
-	if (mtable) {
-		struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index];
-		unsigned char *p = mleaf->leafdata;
-		switch (mleaf->type) {
-		case 0:					/* 21140 non-MII xcvr. */
-			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s: Using a 21140 non-MII transceiver"
-					   " with control setting %2.2x.\n",
-					   dev->name, p[1]);
-			dev->if_port = p[0];
-			if (startup)
-				outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
-			outl(p[1], ioaddr + CSR12);
-			new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18);
-			break;
-		case 2: case 4: {
-			u16 setup[5];
-			u32 csr13val, csr14val, csr15dir, csr15val;
-			for (i = 0; i < 5; i++)
-				setup[i] = get_u16(&p[i*2 + 1]);
-
-			dev->if_port = p[0] & 15;
-			if (media_cap[dev->if_port] & MediaAlwaysFD)
-				tp->full_duplex = 1;
-
-			if (startup && mtable->has_reset) {
-				struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
-				unsigned char *rst = rleaf->leafdata;
-				if (tulip_debug > 1)
-					printk(KERN_DEBUG "%s: Resetting the transceiver.\n",
-						   dev->name);
-				for (i = 0; i < rst[0]; i++)
-					outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
-			}
-			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s: 21143 non-MII %s transceiver control "
-					   "%4.4x/%4.4x.\n",
-					   dev->name, medianame[dev->if_port], setup[0], setup[1]);
-			if (p[0] & 0x40) {	/* SIA (CSR13-15) setup values are provided. */
-				csr13val = setup[0];
-				csr14val = setup[1];
-				csr15dir = (setup[3]<<16) | setup[2];
-				csr15val = (setup[4]<<16) | setup[2];
-				outl(0, ioaddr + CSR13);
-				outl(csr14val, ioaddr + CSR14);
-				outl(csr15dir, ioaddr + CSR15);	/* Direction */
-				outl(csr15val, ioaddr + CSR15);	/* Data */
-				outl(csr13val, ioaddr + CSR13);
-			} else {
-				csr13val = 1;
-				csr14val = 0x0003FF7F;
-				csr15dir = (setup[0]<<16) | 0x0008;
-				csr15val = (setup[1]<<16) | 0x0008;
-				if (dev->if_port <= 4)
-					csr14val = t21142_csr14[dev->if_port];
-				if (startup) {
-					outl(0, ioaddr + CSR13);
-					outl(csr14val, ioaddr + CSR14);
-				}
-				outl(csr15dir, ioaddr + CSR15);	/* Direction */
-				outl(csr15val, ioaddr + CSR15);	/* Data */
-				if (startup) outl(csr13val, ioaddr + CSR13);
-			}
-			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s:  Setting CSR15 to %8.8x/%8.8x.\n",
-					   dev->name, csr15dir, csr15val);
-			if (mleaf->type == 4)
-				new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
-			else
-				new_csr6 = 0x82420000;
-			break;
-		}
-		case 1: case 3: {
-			int phy_num = p[0];
-			int init_length = p[1];
-			u16 *misc_info;
-			u16 to_advertise;
-
-			dev->if_port = 11;
-			new_csr6 = 0x020E0000;
-			if (mleaf->type == 3) {	/* 21142 */
-				u16 *init_sequence = (u16*)(p+2);
-				u16 *reset_sequence = &((u16*)(p+3))[init_length];
-				int reset_length = p[2 + init_length*2];
-				misc_info = reset_sequence + reset_length;
-				if (startup)
-					for (i = 0; i < reset_length; i++)
-						outl(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
-				for (i = 0; i < init_length; i++)
-					outl(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
-			} else {
-				u8 *init_sequence = p + 2;
-				u8 *reset_sequence = p + 3 + init_length;
-				int reset_length = p[2 + init_length];
-				misc_info = (u16*)(reset_sequence + reset_length);
-				if (startup) {
-					outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
-					for (i = 0; i < reset_length; i++)
-						outl(reset_sequence[i], ioaddr + CSR12);
-				}
-				for (i = 0; i < init_length; i++)
-					outl(init_sequence[i], ioaddr + CSR12);
-			}
-			to_advertise = (get_u16(&misc_info[1]) & tp->to_advertise) | 1;
-			tp->advertising[phy_num] = to_advertise;
-			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s:  Advertising %4.4x on PHY %d (%d).\n",
-					   dev->name, to_advertise, phy_num, tp->phys[phy_num]);
-			/* Bogus: put in by a committee?  */
-			mdio_write(dev, tp->phys[phy_num], 4, to_advertise);
-			break;
-		}
-		default:
-			printk(KERN_DEBUG "%s:  Invalid media table selection %d.\n",
-					   dev->name, mleaf->type);
-			new_csr6 = 0x020E0000;
-		}
-		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: Using media type %s, CSR12 is %2.2x.\n",
-				   dev->name, medianame[dev->if_port],
-				   inl(ioaddr + CSR12) & 0xff);
-	} else if (tp->chip_id == DC21041) {
-		int port = dev->if_port <= 4 ? dev->if_port : 0;
-		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: 21041 using media %s, CSR12 is %4.4x.\n",
-				   dev->name, medianame[port == 3 ? 12: port],
-				   inl(ioaddr + CSR12));
-		outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
-		outl(t21041_csr14[port], ioaddr + CSR14);
-		outl(t21041_csr15[port], ioaddr + CSR15);
-		outl(t21041_csr13[port], ioaddr + CSR13);
-		new_csr6 = 0x80020000;
-	} else if (tp->chip_id == LC82C168) {
-		if (startup && ! tp->medialock)
-			dev->if_port = tp->mii_cnt ? 11 : 0;
-		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: PNIC PHY status is %3.3x, media %s.\n",
-				   dev->name, inl(ioaddr + 0xB8), medianame[dev->if_port]);
-		if (tp->mii_cnt) {
-			new_csr6 = 0x810C0000;
-			outl(0x0001, ioaddr + CSR15);
-			outl(0x0201B07A, ioaddr + 0xB8);
-		} else if (startup) {
-			/* Start with 10mbps to do autonegotiation. */
-			outl(0x32, ioaddr + CSR12);
-			new_csr6 = 0x00420000;
-			outl(0x0001B078, ioaddr + 0xB8);
-			outl(0x0201B078, ioaddr + 0xB8);
-		} else if (dev->if_port == 3  ||  dev->if_port == 5) {
-			outl(0x33, ioaddr + CSR12);
-			new_csr6 = 0x01860000;
-			/* Trigger autonegotiation. */
-			outl(startup ? 0x0201F868 : 0x0001F868, ioaddr + 0xB8);
-		} else {
-			outl(0x32, ioaddr + CSR12);
-			new_csr6 = 0x00420000;
-			outl(0x1F078, ioaddr + 0xB8);
-		}
-	} else if (tp->chip_id == DC21040) {					/* 21040 */
-		/* Turn on the xcvr interface. */
-		int csr12 = inl(ioaddr + CSR12);
-		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: 21040 media type is %s, CSR12 is %2.2x.\n",
-				   dev->name, medianame[dev->if_port], csr12);
-		if (media_cap[dev->if_port] & MediaAlwaysFD)
-			tp->full_duplex = 1;
-		new_csr6 = 0x20000;
-		/* Set the full duplux match frame. */
-		outl(FULL_DUPLEX_MAGIC, ioaddr + CSR11);
-		outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
-		if (t21040_csr13[dev->if_port] & 8) {
-			outl(0x0705, ioaddr + CSR14);
-			outl(0x0006, ioaddr + CSR15);
-		} else {
-			outl(0xffff, ioaddr + CSR14);
-			outl(0x0000, ioaddr + CSR15);
-		}
-		outl(0x8f01 | t21040_csr13[dev->if_port], ioaddr + CSR13);
-	} else {					/* Unknown chip type with no media table. */
-		if (tp->default_port == 0)
-			dev->if_port = tp->mii_cnt ? 11 : 3;
-		if (media_cap[dev->if_port] & MediaIsMII) {
-			new_csr6 = 0x020E0000;
-		} else if (media_cap[dev->if_port] & MediaIsFx) {
-			new_csr6 = 0x028600000;
-		} else
-			new_csr6 = 0x038600000;
-		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: No media description table, assuming "
-				   "%s transceiver, CSR12 %2.2x.\n",
-				   dev->name, medianame[dev->if_port],
-				   inl(ioaddr + CSR12));
-	}
-
-	tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
-	return;
-}
-
-/*
-  Check the MII negotiated duplex, and change the CSR6 setting if
-  required.
-  Return 0 if everything is OK.
-  Return < 0 if the transceiver is missing or has no link beat.
-  */
-static int check_duplex(struct net_device *dev)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	int mii_reg1, mii_reg5, negotiated, duplex;
-
-	if (tp->full_duplex_lock)
-		return 0;
-	mii_reg1 = mdio_read(dev, tp->phys[0], 1);
-	mii_reg5 = mdio_read(dev, tp->phys[0], 5);
-	if (tulip_debug > 1)
-		printk(KERN_INFO "%s: MII status %4.4x, Link partner report "
-			   "%4.4x.\n", dev->name, mii_reg1, mii_reg5);
-	if (mii_reg1 == 0xffff)
-		return -2;
-	if ((mii_reg1 & 0x0004) == 0) {
-		int new_reg1 = mdio_read(dev, tp->phys[0], 1);
-		if ((new_reg1 & 0x0004) == 0) {
-			if (tulip_debug  > 1)
-				printk(KERN_INFO "%s: No link beat on the MII interface,"
-					   " status %4.4x.\n", dev->name, new_reg1);
-			return -1;
-		}
-	}
-	negotiated = mii_reg5 & tp->advertising[0];
-	duplex = ((negotiated & 0x0300) == 0x0100
-			  || (negotiated & 0x00C0) == 0x0040);
-	/* 100baseTx-FD  or  10T-FD, but not 100-HD */
-	if (tp->full_duplex != duplex) {
-		tp->full_duplex = duplex;
-		if (negotiated & 0x038)	/* 100mbps. */
-			tp->csr6 &= ~0x00400000;
-		if (tp->full_duplex) tp->csr6 |= 0x0200;
-		else				 tp->csr6 &= ~0x0200;
-		outl_CSR6(tp, tp->csr6 | 0x0002);
-		outl_CSR6(tp, tp->csr6 | 0x2002);
-		if (tulip_debug > 0)
-			printk(KERN_INFO "%s: Setting %s-duplex based on MII"
-				   "#%d link partner capability of %4.4x.\n",
-				   dev->name, tp->full_duplex ? "full" : "half",
-				   tp->phys[0], mii_reg5);
-		return 1;
-	}
-	return 0;
-}
-
-static void tulip_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	u32 csr12 = inl(ioaddr + CSR12);
-	int next_tick = 2*HZ;
-
-	if (tulip_debug > 2) {
-		printk(KERN_DEBUG "%s: Media selection tick, %s, status %8.8x mode"
-			   " %8.8x SIA %8.8x %8.8x %8.8x %8.8x.\n",
-			   dev->name, medianame[dev->if_port], inl(ioaddr + CSR5),
-			   inl(ioaddr + CSR6), csr12, inl(ioaddr + CSR13),
-			   inl(ioaddr + CSR14), inl(ioaddr + CSR15));
-	}
-	switch (tp->chip_id) {
-	case DC21040:
-		if (!tp->medialock  &&  csr12 & 0x0002) { /* Network error */
-			printk(KERN_INFO "%s: No link beat found.\n",
-				   dev->name);
-			dev->if_port = (dev->if_port == 2 ? 0 : 2);
-			select_media(dev, 0);
-			dev->trans_start = jiffies;
-		}
-		break;
-	case DC21041:
-		if (tulip_debug > 2)
-			printk(KERN_DEBUG "%s: 21041 media tick  CSR12 %8.8x.\n",
-				   dev->name, csr12);
-		if (tp->medialock) break;
-		switch (dev->if_port) {
-		case 0: case 3: case 4:
-		  if (csr12 & 0x0004) { /*LnkFail */
-			/* 10baseT is dead.  Check for activity on alternate port. */
-			tp->mediasense = 1;
-			if (csr12 & 0x0200)
-				dev->if_port = 2;
-			else
-				dev->if_port = 1;
-			printk(KERN_INFO "%s: No 21041 10baseT link beat, Media switched to %s.\n",
-				   dev->name, medianame[dev->if_port]);
-			outl(0, ioaddr + CSR13); /* Reset */
-			outl(t21041_csr14[dev->if_port], ioaddr + CSR14);
-			outl(t21041_csr15[dev->if_port], ioaddr + CSR15);
-			outl(t21041_csr13[dev->if_port], ioaddr + CSR13);
-			next_tick = 10*HZ;			/* 2.4 sec. */
-		  } else
-			next_tick = 30*HZ;
-		  break;
-		case 1:					/* 10base2 */
-		case 2:					/* AUI */
-			if (csr12 & 0x0100) {
-				next_tick = (30*HZ);			/* 30 sec. */
-				tp->mediasense = 0;
-			} else if ((csr12 & 0x0004) == 0) {
-				printk(KERN_INFO "%s: 21041 media switched to 10baseT.\n",
-					   dev->name);
-				dev->if_port = 0;
-				select_media(dev, 0);
-				next_tick = (24*HZ)/10;				/* 2.4 sec. */
-			} else if (tp->mediasense || (csr12 & 0x0002)) {
-				dev->if_port = 3 - dev->if_port; /* Swap ports. */
-				select_media(dev, 0);
-				next_tick = 20*HZ;
-			} else {
-				next_tick = 20*HZ;
-			}
-			break;
-		}
-		break;
-	case DC21140:  case DC21142: case MX98713: case COMPEX9881: default: {
-		struct medialeaf *mleaf;
-		unsigned char *p;
-		if (tp->mtable == NULL) {	/* No EEPROM info, use generic code. */
-			/* Not much that can be done.
-			   Assume this a generic MII or SYM transceiver. */
-			next_tick = 60*HZ;
-			if (tulip_debug > 2)
-				printk(KERN_DEBUG "%s: network media monitor CSR6 %8.8x "
-					   "CSR12 0x%2.2x.\n",
-					   dev->name, inl(ioaddr + CSR6), csr12 & 0xff);
-			break;
-		}
-		mleaf = &tp->mtable->mleaf[tp->cur_index];
-		p = mleaf->leafdata;
-		switch (mleaf->type) {
-		case 0: case 4: {
-			/* Type 0 serial or 4 SYM transceiver.  Check the link beat bit. */
-			int offset = mleaf->type == 4 ? 5 : 2;
-			s8 bitnum = p[offset];
-			if (p[offset+1] & 0x80) {
-				if (tulip_debug > 1)
-					printk(KERN_DEBUG"%s: Transceiver monitor tick "
-						   "CSR12=%#2.2x, no media sense.\n",
-						   dev->name, csr12);
-				if (mleaf->type == 4) {
-					if (mleaf->media == 3 && (csr12 & 0x02))
-						goto select_next_media;
-				}
-				break;
-			}
-			if (tulip_debug > 2)
-				printk(KERN_DEBUG "%s: Transceiver monitor tick: CSR12=%#2.2x"
-					   " bit %d is %d, expecting %d.\n",
-					   dev->name, csr12, (bitnum >> 1) & 7,
-					   (csr12 & (1 << ((bitnum >> 1) & 7))) != 0,
-					   (bitnum >= 0));
-			/* Check that the specified bit has the proper value. */
-			if ((bitnum < 0) !=
-				((csr12 & (1 << ((bitnum >> 1) & 7))) != 0)) {
-				if (tulip_debug > 1)
-					printk(KERN_DEBUG "%s: Link beat detected for %s.\n", dev->name,
-						   medianame[mleaf->media]);
-				if ((p[2] & 0x61) == 0x01)	/* Bogus Znyx board. */
-					goto actually_mii;
-				break;
-			}
-			if (tp->medialock)
-				break;
-	  select_next_media:
-			if (--tp->cur_index < 0) {
-				/* We start again, but should instead look for default. */
-				tp->cur_index = tp->mtable->leafcount - 1;
-			}
-			dev->if_port = tp->mtable->mleaf[tp->cur_index].media;
-			if (media_cap[dev->if_port] & MediaIsFD)
-				goto select_next_media; /* Skip FD entries. */
-			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s: No link beat on media %s,"
-					   " trying transceiver type %s.\n",
-					   dev->name, medianame[mleaf->media & 15],
-					   medianame[tp->mtable->mleaf[tp->cur_index].media]);
-			select_media(dev, 0);
-			/* Restart the transmit process. */
-			outl_CSR6(tp, tp->csr6 | 0x0002);
-			outl_CSR6(tp, tp->csr6 | 0x2002);
-			next_tick = (24*HZ)/10;
-			break;
-		}
-		case 1:  case 3:		/* 21140, 21142 MII */
-		actually_mii:
-			check_duplex(dev);
-			next_tick = 60*HZ;
-			break;
-		case 2:					/* 21142 serial block has no link beat. */
-		default:
-			break;
-		}
-	}
-	break;
-	}
-	tp->timer.expires = RUN_AT(next_tick);
-	add_timer(&tp->timer);
-}
-
-
-/* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list
-   of available transceivers.  */
-static void t21142_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int csr12 = inl(ioaddr + CSR12);
-	int next_tick = 60*HZ;
-	int new_csr6 = 0;
-
-	if (tulip_debug > 2)
-		printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n",
-			   dev->name, csr12, medianame[dev->if_port]);
-	if (media_cap[dev->if_port] & MediaIsMII) {
-		check_duplex(dev);
-		next_tick = 60*HZ;
-	} else if (tp->nwayset) {
-		/* Don't screw up a negotiated session! */
-		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: Using NWay-set %s media, csr12 %8.8x.\n",
-				   dev->name, medianame[dev->if_port], csr12);
-	} else if (tp->medialock) {
-			;
-	} else if (dev->if_port == 3) {
-		if (csr12 & 2) {	/* No 100mbps link beat, revert to 10mbps. */
-			if (tulip_debug > 1)
-				printk(KERN_INFO"%s: No 21143 100baseTx link beat, %8.8x, "
-					   "trying NWay.\n", dev->name, csr12);
-			t21142_start_nway(dev);
-			next_tick = 3*HZ;
-		}
-	} else if ((csr12 & 0x7000) != 0x5000) {
-		/* Negotiation failed.  Search media types. */
-		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: 21143 negotiation failed, status %8.8x.\n",
-				   dev->name, csr12);
-		if (!(csr12 & 4)) {		/* 10mbps link beat good. */
-			new_csr6 = 0x82420000;
-			dev->if_port = 0;
-			outl(0, ioaddr + CSR13);
-			outl(0x0003FFFF, ioaddr + CSR14);
-			outw(t21142_csr15[dev->if_port], ioaddr + CSR15);
-			outl(t21142_csr13[dev->if_port], ioaddr + CSR13);
-		} else {
-			/* Select 100mbps port to check for link beat. */
-			new_csr6 = 0x83860000;
-			dev->if_port = 3;
-			outl(0, ioaddr + CSR13);
-			outl(0x0003FF7F, ioaddr + CSR14);
-			outw(8, ioaddr + CSR15);
-			outl(1, ioaddr + CSR13);
-		}
-		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: Testing new 21143 media %s.\n",
-				   dev->name, medianame[dev->if_port]);
-		if (new_csr6 != (tp->csr6 & ~0x00D5)) {
-			tp->csr6 &= 0x00D5;
-			tp->csr6 |= new_csr6;
-			outl(0x0301, ioaddr + CSR12);
-			outl_CSR6(tp, tp->csr6 | 0x0002);
-			outl_CSR6(tp, tp->csr6 | 0x2002);
-		}
-		next_tick = 3*HZ;
-	}
-
-	tp->timer.expires = RUN_AT(next_tick);
-	add_timer(&tp->timer);
-}
-
-
-static void t21142_start_nway(struct net_device *dev)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int csr14 = ((tp->to_advertise & 0x0780) << 9)  |
-		((tp->to_advertise&0x0020)<<1) | 0xffbf;
-
-	dev->if_port = 0;
-	tp->nway = tp->mediasense = 1;
-	tp->nwayset = tp->lpar = 0;
-	if (debug > 1)
-		printk(KERN_DEBUG "%s: Restarting 21143 autonegotiation, %8.8x.\n",
-			   dev->name, csr14);
-	outl(0x0001, ioaddr + CSR13);
-	outl(csr14, ioaddr + CSR14);
-	tp->csr6 = 0x82420000 | (tp->to_advertise & 0x0040 ? 0x0200 : 0);
-	outl_CSR6(tp, tp->csr6);
-	if (tp->mtable  &&  tp->mtable->csr15dir) {
-		outl(tp->mtable->csr15dir, ioaddr + CSR15);
-		outl(tp->mtable->csr15val, ioaddr + CSR15);
-	} else
-		outw(0x0008, ioaddr + CSR15);
-	outl(0x1301, ioaddr + CSR12); 		/* Trigger NWAY. */
-}
-
-
-static void t21142_lnk_change(struct net_device *dev, int csr5)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int csr12 = inl(ioaddr + CSR12);
-
-	if (tulip_debug > 1)
-		printk(KERN_INFO"%s: 21143 link status interrupt %8.8x, CSR5 %x, "
-			   "%8.8x.\n", dev->name, csr12, csr5, inl(ioaddr + CSR14));
-
-	/* If NWay finished and we have a negotiated partner capability. */
-	if (tp->nway  &&  !tp->nwayset  &&  (csr12 & 0x7000) == 0x5000) {
-		int setup_done = 0;
-		int negotiated = tp->to_advertise & (csr12 >> 16);
-		tp->lpar = csr12 >> 16;
-		tp->nwayset = 1;
-		if (negotiated & 0x0100)		dev->if_port = 5;
-		else if (negotiated & 0x0080)	dev->if_port = 3;
-		else if (negotiated & 0x0040)	dev->if_port = 4;
-		else if (negotiated & 0x0020)	dev->if_port = 0;
-		else {
-			tp->nwayset = 0;
-			if ((csr12 & 2) == 0  &&  (tp->to_advertise & 0x0180))
-				dev->if_port = 3;
-		}
-		tp->full_duplex = (media_cap[dev->if_port] & MediaAlwaysFD) ? 1:0;
-
-		if (tulip_debug > 1) {
-			if (tp->nwayset)
-				printk(KERN_INFO "%s: Switching to %s based on link "
-					   "negotiation %4.4x & %4.4x = %4.4x.\n",
-					   dev->name, medianame[dev->if_port], tp->to_advertise,
-					   tp->lpar, negotiated);
-			else
-				printk(KERN_INFO "%s: Autonegotiation failed, using %s,"
-					   " link beat status %4.4x.\n",
-					   dev->name, medianame[dev->if_port], csr12);
-		}
-
-		if (tp->mtable) {
-			int i;
-			for (i = 0; i < tp->mtable->leafcount; i++)
-				if (tp->mtable->mleaf[i].media == dev->if_port) {
-					tp->cur_index = i;
-					select_media(dev, 0);
-					setup_done = 1;
-					break;
-				}
-		}
-		if ( ! setup_done) {
-			tp->csr6 = dev->if_port & 1 ? 0x83860000 : 0x82420000;
-			if (tp->full_duplex)
-				tp->csr6 |= 0x0200;
-			outl(1, ioaddr + CSR13);
-		}
-#if 0							/* Restart shouldn't be needed. */
-		outl_CSR6(tp, tp->csr6 | 0x0000);
-		if (debug > 2)
-			printk(KERN_DEBUG "%s:  Restarting Tx and Rx, CSR5 is %8.8x.\n",
-				   dev->name, inl(ioaddr + CSR5));
-#endif
-		outl_CSR6(tp, tp->csr6 | 0x2002);
-		if (debug > 2)
-			printk(KERN_DEBUG "%s:  Setting CSR6 %8.8x/%x CSR12 %8.8x.\n",
-				   dev->name, tp->csr6, inl(ioaddr + CSR6),
-				   inl(ioaddr + CSR12));
-	} else if ((tp->nwayset  &&  (csr5 & 0x08000000)
-				&& (dev->if_port == 3  ||  dev->if_port == 5)
-				&& (csr12 & 2) == 2) ||
-			   (tp->nway && (csr5 & (TPLnkFail)))) {
-		/* Link blew? Maybe restart NWay. */
-		del_timer(&tp->timer);
-		t21142_start_nway(dev);
-		tp->timer.expires = RUN_AT(3*HZ);
-		add_timer(&tp->timer);
-	} else if (dev->if_port == 3  ||  dev->if_port == 5) {
-		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: 21143 %s link beat %s.\n",
-				   dev->name, medianame[dev->if_port],
-				   (csr12 & 2) ? "failed" : "good");
-		if ((csr12 & 2)  &&  ! tp->medialock) {
-			del_timer(&tp->timer);
-			t21142_start_nway(dev);
-			tp->timer.expires = RUN_AT(3*HZ);
-			add_timer(&tp->timer);
-		}
-	} else if (dev->if_port == 0  ||  dev->if_port == 4) {
-		if ((csr12 & 4) == 0)
-			printk(KERN_INFO"%s: 21143 10baseT link beat good.\n",
-				   dev->name);
-	} else if (!(csr12 & 4)) {		/* 10mbps link beat good. */
-		if (tulip_debug)
-			printk(KERN_INFO"%s: 21143 10mbps sensed media.\n",
-				   dev->name);
-		dev->if_port = 0;
-	} else if (tp->nwayset) {
-		if (tulip_debug)
-			printk(KERN_INFO"%s: 21143 using NWay-set %s, csr6 %8.8x.\n",
-				   dev->name, medianame[dev->if_port], tp->csr6);
-	} else {		/* 100mbps link beat good. */
-		if (tulip_debug)
-			printk(KERN_INFO"%s: 21143 100baseTx sensed media.\n",
-				   dev->name);
-		dev->if_port = 3;
-		tp->csr6 = 0x83860000;
-		outl(0x0003FF7F, ioaddr + CSR14);
-		outl(0x0301, ioaddr + CSR12);
-		outl_CSR6(tp, tp->csr6 | 0x0002);
-		outl_CSR6(tp, tp->csr6 | 0x2002);
-	}
-}
-
-
-static void mxic_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int next_tick = 60*HZ;
-
-	if (tulip_debug > 3) {
-		printk(KERN_INFO"%s: MXIC negotiation status %8.8x.\n", dev->name,
-			   inl(ioaddr + CSR12));
-	}
-	if (next_tick) {
-		tp->timer.expires = RUN_AT(next_tick);
-		add_timer(&tp->timer);
-	}
-}
-
-
-static void pnic_do_nway(struct net_device *dev)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	u32 phy_reg = inl(ioaddr + 0xB8);
-	u32 new_csr6 = tp->csr6 & ~0x40C40200;
-
-	if (phy_reg & 0x78000000) { /* Ignore baseT4 */
-		if (phy_reg & 0x20000000)		dev->if_port = 5;
-		else if (phy_reg & 0x40000000)	dev->if_port = 3;
-		else if (phy_reg & 0x10000000)	dev->if_port = 4;
-		else if (phy_reg & 0x08000000)	dev->if_port = 0;
-		tp->nwayset = 1;
-		new_csr6 = (dev->if_port & 1) ? 0x01860000 : 0x00420000;
-		outl(0x32 | (dev->if_port & 1), ioaddr + CSR12);
-		if (dev->if_port & 1)
-			outl(0x1F868, ioaddr + 0xB8);
-		if (phy_reg & 0x30000000) {
-			tp->full_duplex = 1;
-			new_csr6 |= 0x00000200;
-		}
-		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: PNIC autonegotiated status %8.8x, %s.\n",
-				   dev->name, phy_reg, medianame[dev->if_port]);
-		if (tp->csr6 != new_csr6) {
-			tp->csr6 = new_csr6;
-			/* Restart Tx */
-			outl_CSR6(tp, tp->csr6 | 0x0002);
-			outl_CSR6(tp, tp->csr6 | 0x2002);
-			dev->trans_start = jiffies;
-		}
-	}
-}
-
-
-static void pnic_lnk_change(struct net_device *dev, int csr5)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int phy_reg = inl(ioaddr + 0xB8);
-
-	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: PNIC link changed state %8.8x, CSR5 %8.8x.\n",
-			   dev->name, phy_reg, csr5);
-	if (inl(ioaddr + CSR5) & TPLnkFail) {
-		outl((inl(ioaddr + CSR7) & ~TPLnkFail) | TPLnkPass, ioaddr + CSR7);
-		if (! tp->nwayset  ||  jiffies - dev->trans_start > 1*HZ) {
-			tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff);
-			outl_CSR6(tp, tp->csr6);
-			outl(0x30, ioaddr + CSR12);
-			outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */
-			dev->trans_start = jiffies;
-		}
-	} else if (inl(ioaddr + CSR5) & TPLnkPass) {
-		pnic_do_nway(dev);
-		outl((inl(ioaddr + CSR7) & ~TPLnkPass) | TPLnkFail, ioaddr + CSR7);
-	}
-}
-
-
-static void pnic_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int next_tick = 60*HZ;
-
-	if (media_cap[dev->if_port] & MediaIsMII) {
-		if (check_duplex(dev) > 0)
-			next_tick = 3*HZ;
-	} else {
-		int csr12 = inl(ioaddr + CSR12);
-		int new_csr6 = tp->csr6 & ~0x40C40200;
-		int phy_reg = inl(ioaddr + 0xB8);
-		int csr5 = inl(ioaddr + CSR5);
-
-		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: PNIC timer PHY status %8.8x, %s "
-				   "CSR5 %8.8x.\n",
-				   dev->name, phy_reg, medianame[dev->if_port], csr5);
-		if (phy_reg & 0x04000000) {	/* Remote link fault */
-			outl(0x0201F078, ioaddr + 0xB8);
-			next_tick = 1*HZ;
-			tp->nwayset = 0;
-		} else if (phy_reg & 0x78000000) { /* Ignore baseT4 */
-			pnic_do_nway(dev);
-			next_tick = 60*HZ;
-		} else if (csr5 & TPLnkFail) { /* 100baseTx link beat */
-			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s: %s link beat failed, CSR12 %4.4x, "
-					   "CSR5 %8.8x, PHY %3.3x.\n",
-					   dev->name, medianame[dev->if_port], csr12,
-					   inl(ioaddr + CSR5), inl(ioaddr + 0xB8));
-			next_tick = 3*HZ;
-			if (tp->medialock) {
-			} else if (tp->nwayset  &&  (dev->if_port & 1)) {
-				next_tick = 1*HZ;
-			} else if (dev->if_port == 0) {
-				dev->if_port = 3;
-				outl(0x33, ioaddr + CSR12);
-				new_csr6 = 0x01860000;
-				outl(0x1F868, ioaddr + 0xB8);
-			} else {
-				dev->if_port = 0;
-				outl(0x32, ioaddr + CSR12);
-				new_csr6 = 0x00420000;
-				outl(0x1F078, ioaddr + 0xB8);
-			}
-			if (tp->csr6 != new_csr6) {
-				tp->csr6 = new_csr6;
-				/* Restart Tx */
-				outl_CSR6(tp, tp->csr6 | 0x0002);
-				outl_CSR6(tp, tp->csr6 | 0x2002);
-				dev->trans_start = jiffies;
-				if (tulip_debug > 1)
-					printk(KERN_INFO "%s: Changing PNIC configuration to %s "
-						   "%s-duplex, CSR6 %8.8x.\n",
-						   dev->name, medianame[dev->if_port],
-						   tp->full_duplex ? "full" : "half", new_csr6);
-			}
-		}
-	}
-	tp->timer.expires = RUN_AT(next_tick);
-	add_timer(&tp->timer);
-}
-
-static void comet_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int next_tick = 60*HZ;
-
-	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: Comet link status %4.4x partner capability "
-			   "%4.4x.\n",
-			   dev->name, inl(ioaddr + 0xB8), inl(ioaddr + 0xC8));
-	tp->timer.expires = RUN_AT(next_tick);
-	add_timer(&tp->timer);
-}
-
-static void tulip_tx_timeout(struct net_device *dev)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-
-	if (media_cap[dev->if_port] & MediaIsMII) {
-		/* Do nothing -- the media monitor should handle this. */
-		if (tulip_debug > 1)
-			printk(KERN_WARNING "%s: Transmit timeout using MII device.\n",
-				   dev->name);
-	} else if (tp->chip_id == DC21040) {
-		if ( !tp->medialock  &&  inl(ioaddr + CSR12) & 0x0002) {
-			dev->if_port = (dev->if_port == 2 ? 0 : 2);
-			printk(KERN_INFO "%s: transmit timed out, switching to "
-				   "%s.\n",
-				   dev->name, medianame[dev->if_port]);
-			select_media(dev, 0);
-		}
-		dev->trans_start = jiffies;
-		return;
-	} else if (tp->chip_id == DC21041) {
-		int csr12 = inl(ioaddr + CSR12);
-
-		printk(KERN_WARNING "%s: 21041 transmit timed out, status %8.8x, "
-			   "CSR12 %8.8x, CSR13 %8.8x, CSR14 %8.8x, resetting...\n",
-			   dev->name, inl(ioaddr + CSR5), csr12,
-			   inl(ioaddr + CSR13), inl(ioaddr + CSR14));
-		tp->mediasense = 1;
-		if ( ! tp->medialock) {
-			if (dev->if_port == 1 || dev->if_port == 2)
-				if (csr12 & 0x0004) {
-					dev->if_port = 2 - dev->if_port;
-				} else
-					dev->if_port = 0;
-			else
-				dev->if_port = 1;
-			select_media(dev, 0);
-		}
-	} else if (tp->chip_id == DC21140 || tp->chip_id == DC21142
-			   || tp->chip_id == MX98713 || tp->chip_id == COMPEX9881) {
-		printk(KERN_WARNING "%s: 21140 transmit timed out, status %8.8x, "
-			   "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
-			   dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR12),
-			   inl(ioaddr + CSR13), inl(ioaddr + CSR14), inl(ioaddr + CSR15));
-		if ( ! tp->medialock  &&  tp->mtable) {
-			do
-				--tp->cur_index;
-			while (tp->cur_index >= 0
-				   && (media_cap[tp->mtable->mleaf[tp->cur_index].media]
-					   & MediaIsFD));
-			if (--tp->cur_index < 0) {
-				/* We start again, but should instead look for default. */
-				tp->cur_index = tp->mtable->leafcount - 1;
-			}
-			select_media(dev, 0);
-			printk(KERN_WARNING "%s: transmit timed out, switching to %s "
-				   "media.\n", dev->name, medianame[dev->if_port]);
-		}
-	} else {
-		printk(KERN_WARNING "%s: Transmit timed out, status %8.8x, CSR12 "
-			   "%8.8x, resetting...\n",
-			   dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR12));
-		dev->if_port = 0;
-	}
-
-#if defined(way_too_many_messages)
-	if (tulip_debug > 3) {
-		int i;
-		for (i = 0; i < RX_RING_SIZE; i++) {
-			u8 *buf = (u8 *)(tp->rx_ring[i].buffer1);
-			int j;
-			printk(KERN_DEBUG "%2d: %8.8x %8.8x %8.8x %8.8x  "
-				   "%2.2x %2.2x %2.2x.\n",
-				   i, (unsigned int)tp->rx_ring[i].status,
-				   (unsigned int)tp->rx_ring[i].length,
-				   (unsigned int)tp->rx_ring[i].buffer1,
-				   (unsigned int)tp->rx_ring[i].buffer2,
-				   buf[0], buf[1], buf[2]);
-			for (j = 0; buf[j] != 0xee && j < 1600; j++)
-				if (j < 100) printk(" %2.2x", buf[j]);
-			printk(" j=%d.\n", j);
-		}
-		printk(KERN_DEBUG "  Rx ring %8.8x: ", (int)tp->rx_ring);
-		for (i = 0; i < RX_RING_SIZE; i++)
-			printk(" %8.8x", (unsigned int)tp->rx_ring[i].status);
-		printk("\n" KERN_DEBUG "  Tx ring %8.8x: ", (int)tp->tx_ring);
-		for (i = 0; i < TX_RING_SIZE; i++)
-			printk(" %8.8x", (unsigned int)tp->tx_ring[i].status);
-		printk("\n");
-	}
-#endif
-
-	/* Stop and restart the chip's Tx processes . */
-	outl_CSR6(tp, tp->csr6 | 0x0002);
-	outl_CSR6(tp, tp->csr6 | 0x2002);
-	/* Trigger an immediate transmit demand. */
-	outl(0, ioaddr + CSR1);
-
-	dev->trans_start = jiffies;
-	tp->stats.tx_errors++;
-	return;
-}
-
-
-/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void tulip_init_ring(struct net_device *dev)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	int i;
-
-	tp->tx_full = 0;
-	tp->cur_rx = tp->cur_tx = 0;
-	tp->dirty_rx = tp->dirty_tx = 0;
-	tp->susp_rx = 0;
-	tp->ttimer = 0;
-	tp->nir = 0;
-
-	for (i = 0; i < RX_RING_SIZE; i++) {
-		tp->rx_ring[i].status = 0x00000000;
-		tp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ);
-		tp->rx_ring[i].buffer2 = virt_to_le32desc(&tp->rx_ring[i+1]);
-		tp->rx_skbuff[i] = NULL;
-	}
-	/* Mark the last entry as wrapping the ring. */
-	tp->rx_ring[i-1].length = cpu_to_le32(PKT_BUF_SZ | DESC_RING_WRAP);
-	tp->rx_ring[i-1].buffer2 = virt_to_le32desc(&tp->rx_ring[0]);
-
-	for (i = 0; i < RX_RING_SIZE; i++) {
-		/* Note the receive buffer must be longword aligned.
-		   dev_alloc_skb() provides 16 byte alignment.  But do *not*
-		   use skb_reserve() to align the IP header! */
-		struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ);
-		tp->rx_skbuff[i] = skb;
-		if (skb == NULL)
-			break;
-		skb->dev = dev;			/* Mark as being used by this device. */
-		tp->rx_ring[i].status = cpu_to_le32(DescOwned);	/* Owned by Tulip chip */
-		tp->rx_ring[i].buffer1 = virt_to_le32desc(skb->tail);
-	}
-	tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
-
-	/* The Tx buffer descriptor is filled in as needed, but we
-	   do need to clear the ownership bit. */
-	for (i = 0; i < TX_RING_SIZE; i++) {
-		tp->tx_skbuff[i] = 0;
-		tp->tx_ring[i].status = 0x00000000;
-		tp->tx_ring[i].buffer2 = virt_to_le32desc(&tp->tx_ring[i+1]);
-	}
-	tp->tx_ring[i-1].buffer2 = virt_to_le32desc(&tp->tx_ring[0]);
-}
-
-static int
-tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	int entry;
-	u32 flag;
-	unsigned long cpuflags;
-
-	/* Caution: the write order is important here, set the field
-	   with the ownership bits last. */
-
-	spin_lock_irqsave(&tp->tx_lock, cpuflags);
-
-	/* Calculate the next Tx descriptor entry. */
-	entry = tp->cur_tx % TX_RING_SIZE;
-
-	tp->tx_skbuff[entry] = skb;
-	tp->tx_ring[entry].buffer1 = virt_to_le32desc(skb->data);
-
-	if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE/2) {/* Typical path */
-		flag = 0x60000000; /* No interrupt */
-	} else if (tp->cur_tx - tp->dirty_tx == TX_RING_SIZE/2) {
-		flag = 0xe0000000; /* Tx-done intr. */
-	} else if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE - 2) {
-		flag = 0x60000000; /* No Tx-done intr. */
-	} else {		/* Leave room for set_rx_mode() to fill entries. */
-		tp->tx_full = 1;
-		flag = 0xe0000000; /* Tx-done intr. */
-		netif_stop_queue(dev);
-	}
-	if (entry == TX_RING_SIZE-1)
-		flag = 0xe0000000 | DESC_RING_WRAP;
-
-	tp->tx_ring[entry].length = cpu_to_le32(skb->len | flag);
-	tp->tx_ring[entry].status = cpu_to_le32(DescOwned);
-	tp->cur_tx++;
-	spin_unlock_irqrestore(&tp->tx_lock, cpuflags);
-
-	/* Trigger an immediate transmit demand. */
-	outl(0, dev->base_addr + CSR1);
-
-	dev->trans_start = jiffies;
-
-	return 0;
-}
-
-/* The interrupt handler does all of the Rx thread work and cleans up
-   after the Tx thread. */
-static void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
-{
-	struct net_device *dev = (struct net_device *)dev_instance;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int csr5;
-	int entry;
-	int missed;
-	int rx = 0;
-	int tx = 0;
-	int oi = 0;
-	int maxrx = RX_RING_SIZE;
-	int maxtx = TX_RING_SIZE;
-	int maxoi = TX_RING_SIZE;
-
-	tp->nir++;
-
-	do {
-		csr5 = inl(ioaddr + CSR5);
-		/* Acknowledge all of the current interrupt sources ASAP. */
-		outl(csr5 & 0x0001ffff, ioaddr + CSR5);
-
-		if (tulip_debug > 4)
-			printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x.\n",
-				   dev->name, csr5, inl(dev->base_addr + CSR5));
-
-		if ((csr5 & (NormalIntr|AbnormalIntr)) == 0)
-			break;
-
-		if (csr5 & (RxIntr | RxNoBuf)) {
-			rx += tulip_rx(dev);
-			tulip_refill_rx(dev);
-		}
-
-		if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) {
-			unsigned int dirty_tx;
-
-			spin_lock(&tp->tx_lock);
-
-			for (dirty_tx = tp->dirty_tx; tp->cur_tx - dirty_tx > 0;
-				 dirty_tx++) {
-				int entry = dirty_tx % TX_RING_SIZE;
-				int status = le32_to_cpu(tp->tx_ring[entry].status);
-
-				if (status < 0)
-					break;			/* It still has not been Txed */
-				/* Check for Rx filter setup frames. */
-				if (tp->tx_skbuff[entry] == NULL)
-				  continue;
-				
-				if (status & 0x8000) {
-					/* There was an major error, log it. */
-#ifndef final_version
-					if (tulip_debug > 1)
-						printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
-							   dev->name, status);
-#endif
-					tp->stats.tx_errors++;
-					if (status & 0x4104) tp->stats.tx_aborted_errors++;
-					if (status & 0x0C00) tp->stats.tx_carrier_errors++;
-					if (status & 0x0200) tp->stats.tx_window_errors++;
-					if (status & 0x0002) tp->stats.tx_fifo_errors++;
-					if ((status & 0x0080) && tp->full_duplex == 0)
-						tp->stats.tx_heartbeat_errors++;
-#ifdef ETHER_STATS
-					if (status & 0x0100) tp->stats.collisions16++;
-#endif
-				} else {
-#ifdef ETHER_STATS
-					if (status & 0x0001) tp->stats.tx_deferred++;
-#endif
-					tp->stats.tx_bytes += tp->tx_skbuff[entry]->len;
-					tp->stats.collisions += (status >> 3) & 15;
-					tp->stats.tx_packets++;
-				}
-
-				/* Free the original skb. */
-				dev_kfree_skb_irq(tp->tx_skbuff[entry]);
-				tp->tx_skbuff[entry] = 0;
-				tx++;
-			}
-
-#ifndef final_version
-			if (tp->cur_tx - dirty_tx > TX_RING_SIZE) {
-				printk(KERN_ERR "%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
-					   dev->name, dirty_tx, tp->cur_tx, tp->tx_full);
-				dirty_tx += TX_RING_SIZE;
-			}
-#endif
-
-			if (tp->tx_full && tp->cur_tx - dirty_tx  < TX_RING_SIZE - 2) {
-				/* The ring is no longer full, clear tbusy. */
-				tp->tx_full = 0;
-				netif_wake_queue(dev);
-			}
-
-			tp->dirty_tx = dirty_tx;
-			if (csr5 & TxDied) {
-				if (tulip_debug > 2)
-					printk(KERN_WARNING "%s: The transmitter stopped."
-						   "  CSR5 is %x, CSR6 %x, new CSR6 %x.\n",
-						   dev->name, csr5, inl(ioaddr + CSR6), tp->csr6);
-				outl_CSR6(tp, tp->csr6 | 0x0002);
-				outl_CSR6(tp, tp->csr6 | 0x2002);
-			}
-			spin_unlock(&tp->tx_lock);
-		}
-
-		/* Log errors. */
-		if (csr5 & AbnormalIntr) {	/* Abnormal error summary bit. */
-			if (csr5 == 0xffffffff)
-				break;
-			if (csr5 & TxJabber) tp->stats.tx_errors++;
-			if (csr5 & TxFIFOUnderflow) {
-				if ((tp->csr6 & 0xC000) != 0xC000)
-					tp->csr6 += 0x4000;	/* Bump up the Tx threshold */
-				else
-					tp->csr6 |= 0x00200000;  /* Store-n-forward. */
-				/* Restart the transmit process. */
-				outl_CSR6(tp, tp->csr6 | 0x0002);
-				outl_CSR6(tp, tp->csr6 | 0x2002);
-				outl(0, ioaddr + CSR1);
-			}
-			if (csr5 & RxDied) {		/* Missed a Rx frame. */
-				tp->stats.rx_errors++;
-				tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
-				outl_CSR6(tp, tp->csr6 | 0x2002);
-			}
-			if (csr5 & (TPLnkPass | TPLnkFail | 0x08000000)) {
-				if (tp->link_change)
-					(tp->link_change)(dev, csr5);
-			}
-			if (csr5 & SytemError) {
-				printk(KERN_ERR "%s: (%lu) System Error occured\n", dev->name, tp->nir);
-			}
-			/* Clear all error sources, included undocumented ones! */
-			outl(0x0800f7ba, ioaddr + CSR5);
-			oi++;
-		}
-		if (csr5 & TimerInt) {
-#if 0
-			if (tulip_debug > 2)
-				printk(KERN_ERR "%s: Re-enabling interrupts, %8.8x.\n",
-					   dev->name, csr5);
-			outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
-#endif
-			tp->ttimer = 0;
-			oi++;
-		}
-		if (tx > maxtx || rx > maxrx || oi > maxoi) {
-			if (tulip_debug > 1)
-				printk(KERN_WARNING "%s: Too much work during an interrupt, "
-					   "csr5=0x%8.8x. (%lu) (%d,%d,%d)\n", dev->name, csr5, tp->nir, tx, rx, oi);
-			/* Acknowledge all interrupt sources. */
-#if 0
-			/* Clear all interrupting sources, set timer to re-enable. */
-			outl(((~csr5) & 0x0001ebef) | NormalIntr | AbnormalIntr | TimerInt,
-				 ioaddr + CSR7);
-			outl(12, ioaddr + CSR11);
-			tp->ttimer = 1;
-#endif
-			break;
-		}
-	} while (1);
-
-	tulip_refill_rx(dev);
-
-	/* check if we card is in suspend mode */
-	entry = tp->dirty_rx % RX_RING_SIZE;
-	if (tp->rx_skbuff[entry] == NULL) {
-		if (tulip_debug > 1)
-			printk(KERN_WARNING "%s: in rx suspend mode: (%lu) (tp->cur_rx = %u, ttimer = %d, rx = %d) go/stay in suspend mode\n", dev->name, tp->nir, tp->cur_rx, tp->ttimer, rx);
-		if (tp->ttimer == 0 || (inl(ioaddr + CSR11) & 0xffff) == 0) {
-			if (tulip_debug > 1)
-				printk(KERN_WARNING "%s: in rx suspend mode: (%lu) set timer\n", dev->name, tp->nir);
-			outl(tulip_tbl[tp->chip_id].valid_intrs | TimerInt,
-				ioaddr + CSR7);
-			outl(TimerInt, ioaddr + CSR5);
-			outl(12, ioaddr + CSR11);
-			tp->ttimer = 1;
-		}
-	}
-
-	if ((missed = inl(ioaddr + CSR8) & 0x1ffff)) {
-		tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
-	}
-
-	if (tulip_debug > 4)
-		printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n",
-			   dev->name, inl(ioaddr + CSR5));
-
-}
-
-static int tulip_refill_rx(struct net_device *dev)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	int entry;
-	int refilled = 0;
-
-	/* Refill the Rx ring buffers. */
-	for (; tp->cur_rx - tp->dirty_rx > 0; tp->dirty_rx++) {
-		entry = tp->dirty_rx % RX_RING_SIZE;
-		if (tp->rx_skbuff[entry] == NULL) {
-			struct sk_buff *skb;
-			skb = tp->rx_skbuff[entry] = dev_alloc_skb(PKT_BUF_SZ);
-			if (skb == NULL)
-				break;
-			skb->dev = dev;			/* Mark as being used by this device. */
-			tp->rx_ring[entry].buffer1 = virt_to_le32desc(skb->tail);
-			refilled++;
-		}
-		tp->rx_ring[entry].status = cpu_to_le32(DescOwned);
-	}
-	return refilled;
-}
-
-static int tulip_rx(struct net_device *dev)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	int entry = tp->cur_rx % RX_RING_SIZE;
-	int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
-	int received = 0;
-
-	if (tulip_debug > 4)
-		printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
-			   tp->rx_ring[entry].status);
-	/* If we own the next entry, it is a new packet. Send it up. */
-	while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
-		s32 status = le32_to_cpu(tp->rx_ring[entry].status);
-
-		if (tulip_debug > 5)
-			printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
-				   dev->name, entry, status);
-		if (--rx_work_limit < 0)
-			break;
-		if ((status & 0x38008300) != 0x0300) {
-			if ((status & 0x38000300) != 0x0300) {
-				/* Ingore earlier buffers. */
-				if ((status & 0xffff) != 0x7fff) {
-					if (tulip_debug > 1)
-						printk(KERN_WARNING "%s: Oversized Ethernet frame "
-							   "spanned multiple buffers, status %8.8x!\n",
-							   dev->name, status);
-					tp->stats.rx_length_errors++;
-				}
-			} else if (status & RxDescFatalErr) {
-				/* There was a fatal error. */
-				if (tulip_debug > 2)
-					printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
-						   dev->name, status);
-				tp->stats.rx_errors++; /* end of a packet.*/
-				if (status & 0x0890) tp->stats.rx_length_errors++;
-				if (status & 0x0004) tp->stats.rx_frame_errors++;
-				if (status & 0x0002) tp->stats.rx_crc_errors++;
-				if (status & 0x0001) tp->stats.rx_fifo_errors++;
-			}
-		} else {
-			/* Omit the four octet CRC from the length. */
-			short pkt_len = ((status >> 16) & 0x7ff) - 4;
-			struct sk_buff *skb;
-
-#ifndef final_version
-			if (pkt_len > 1518) {
-				printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
-					   dev->name, pkt_len, pkt_len);
-				pkt_len = 1518;
-				tp->stats.rx_length_errors++;
-			}
-#endif
-			/* Check if the packet is long enough to accept without copying
-			   to a minimally-sized skbuff. */
-			if (pkt_len < rx_copybreak
-				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
-				skb->dev = dev;
-				skb_reserve(skb, 2);	/* 16 byte align the IP header */
-#if ! defined(__alpha__)
-				eth_copy_and_sum(skb, tp->rx_skbuff[entry]->tail, pkt_len, 0);
-				skb_put(skb, pkt_len);
-#else
-				memcpy(skb_put(skb, pkt_len), tp->rx_skbuff[entry]->tail,
-					   pkt_len);
-#endif
-			} else { 	/* Pass up the skb already on the Rx ring. */
-				char *temp = skb_put(skb = tp->rx_skbuff[entry], pkt_len);
-				tp->rx_skbuff[entry] = NULL;
-#ifndef final_version
-				if (le32desc_to_virt(tp->rx_ring[entry].buffer1) != temp)
-					printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
-						   "do not match in tulip_rx: %p vs. %p / %p.\n",
-						   dev->name,
-						   le32desc_to_virt(tp->rx_ring[entry].buffer1),
-						   skb->head, temp);
-#endif
-			}
-			skb->protocol = eth_type_trans(skb, dev);
-			netif_rx(skb);
-			dev->last_rx = jiffies;
-			tp->stats.rx_packets++;
-			tp->stats.rx_bytes += pkt_len;
-		}
-		received++;
-		entry = (++tp->cur_rx) % RX_RING_SIZE;
-	}
-
-	return received;
-}
-
-
-static void tulip_down (struct net_device *dev)
-{
-	long ioaddr = dev->base_addr;
-	struct tulip_private *tp = (struct tulip_private *) dev->priv;
-
-	netif_device_detach (dev);
-
-	del_timer (&tp->timer);
-
-	/* Disable interrupts by clearing the interrupt mask. */
-	outl (0x00000000, ioaddr + CSR7);
-
-	/* Stop the Tx and Rx processes. */
-	outl_CSR6 (tp, inl (ioaddr + CSR6) & ~0x2002);
-
-	/* 21040 -- Leave the card in 10baseT state. */
-	if (tp->chip_id == DC21040)
-		outl (0x00000004, ioaddr + CSR13);
-
-	if (inl (ioaddr + CSR6) != 0xffffffff)
-		tp->stats.rx_missed_errors += inl (ioaddr + CSR8) & 0xffff;
-
-	dev->if_port = tp->saved_if_port;
-
-	/* Leave the driver in snooze, not sleep, mode. */
-	if (tp->flags & HAS_ACPI)
-		pci_write_config_dword (tp->pdev, 0x40, 0x40000000);
-}
-  
-  
-static int tulip_close (struct net_device *dev)
-{
-	long ioaddr = dev->base_addr;
-	struct tulip_private *tp = (struct tulip_private *) dev->priv;
-	int i;
-
-	tulip_down (dev);
-
-	if (tulip_debug > 1)
-		printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
-			dev->name, inl (ioaddr + CSR5));
-
-	free_irq (dev->irq, dev);
-
-	/* Free all the skbuffs in the Rx queue. */
-	for (i = 0; i < RX_RING_SIZE; i++) {
-		struct sk_buff *skb = tp->rx_skbuff[i];
-		tp->rx_skbuff[i] = 0;
-		tp->rx_ring[i].status = 0;	/* Not owned by Tulip chip. */
-		tp->rx_ring[i].length = 0;
-		tp->rx_ring[i].buffer1 = 0xBADF00D0;	/* An invalid address. */
-		if (skb) {
-			dev_kfree_skb (skb);
-		}
-	}
-	for (i = 0; i < TX_RING_SIZE; i++) {
-		if (tp->tx_skbuff[i])
-			dev_kfree_skb (tp->tx_skbuff[i]);
-		tp->tx_skbuff[i] = 0;
-	}
-
-	MOD_DEC_USE_COUNT;
-
-	return 0;
-}
-
-static struct enet_statistics *tulip_get_stats(struct net_device *dev)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-
-	if (netif_running(dev))
-		tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
-
-	return &tp->stats;
-}
-
-
-/* Provide ioctl() calls to examine the MII xcvr state. */
-static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	u16 *data = (u16 *)&rq->ifr_data;
-	int phy = tp->phys[0] & 0x1f;
-	long flags;
-
-	switch(cmd) {
-	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
-		if (tp->mii_cnt)
-			data[0] = phy;
-		else if (tp->flags & HAS_NWAY143)
-			data[0] = 32;
-		else if (tp->chip_id == COMET)
-			data[0] = 1;
-		else
-			return -ENODEV;
-	case SIOCDEVPRIVATE+1:		/* Read the specified MII register. */
-		if (data[0] == 32  &&  (tp->flags & HAS_NWAY143)) {
-			int csr12 = inl(ioaddr + CSR12);
-			int csr14 = inl(ioaddr + CSR14);
-			switch (data[1]) {
-			case 0: {
-				data[3] = (csr14<<5) & 0x1000;
-				break; }
-			case 1:
-				data[3] = 0x7848 + ((csr12&0x7000) == 0x5000 ? 0x20 : 0)
-					+ (csr12&0x06 ? 0x04 : 0);
-				break;
-			case 4: {
-				data[3] = ((csr14>>9)&0x07C0) +
-					((inl(ioaddr + CSR6)>>3)&0x0040) + ((csr14>>1)&0x20) + 1;
-				break;
-			}
-			case 5: data[3] = csr12 >> 16; break;
-			default: data[3] = 0; break;
-			}
-		} else {
-			save_flags(flags);
-			cli();
-			data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);
-			restore_flags(flags);
-		}
-		return 0;
-	case SIOCDEVPRIVATE+2:		/* Write the specified MII register */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		if (data[0] == 32  &&  (tp->flags & HAS_NWAY143)) {
-			if (data[1] == 5)
-				tp->to_advertise = data[2];
-		} else {
-			save_flags(flags);
-			cli();
-			mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
-			restore_flags(flags);
-		}
-		return 0;
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	return -EOPNOTSUPP;
-}
-
-
-/* Set or clear the multicast filter for this adaptor.
-   Note that we only use exclusion around actually queueing the
-   new frame, not around filling tp->setup_frame.  This is non-deterministic
-   when re-entered but still correct. */
-
-/* The little-endian AUTODIN32 ethernet CRC calculation.
-   N.B. Do not use for bulk data, use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c */
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline u32 ether_crc_le(int length, unsigned char *data)
-{
-	u32 crc = 0xffffffff;	/* Initial value. */
-	while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 8; --bit >= 0; current_octet >>= 1) {
-			if ((crc ^ current_octet) & 1) {
-				crc >>= 1;
-				crc ^= ethernet_polynomial_le;
-			} else
-				crc >>= 1;
-		}
-	}
-	return crc;
-}
-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc(int length, unsigned char *data)
-{
-    int crc = -1;
-
-    while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 0; bit < 8; bit++, current_octet >>= 1)
-			crc = (crc << 1) ^
-				((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
-    }
-    return crc;
-}
-
-static void set_rx_mode(struct net_device *dev)
-{
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int csr6 = inl(ioaddr + CSR6) & ~0x00D5;
-	unsigned long cpuflags;
-
-	tp->csr6 &= ~0x00D5;
-	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
-		tp->csr6 |= 0x00C0;
-		csr6 |= 0x00C0;
-		/* Unconditionally log net taps. */
-		printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name);
-	} else if ((dev->mc_count > 1000)  ||  (dev->flags & IFF_ALLMULTI)) {
-		/* Too many to filter well -- accept all multicasts. */
-		tp->csr6 |= 0x0080;
-		csr6 |= 0x0080;
-	} else	if (tp->flags & MC_HASH_ONLY) {
-		/* Some work-alikes have only a 64-entry hash filter table. */
-		/* Should verify correctness on big-endian/__powerpc__ */
-		struct dev_mc_list *mclist;
-		int i;
-		u32 mc_filter[2];		 /* Multicast hash filter */
-		if (dev->mc_count > 64) {		/* Arbitrary non-effective limit. */
-			tp->csr6 |= 0x0080;
-			csr6 |= 0x0080;
-		} else {
-			mc_filter[1] = mc_filter[0] = 0;
-			for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-				 i++, mclist = mclist->next)
-				set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26, mc_filter);
-			if (tp->chip_id == AX88140) {
-				outl(2, ioaddr + CSR13);
-				outl(mc_filter[0], ioaddr + CSR14);
-				outl(3, ioaddr + CSR13);
-				outl(mc_filter[1], ioaddr + CSR14);
-			} else if (tp->chip_id == COMET) { /* Has a simple hash filter. */
-				outl(mc_filter[0], ioaddr + 0xAC);
-				outl(mc_filter[1], ioaddr + 0xB0);
-			}
-		}
-	} else {
-		u16 *eaddrs, *setup_frm = tp->setup_frame;
-		struct dev_mc_list *mclist;
-		u32 tx_flags = 0x08000000 | 192;
-		int i;
-
-		/* Note that only the low-address shortword of setup_frame is valid!
-		   The values are doubled for big-endian architectures. */
-		if (dev->mc_count > 14) { /* Must use a multicast hash table. */
-			u16 hash_table[32];
-			tx_flags = 0x08400000 | 192;		/* Use hash filter. */
-			memset(hash_table, 0, sizeof(hash_table));
-			set_bit(255, hash_table); 			/* Broadcast entry */
-			/* This should work on big-endian machines as well. */
-			for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-				 i++, mclist = mclist->next)
-				set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff,
-						hash_table);
-			for (i = 0; i < 32; i++)
-				*setup_frm++ = *setup_frm++ = hash_table[i];
-			setup_frm = &tp->setup_frame[13*6];
-		} else {
-			/* We have <= 14 addresses so we can use the wonderful
-			   16 address perfect filtering of the Tulip. */
-			for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
-				 i++, mclist = mclist->next) {
-				eaddrs = (u16 *)mclist->dmi_addr;
-				*setup_frm++ = *setup_frm++ = *eaddrs++;
-				*setup_frm++ = *setup_frm++ = *eaddrs++;
-				*setup_frm++ = *setup_frm++ = *eaddrs++;
-			}
-			/* Fill the unused entries with the broadcast address. */
-			memset(setup_frm, 0xff, (15-i)*12);
-			setup_frm = &tp->setup_frame[15*6];
-		}
-		/* Fill the final entry with our physical address. */
-		eaddrs = (u16 *)dev->dev_addr;
-		*setup_frm++ = *setup_frm++ = eaddrs[0];
-		*setup_frm++ = *setup_frm++ = eaddrs[1];
-		*setup_frm++ = *setup_frm++ = eaddrs[2];
-		/* Now add this frame to the Tx list. */
-		spin_lock_irqsave(&tp->tx_lock, cpuflags);
-		if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) {
-			/* Same setup recently queued, we need not add it. */
-		} else {
-			unsigned long flags;
-			unsigned int entry;
-
-			save_flags(flags); cli();
-			entry = tp->cur_tx++ % TX_RING_SIZE;
-
-			if (entry != 0) {
-				/* Avoid a chip errata by prefixing a dummy entry. */
-				tp->tx_skbuff[entry] = 0;
-				tp->tx_ring[entry].length =
-					(entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0;
-				tp->tx_ring[entry].buffer1 = 0;
-				tp->tx_ring[entry].status = cpu_to_le32(DescOwned);
-				entry = tp->cur_tx++ % TX_RING_SIZE;
-			}
-
-			tp->tx_skbuff[entry] = 0;
-			/* Put the setup frame on the Tx list. */
-			if (entry == TX_RING_SIZE-1)
-				tx_flags |= DESC_RING_WRAP;		/* Wrap ring. */
-			tp->tx_ring[entry].length = cpu_to_le32(tx_flags);
-			tp->tx_ring[entry].buffer1 = virt_to_le32desc(tp->setup_frame);
-			tp->tx_ring[entry].status = cpu_to_le32(DescOwned);
-			if (tp->cur_tx - tp->dirty_tx >= TX_RING_SIZE - 2) {
-				netif_stop_queue(dev);
-				tp->tx_full = 1;
-			}
-			spin_unlock_irqrestore(&tp->tx_lock, cpuflags);
-			/* Trigger an immediate transmit demand. */
-			outl(0, ioaddr + CSR1);
-		}
-	}
-	outl_CSR6(tp, csr6 | 0x0000);
-}
-
-
-static int __devinit tulip_init_one (struct pci_dev *pdev,
-				     const struct pci_device_id *ent)
-{
-	static int did_version = 0;			/* Already printed version info. */
-	struct tulip_private *tp;
-	/* See note below on the multiport cards. */
-	static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'};
-	static int last_irq = 0;
-	static int multiport_cnt = 0;		/* For four-port boards w/one EEPROM */
-	u8 chip_rev;
-	int i, irq;
-	unsigned short sum;
-	u8 ee_data[EEPROM_SIZE];
-	struct net_device *dev;
-	long ioaddr;
-	static int board_idx = -1;
-	int chip_idx = ent->driver_data;
-	
-	board_idx++;
-
-	if (tulip_debug > 0  &&  did_version++ == 0)
-		printk (KERN_INFO "%s", version);
-
-        if( pdev->subsystem_vendor == 0x1376 ){
-		printk (KERN_ERR PFX "skipping LMC card.\n");
-		return -ENODEV;
-	}
-	
-	ioaddr = pci_resource_start (pdev, 0);
-	irq = pdev->irq;
-
-	/* Make certain the data structures are quadword aligned. */
-	dev = init_etherdev (NULL, sizeof (*tp));
-	if (!dev) {
-		printk (KERN_ERR PFX "unable to allocate ether device, aborting\n");
-		return -ENOMEM;
-	}
-
-	/* We do a request_region() only to register /proc/ioports info. */
-	/* Note that proper size is tulip_tbl[chip_idx].chip_name, but... */
-	if (!request_region (ioaddr, tulip_tbl[chip_idx].io_size, dev->name)) {
-		printk (KERN_ERR PFX "unable to allocate ether device, aborting\n");
-		goto err_out_free_netdev;
-	}
-
-	if (pci_enable_device(pdev)) {
-		printk (KERN_ERR PFX "cannot enable PCI device (id %04x:%04x, bus %d, devfn %d), aborting\n",
-			pdev->vendor, pdev->device,
-			pdev->bus->number, pdev->devfn);
-		goto err_out_free_netdev;
-	}
-
-	pci_set_master(pdev);
-
-	tp = dev->priv;
-	memset(tp, 0, sizeof(*tp));
-
-	pci_read_config_byte (pdev, PCI_REVISION_ID, &chip_rev);
-
-	printk(KERN_INFO "%s: %s rev %d at %#3lx,",
-		   dev->name, tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr);
-
-	/* Stop the chip's Tx and Rx processes. */
-	outl_CSR6(tp, inl(ioaddr + CSR6) & ~0x2002);
-	/* Clear the missed-packet counter. */
-	(volatile int)inl(ioaddr + CSR8);
-
-	if (chip_idx == DC21041  &&  inl(ioaddr + CSR9) & 0x8000) {
-		printk(" 21040 compatible mode,");
-		chip_idx = DC21040;
-	}
-
-	/* The station address ROM is read byte serially.  The register must
-	   be polled, waiting for the value to be read bit serially from the
-	   EEPROM.
-	   */
-	sum = 0;
-	if (chip_idx == DC21040) {
-		outl(0, ioaddr + CSR9);		/* Reset the pointer with a dummy write. */
-		for (i = 0; i < 6; i++) {
-			int value, boguscnt = 100000;
-			do
-				value = inl(ioaddr + CSR9);
-			while (value < 0  && --boguscnt > 0);
-			dev->dev_addr[i] = value;
-			sum += value & 0xff;
-		}
-	} else if (chip_idx == LC82C168) {
-		for (i = 0; i < 3; i++) {
-			int value, boguscnt = 100000;
-			outl(0x600 | i, ioaddr + 0x98);
-			do
-				value = inl(ioaddr + CSR9);
-			while (value < 0  && --boguscnt > 0);
-			put_unaligned(le16_to_cpu(value), ((u16*)dev->dev_addr) + i);
-			sum += value & 0xffff;
-		}
-	} else if (chip_idx == COMET) {
-		/* No need to read the EEPROM. */
-		put_unaligned(inl(ioaddr + 0xA4), (u32 *)dev->dev_addr);
-		put_unaligned(inl(ioaddr + 0xA8), (u16 *)(dev->dev_addr + 4));
-		for (i = 0; i < 6; i ++)
-			sum += dev->dev_addr[i];
-	} else {
-		/* A serial EEPROM interface, we read now and sort it out later. */
-		int sa_offset = 0;
-		int ee_addr_size = read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
-
-		for (i = 0; i < sizeof(ee_data)/2; i++)
-			((u16 *)ee_data)[i] =
-				le16_to_cpu(read_eeprom(ioaddr, i, ee_addr_size));
-
-		/* DEC now has a specification (see Notes) but early board makers
-		   just put the address in the first EEPROM locations. */
-		/* This does  memcmp(eedata, eedata+16, 8) */
-		for (i = 0; i < 8; i ++)
-			if (ee_data[i] != ee_data[16+i])
-				sa_offset = 20;
-		if (ee_data[0] == 0xff  &&  ee_data[1] == 0xff &&  ee_data[2] == 0) {
-			sa_offset = 2;		/* Grrr, damn Matrox boards. */
-			multiport_cnt = 4;
-		}
-		for (i = 0; i < 6; i ++) {
-			dev->dev_addr[i] = ee_data[i + sa_offset];
-			sum += ee_data[i + sa_offset];
-		}
-	}
-	/* Lite-On boards have the address byte-swapped. */
-	if ((dev->dev_addr[0] == 0xA0  ||  dev->dev_addr[0] == 0xC0)
-		&&  dev->dev_addr[1] == 0x00)
-		for (i = 0; i < 6; i+=2) {
-			char tmp = dev->dev_addr[i];
-			dev->dev_addr[i] = dev->dev_addr[i+1];
-			dev->dev_addr[i+1] = tmp;
-		}
-	/* On the Zynx 315 Etherarray and other multiport boards only the
-	   first Tulip has an EEPROM.
-	   The addresses of the subsequent ports are derived from the first.
-	   Many PCI BIOSes also incorrectly report the IRQ line, so we correct
-	   that here as well. */
-	if (sum == 0  || sum == 6*0xff) {
-		printk(" EEPROM not present,");
-		for (i = 0; i < 5; i++)
-			dev->dev_addr[i] = last_phys_addr[i];
-		dev->dev_addr[i] = last_phys_addr[i] + 1;
-#if defined(__i386__)		/* Patch up x86 BIOS bug. */
-		if (last_irq)
-			irq = last_irq;
-#endif
-	}
-
-	for (i = 0; i < 6; i++)
-		printk("%c%2.2X", i ? ':' : ' ', last_phys_addr[i] = dev->dev_addr[i]);
-	printk(", IRQ %d.\n", irq);
-	last_irq = irq;
-
-	pdev->driver_data = dev;
-	dev->base_addr = ioaddr;
-	dev->irq = irq;
-
-	tp->chip_id = chip_idx;
-	tp->revision = chip_rev;
-	tp->flags = tulip_tbl[chip_idx].flags;
-	tp->csr0 = csr0;
-	tp->pdev = pdev;
-	tp->base_addr = dev->base_addr;
-
-	/* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles.
-	   And the ASIX must have a burst limit or horrible things happen. */
-	if (chip_idx == DC21143  &&  chip_rev == 65)
-		tp->csr0 &= ~0x01000000;
-	else if (chip_idx == AX88140)
-		tp->csr0 |= 0x2000;
-
-#ifdef TULIP_FULL_DUPLEX
-	tp->full_duplex = 1;
-	tp->full_duplex_lock = 1;
-#endif
-#ifdef TULIP_DEFAULT_MEDIA
-	tp->default_port = TULIP_DEFAULT_MEDIA;
-#endif
-#ifdef TULIP_NO_MEDIA_SWITCH
-	tp->medialock = 1;
-#endif
-	tp->tx_lock = SPIN_LOCK_UNLOCKED;
-
-	/* The lower four bits are the media type. */
-	if (board_idx >= 0  &&  board_idx < MAX_UNITS) {
-		tp->default_port = options[board_idx] & 15;
-		if ((options[board_idx] & 0x90) || full_duplex[board_idx] > 0)
-			tp->full_duplex = 1;
-		if (mtu[board_idx] > 0)
-			dev->mtu = mtu[board_idx];
-	}
-	if (dev->mem_start)
-		tp->default_port = dev->mem_start;
-	if (tp->default_port) {
-		tp->medialock = 1;
-		if (media_cap[tp->default_port] & MediaAlwaysFD)
-			tp->full_duplex = 1;
-	}
-	if (tp->full_duplex)
-		tp->full_duplex_lock = 1;
-
-	if (media_cap[tp->default_port] & MediaIsMII) {
-		u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 };
-		tp->to_advertise = media2advert[tp->default_port - 9];
-	} else if (tp->flags & HAS_8023X)
-		tp->to_advertise = 0x05e1;
-	else 
-		tp->to_advertise = 0x01e1;
-
-	/* This is logically part of probe1(), but too complex to write inline. */
-	if (tp->flags & HAS_MEDIA_TABLE) {
-		memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom));
-		parse_eeprom(dev);
-	}
-
-	if ((tp->flags & ALWAYS_CHECK_MII) ||
-		(tp->mtable  &&  tp->mtable->has_mii) ||
-		( ! tp->mtable  &&  (tp->flags & HAS_MII))) {
-		int phy, phy_idx;
-		if (tp->mtable  &&  tp->mtable->has_mii) {
-			for (i = 0; i < tp->mtable->leafcount; i++)
-				if (tp->mtable->mleaf[i].media == 11) {
-					tp->cur_index = i;
-					tp->saved_if_port = dev->if_port;
-					select_media(dev, 1);
-					dev->if_port = tp->saved_if_port;
-					break;
-				}
-		}
-		/* Find the connected MII xcvrs.
-		   Doing this in open() would allow detecting external xcvrs later,
-		   but takes much time. */
-		for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys);
-			 phy++) {
-			int mii_status = mdio_read(dev, phy, 1);
-			if ((mii_status & 0x8301) == 0x8001 ||
-				((mii_status & 0x8000) == 0  && (mii_status & 0x7800) != 0)) {
-				int mii_reg0 = mdio_read(dev, phy, 0);
-				int mii_advert = mdio_read(dev, phy, 4);
-				int reg4 = ((mii_status>>6) & tp->to_advertise) | 1;
-				tp->phys[phy_idx] = phy;
-				tp->advertising[phy_idx++] = reg4;
-				printk(KERN_INFO "%s:  MII transceiver #%d "
-					   "config %4.4x status %4.4x advertising %4.4x.\n",
-					   dev->name, phy, mii_reg0, mii_status, mii_advert);
-				/* Fixup for DLink with miswired PHY. */
-				if (mii_advert != reg4) {
-					printk(KERN_DEBUG "%s:  Advertising %4.4x on PHY %d,"
-						   " previously advertising %4.4x.\n",
-						   dev->name, reg4, phy, mii_advert);
-					printk(KERN_DEBUG "%s:  Advertising %4.4x (to advertise"
-						   " is %4.4x).\n",
-						   dev->name, reg4, tp->to_advertise);
-					mdio_write(dev, phy, 4, reg4);
-				}
-				/* Enable autonegotiation: some boards default to off. */
-				mdio_write(dev, phy, 0, mii_reg0 |
-						   (tp->full_duplex ? 0x1100 : 0x1000) |
-						   (media_cap[tp->default_port]&MediaIs100 ? 0x2000:0));
-			}
-		}
-		tp->mii_cnt = phy_idx;
-		if (tp->mtable  &&  tp->mtable->has_mii  &&  phy_idx == 0) {
-			printk(KERN_INFO "%s: ***WARNING***: No MII transceiver found!\n",
-				   dev->name);
-			tp->phys[0] = 1;
-		}
-	}
-
-	/* The Tulip-specific entries in the device structure. */
-	dev->open = tulip_open;
-	dev->hard_start_xmit = tulip_start_xmit;
-	dev->tx_timeout = tulip_tx_timeout;
-	dev->watchdog_timeo = TX_TIMEOUT;
-	dev->stop = tulip_close;
-	dev->get_stats = tulip_get_stats;
-	dev->do_ioctl = private_ioctl;
-	dev->set_multicast_list = set_rx_mode;
-
-	if ((tp->flags & HAS_NWAY143)  || tp->chip_id == DC21041)
-		tp->link_change = t21142_lnk_change;
-	else if (tp->flags & HAS_PNICNWAY)
-		tp->link_change = pnic_lnk_change;
-
-	/* Reset the xcvr interface and turn on heartbeat. */
-	switch (chip_idx) {
-	case DC21041:
-		tp->to_advertise = 0x0061;
-		outl(0x00000000, ioaddr + CSR13);
-		outl(0xFFFFFFFF, ioaddr + CSR14);
-		outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */
-		outl_CSR6(tp, inl(ioaddr + CSR6) | 0x0200);
-		outl(0x0000EF05, ioaddr + CSR13);
-		break;
-	case DC21040:
-		outl(0x00000000, ioaddr + CSR13);
-		outl(0x00000004, ioaddr + CSR13);
-		break;
-	case DC21140: default:
-		if (tp->mtable)
-			outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12);
-		break;
-	case DC21142:
-	case PNIC2:
-		if (tp->mii_cnt  ||  media_cap[dev->if_port] & MediaIsMII) {
-			outl_CSR6(tp, 0x82020000);
-			outl(0x0000, ioaddr + CSR13);
-			outl(0x0000, ioaddr + CSR14);
-			outl_CSR6(tp, 0x820E0000);
-		} else
-			t21142_start_nway(dev);
-		break;
-	case LC82C168:
-		if ( ! tp->mii_cnt) {
-			tp->nway = 1;
-			tp->nwayset = 0;
-			outl_CSR6(tp, 0x00420000);
-			outl(0x30, ioaddr + CSR12);
-			outl_CSR6(tp, 0x0001F078);
-			outl_CSR6(tp, 0x0201F078); /* Turn on autonegotiation. */
-		}
-		break;
-	case MX98713: case COMPEX9881:
-		outl_CSR6(tp, 0x00000000);
-		outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */
-		outl(0x00000001, ioaddr + CSR13);
-		break;
-	case MX98715: case MX98725:
-		outl_CSR6(tp, 0x01a80000);
-		outl(0xFFFFFFFF, ioaddr + CSR14);
-		outl(0x00001000, ioaddr + CSR12);
-		break;
-	case COMET:
-		/* No initialization necessary. */
-		break;
-	}
-
-	/* put the chip in snooze mode until opened */
-	if (tulip_tbl[chip_idx].flags & HAS_ACPI)
-		pci_write_config_dword(pdev, 0x40, 0x40000000);
-
-	return 0;
-
-err_out_free_netdev:
-	unregister_netdev (dev);
-	kfree (dev);
-	return -ENODEV;
-}
-
-
-static void tulip_suspend (struct pci_dev *pdev)
-{
-	struct net_device *dev = pdev->driver_data;
-
-	if (dev && netif_device_present (dev))
-		tulip_down (dev);
-}
-
-
-static void tulip_resume (struct pci_dev *pdev)
-{
-	struct net_device *dev = pdev->driver_data;
-
-	if (dev && !netif_device_present (dev))
-		tulip_up (dev);
-}
-
-
-static void __devexit tulip_remove_one (struct pci_dev *pdev)
-{
-	struct net_device *dev = pdev->driver_data;
-
-	if (dev) {
-		struct tulip_private *tp = (struct tulip_private *)dev->priv;
-		unregister_netdev(dev);
-		release_region(dev->base_addr,
-			       tulip_tbl[tp->chip_id].io_size);
-		kfree(dev);
-	}
-}
-
-
-static struct pci_driver tulip_driver = {
-	name:		TULIP_MODULE_NAME,
-	id_table:	tulip_pci_tbl,
-	probe:		tulip_init_one,
-	remove:		tulip_remove_one,
-	suspend:	tulip_suspend,
-	resume:		tulip_resume,
-};
-
-
-static int __init tulip_init (void)
-{
-	return pci_module_init (&tulip_driver);
-}
-
-
-static void __exit tulip_cleanup (void)
-{
-	pci_unregister_driver (&tulip_driver);
-}
-
-
-module_init(tulip_init);
-module_exit(tulip_cleanup);
diff -u --recursive --new-file v2.3.47/linux/drivers/net/wan/cosa.c linux/drivers/net/wan/cosa.c
--- v2.3.47/linux/drivers/net/wan/cosa.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/net/wan/cosa.c	Mon Feb 21 10:23:56 2000
@@ -1,4 +1,4 @@
-/* $Id: cosa.c,v 1.28 1999/10/11 21:06:58 kas Exp $ */
+/* $Id: cosa.c,v 1.30 2000/02/21 15:19:49 kas Exp $ */
 
 /*
  *  Copyright (C) 1995-1997  Jan "Yenya" Kasprzak <kas@fi.muni.cz>
@@ -222,6 +222,8 @@
 #undef DEBUG_IRQS 1	/* Print the message when the IRQ is received */
 #undef DEBUG_IO 1	/* Dump the I/O traffic */
 
+#define TX_TIMEOUT	(5*HZ)
+
 /* Maybe the following should be allocated dynamically */
 static struct cosa_data cosa_cards[MAX_CARDS];
 static int nr_cards = 0;
@@ -286,6 +288,7 @@
 static void sppp_channel_delete(struct channel_data *chan);
 static int cosa_sppp_open(struct net_device *d);
 static int cosa_sppp_close(struct net_device *d);
+static void cosa_sppp_timeout(struct net_device *d);
 static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *d);
 static char *sppp_setup_rx(struct channel_data *channel, int size);
 static int sppp_rx_done(struct channel_data *channel);
@@ -370,7 +373,7 @@
 {
 	int i;
 
-	printk(KERN_INFO "cosa v1.06 (c) 1997-8 Jan Kasprzak <kas@fi.muni.cz>\n");
+	printk(KERN_INFO "cosa v1.07 (c) 1997-2000 Jan Kasprzak <kas@fi.muni.cz>\n");
 #ifdef __SMP__
 	printk(KERN_INFO "cosa: SMP found. Please mail any success/failure reports to the author.\n");
 #endif
@@ -406,7 +409,6 @@
 #ifdef MODULE
 void cleanup_module (void)
 {
-	int i;
 	struct cosa_data *cosa;
 	printk(KERN_INFO "Unloading the cosa module\n");
 
@@ -595,6 +597,8 @@
 	d->hard_start_xmit = cosa_sppp_tx;
 	d->do_ioctl = cosa_sppp_ioctl;
 	d->get_stats = cosa_net_stats;
+	d->tx_timeout = cosa_sppp_timeout;
+	d->watchdog_timeo = TX_TIMEOUT;
 	dev_init_buffers(d);
 	if (register_netdev(d) == -1) {
 		printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
@@ -609,7 +613,6 @@
 	unregister_netdev(chan->pppdev.dev);
 }
 
-
 static int cosa_sppp_open(struct net_device *d)
 {
 	struct channel_data *chan = d->priv;
@@ -646,7 +649,7 @@
 		return err;
 	}
 
-	d->tbusy = 0;
+	netif_start_queue(d);
 	cosa_enable_rx(chan);
 	return 0;
 }
@@ -655,41 +658,39 @@
 {
 	struct channel_data *chan = dev->priv;
 
-	if (dev->tbusy) { 
-		if (time_before(jiffies, dev->trans_start+2*HZ))
-			return 1;	/* Two seconds timeout */
-		if (test_bit(RXBIT, &chan->cosa->rxtx)) {
-			chan->stats.rx_errors++;
-			chan->stats.rx_missed_errors++;
-		} else {
-			chan->stats.tx_errors++;
-			chan->stats.tx_aborted_errors++;
-		}
-		cosa_kick(chan->cosa);
-		if (chan->tx_skb) {
-			dev_kfree_skb(chan->tx_skb);
-			chan->tx_skb = 0;
-		}
-		dev->tbusy = 0;
-	}
-	if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
-		printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
-		return 1;
-	}
-	
+	netif_stop_queue(dev);
+
 	chan->tx_skb = skb;
-	dev->trans_start = jiffies;
 	cosa_start_tx(chan, skb->data, skb->len);
 	return 0;
 }
 
+static void cosa_sppp_timeout(struct net_device *dev)
+{
+	struct channel_data *chan = dev->priv;
+
+	if (test_bit(RXBIT, &chan->cosa->rxtx)) {
+		chan->stats.rx_errors++;
+		chan->stats.rx_missed_errors++;
+	} else {
+		chan->stats.tx_errors++;
+		chan->stats.tx_aborted_errors++;
+	}
+	cosa_kick(chan->cosa);
+	if (chan->tx_skb) {
+		dev_kfree_skb(chan->tx_skb);
+		chan->tx_skb = 0;
+	}
+	netif_wake_queue(dev);
+}
+
 static int cosa_sppp_close(struct net_device *d)
 {
 	struct channel_data *chan = d->priv;
 	int flags;
 
+	netif_stop_queue(d);
 	sppp_close(d);
-	d->tbusy = 1;
 	cosa_disable_rx(chan);
 	spin_lock_irqsave(&chan->cosa->lock, flags);
 	if (chan->rx_skb) {
@@ -760,8 +761,7 @@
 	chan->tx_skb = 0;
 	chan->stats.tx_packets++;
 	chan->stats.tx_bytes += size;
-	chan->pppdev.dev->tbusy = 0;
-	mark_bh(NET_BH);
+	netif_wake_queue(chan->pppdev.dev);
 	return 1;
 }
 
@@ -1350,14 +1350,14 @@
 static void cosa_kick(struct cosa_data *cosa)
 {
 	unsigned flags, flags1;
-	char *s = "Unknown";
+	char *s = "(probably) IRQ";
 
 	if (test_bit(RXBIT, &cosa->rxtx))
-		s = "RX";
+		s = "RX DMA";
 	if (test_bit(TXBIT, &cosa->rxtx))
-		s = "TX";
+		s = "TX DMA";
 
-	printk(KERN_INFO "%s: %s DMA timeout - restarting.\n", cosa->name, s); 
+	printk(KERN_INFO "%s: %s timeout - restarting.\n", cosa->name, s); 
 	spin_lock_irqsave(&cosa->lock, flags);
 	cosa->rxtx = 0;
 
diff -u --recursive --new-file v2.3.47/linux/drivers/net/wan/syncppp.c linux/drivers/net/wan/syncppp.c
--- v2.3.47/linux/drivers/net/wan/syncppp.c	Fri Jan 21 18:19:16 2000
+++ linux/drivers/net/wan/syncppp.c	Tue Feb 22 22:38:31 2000
@@ -50,6 +50,7 @@
 #include <linux/random.h>
 #include <linux/pkt_sched.h>
 #include <asm/byteorder.h>
+#include <linux/spinlock.h>
 #include "syncppp.h"
 
 #define MAXALIVECNT     6               /* max. alive packets */
@@ -126,6 +127,7 @@
 
 static struct sppp *spppq;
 static struct timer_list sppp_keepalive_timer;
+static spinlock_t spppq_lock;
 
 static void sppp_keepalive (unsigned long dummy);
 static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type,
@@ -359,8 +361,8 @@
 {
 	struct sppp *sp;
 	unsigned long flags;
-	save_flags(flags);
-	cli();
+
+	spin_lock_irqsave(&spppq_lock, flags);
 
 	for (sp=spppq; sp; sp=sp->pp_next) 
 	{
@@ -402,7 +404,7 @@
 				sp->lcp.echoid, 4, &nmagic);
 		}
 	}
-	restore_flags(flags);
+	spin_unlock_irqrestore(&spppq_lock, flags);
 	sppp_keepalive_timer.expires=jiffies+10*HZ;
 	add_timer(&sppp_keepalive_timer);
 }
@@ -915,7 +917,9 @@
 {
 	struct net_device *dev = pd->dev;
 	struct sppp *sp = &pd->sppp;
-	
+	unsigned long flags;
+
+	spin_lock_irqsave(&spppq_lock, flags);
 	/* Initialize keepalive handler. */
 	if (! spppq)
 	{
@@ -927,6 +931,7 @@
 	/* Insert new entry into the keepalive list. */
 	sp->pp_next = spppq;
 	spppq = sp;
+	spin_unlock_irqrestore(&spppq_lock, flags);
 
 	sp->pp_loopcnt = 0;
 	sp->pp_alivecnt = 0;
@@ -971,7 +976,9 @@
 void sppp_detach (struct net_device *dev)
 {
 	struct sppp **q, *p, *sp = (struct sppp *)sppp_of(dev);
+	unsigned long flags;
 
+	spin_lock_irqsave(&spppq_lock, flags);
 	/* Remove the entry from the keepalive list. */
 	for (q = &spppq; (p = *q); q = &p->pp_next)
 		if (p == sp) {
@@ -983,6 +990,7 @@
 	if (! spppq)
 		del_timer(&sppp_keepalive_timer);
 	sppp_clear_timeout (sp);
+	spin_unlock_irqrestore(&spppq_lock, flags);
 }
 
 EXPORT_SYMBOL(sppp_detach);
@@ -1292,6 +1300,7 @@
 {
 	printk(KERN_INFO "Cronyx Ltd, Synchronous PPP and CISCO HDLC (c) 1994\n");
 	printk(KERN_INFO "Linux port (c) 1998 Building Number Three Ltd & Jan \"Yenya\" Kasprzak.\n");
+	spin_lock_init(&spppq_lock);
 	sppp_packet_type.type=htons(ETH_P_WAN_PPP);	
 	dev_add_pack(&sppp_packet_type);
 }
diff -u --recursive --new-file v2.3.47/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
--- v2.3.47/linux/drivers/net/wavelan.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/net/wavelan.c	Mon Feb 21 20:51:51 2000
@@ -24,24 +24,24 @@
 
 /*------------------------------------------------------------------*/
 /*
- * Wrapper for disabling interrupts.
+ * Wrapper for disabling interrupts and locking the driver.
+ * (note : inline, so optimised away)
  */
-
-static inline unsigned long wv_splhi(void)
+static inline void wv_splhi(net_local *		lp,
+			    unsigned long *	pflags)
 {
-	unsigned long flags;
-	save_flags(flags);
-	cli();
-	return (flags);
+	spin_lock_irqsave(&lp->spinlock, *pflags);
+	/* Note : above does the cli(); itself */
 }
 
 /*------------------------------------------------------------------*/
 /*
- * Wrapper for re-enabling interrupts.
+ * Wrapper for re-enabling interrupts and un-locking the driver.
  */
-static inline void wv_splx(unsigned long flags)
+static inline void wv_splx(net_local *		lp,
+			   unsigned long *	pflags)
 {
-	restore_flags(flags);
+	spin_unlock_irqrestore(&lp->spinlock, *pflags);
 }
 
 /*------------------------------------------------------------------*/
@@ -180,13 +180,12 @@
 	unsigned long ioaddr = dev->base_addr;
 	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	wv_splhi(lp, &flags);
 	
 	lp->hacr &= ~HACR_INTRON;
 	hacr_write(ioaddr, lp->hacr);
 
-	restore_flags(flags);
+	wv_splx(lp, &flags);
 }				/* wv_ints_off */
 
 /*------------------------------------------------------------------*/
@@ -199,11 +198,12 @@
 	unsigned long ioaddr = dev->base_addr;
 	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	wv_splhi(lp, &flags);
+
 	lp->hacr |= HACR_INTRON;
 	hacr_write(ioaddr, lp->hacr);
-	restore_flags(flags);
+
+	wv_splx(lp, &flags);
 }				/* wv_ints_on */
 
 /******************* MODEM MANAGEMENT SUBROUTINES *******************/
@@ -707,7 +707,7 @@
 			printk(KERN_INFO
 			       "%s: wv_config_complete(): configure failed; status = 0x%x\n",
 			       dev->name, status);
-#endif				/* DEBUG_CONFIG_ERROR */
+#endif	/* DEBUG_CONFIG_ERROR */
 
 		ret = 1;	/* Ready to be scrapped */
 	}
@@ -723,6 +723,8 @@
 /*
  * Command completion interrupt.
  * Reclaim as many freed tx buffers as we can.
+ * (called in wavelan_interrupt()).
+ * Note : the spinlock is already grabbed for us.
  */
 static int wv_complete(device * dev, unsigned long ioaddr, net_local * lp)
 {
@@ -870,16 +872,20 @@
 {
 	net_local *lp = (net_local *) dev->priv;
 
+	/* Arm the flag, will be cleard in wv_82586_config() */
+	lp->reconfig_82586 = 1;
+
 	/* Check if we can do it now ! */
-	if (!netif_running(dev) && netif_queue_stopped(dev)) {
-		lp->reconfig_82586 = 1;
+	if((netif_running(dev)) && !(netif_queue_stopped(dev)))
+		/* May fail */
+		wv_82586_config(dev);
+	else {
 #ifdef DEBUG_CONFIG_INFO
 		printk(KERN_DEBUG
 		       "%s: wv_82586_reconfig(): delayed (state = %lX)\n",
 			       dev->name, dev->state);
 #endif
-	} else
-		wv_82586_config(dev);
+	}
 }
 
 /********************* DEBUG & INFO SUBROUTINES *********************/
@@ -1806,9 +1812,9 @@
 #endif
 
 	/* Disable interrupts and save flags. */
-	save_flags(flags);
-	cli();
+	wv_splhi(lp, &flags);
 	/* FIXME: can't copy*user when cli this is broken! */
+	/* Note : is it still valid ? Jean II */
 	
 	/* Look what is the request */
 	switch (cmd) {
@@ -2271,7 +2277,7 @@
 	}
 
 	/* Enable interrupts and restore flags. */
-	restore_flags(flags);
+	wv_splx(lp, &flags);
 
 #ifdef DEBUG_IOCTL_TRACE
 	printk(KERN_DEBUG "%s: <-wavelan_ioctl()\n", dev->name);
@@ -2297,15 +2303,12 @@
 	       dev->name);
 #endif
 
-	/* Disable interrupts and save flags. */
-	save_flags(flags);
-	cli();
-	
+	/* Check */
 	if (lp == (net_local *) NULL)
-	{
-		restore_flags(flags);
 		return (iw_stats *) NULL;
-	}
+	
+	/* Disable interrupts and save flags. */
+	wv_splhi(lp, &flags);
 	
 	wstats = &lp->wstats;
 
@@ -2333,7 +2336,7 @@
 	wstats->discard.misc = 0L;
 
 	/* Enable interrupts and restore flags. */
-	restore_flags(flags);
+	wv_splx(lp, &flags);
 
 #ifdef DEBUG_IOCTL_TRACE
 	printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n",
@@ -2455,7 +2458,8 @@
 /*
  * Transfer as many packets as we can
  * from the device RAM.
- * Called by the interrupt handler.
+ * (called in wavelan_interrupt()).
+ * Note : the spinlock is already grabbed for us.
  */
 static inline void wv_receive(device * dev)
 {
@@ -2640,7 +2644,7 @@
  *
  * (called in wavelan_packet_xmit())
  */
-static inline void wv_packet_write(device * dev, void *buf, short length)
+static inline int wv_packet_write(device * dev, void *buf, short length)
 {
 	net_local *lp = (net_local *) dev->priv;
 	unsigned long ioaddr = dev->base_addr;
@@ -2665,9 +2669,18 @@
 	if (clen < ETH_ZLEN)
 		clen = ETH_ZLEN;
 
-	save_flags(flags);
-	cli();
-	
+	wv_splhi(lp, &flags);
+
+	/* Check nothing bad has happened */
+	if (lp->tx_n_in_use == (NTXBLOCKS - 1)) {
+#ifdef DEBUG_TX_ERROR
+		printk(KERN_INFO "%s: wv_packet_write(): Tx queue full.\n",
+		       dev->name);
+#endif
+		wv_splx(lp, &flags);
+		return 1;
+	}
+
 	/* Calculate addresses of next block and previous block. */
 	txblock = lp->tx_first_free;
 	txpred = txblock - TXBLOCKZ;
@@ -2736,20 +2749,13 @@
 	/* Keep stats up to date. */
 	lp->stats.tx_bytes += length;
 
-	/* If watchdog not already active, activate it... */
-	if (lp->watchdog.prev == (timer_list *) NULL) {
-		/* Set timer to expire in WATCHDOG_JIFFIES. */
-		lp->watchdog.expires = jiffies + WATCHDOG_JIFFIES;
-		add_timer(&lp->watchdog);
-	}
-
 	if (lp->tx_first_in_use == I82586NULL)
 		lp->tx_first_in_use = txblock;
 
 	if (lp->tx_n_in_use < NTXBLOCKS - 1)
 		netif_wake_queue(dev);
 
-	restore_flags(flags);
+	wv_splx(lp, &flags);
 	
 #ifdef DEBUG_TX_INFO
 	wv_packet_info((u8 *) buf, length, dev->name,
@@ -2759,6 +2765,8 @@
 #ifdef DEBUG_TX_TRACE
 	printk(KERN_DEBUG "%s: <-wv_packet_write()\n", dev->name);
 #endif
+
+	return 0;
 }
 
 /*------------------------------------------------------------------*/
@@ -2781,7 +2789,6 @@
 	 * Block a timer-based transmit from overlapping.
 	 * In other words, prevent reentering this routine.
 	 */
-
 	netif_stop_queue(dev);
 
 	/* If somebody has asked to reconfigure the controller, 
@@ -2789,13 +2796,18 @@
 	 */
 	if (lp->reconfig_82586) {
 		wv_82586_config(dev);
+		/* Check that we can continue */
+		if (lp->tx_n_in_use == (NTXBLOCKS - 1))
+			return 1;
 	}
 #ifdef DEBUG_TX_ERROR
 	if (skb->next)
 		printk(KERN_INFO "skb has next\n");
 #endif
 
-	wv_packet_write(dev, skb->data, skb->len);
+	/* Write packet on the card */
+	if(wv_packet_write(dev, skb->data, skb->len))
+		return 1;	/* We failed */
 
 	dev_kfree_skb(skb);
 
@@ -3161,7 +3173,7 @@
 	}
 
 	lp->tx_n_in_use = 0;
-	netif_wake_queue(dev);
+	netif_start_queue(dev);
 #ifdef DEBUG_CONFIG_TRACE
 	printk(KERN_DEBUG "%s: <-wv_cu_start()\n", dev->name);
 #endif
@@ -3310,7 +3322,7 @@
  * as usual to the NOP command.
  * Note that only the last command (mc_set) will generate an interrupt.
  *
- * (called by wv_hw_reset(), wv_82586_reconfig())
+ * (called by wv_hw_reset(), wv_82586_reconfig(), wavelan_packet_xmit())
  */
 static void wv_82586_config(device * dev)
 {
@@ -3336,9 +3348,18 @@
 	printk(KERN_DEBUG "%s: ->wv_82586_config()\n", dev->name);
 #endif
 
-	save_flags(flags);
-	cli();
+	wv_splhi(lp, &flags);
 	
+	/* Check nothing bad has happened */
+	if (lp->tx_n_in_use == (NTXBLOCKS - 1)) {
+#ifdef DEBUG_CONFIG_ERROR
+		printk(KERN_INFO "%s: wv_82586_config(): Tx queue full.\n",
+		       dev->name);
+#endif
+		wv_splx(lp, &flags);
+		return;
+	}
+
 	/* Calculate addresses of next block and previous block. */
 	txblock = lp->tx_first_free;
 	txpred = txblock - TXBLOCKZ;
@@ -3467,22 +3488,17 @@
 		    (unsigned char *) &nop.nop_h.ac_link,
 		    sizeof(nop.nop_h.ac_link));
 
-	/* If watchdog not already active, activate it... */
-	if (lp->watchdog.prev == (timer_list *) NULL) {
-		/* set timer to expire in WATCHDOG_JIFFIES */
-		lp->watchdog.expires = jiffies + WATCHDOG_JIFFIES;
-		add_timer(&lp->watchdog);
-	}
-
+	/* Job done, clear the flag */
 	lp->reconfig_82586 = 0;
 
 	if (lp->tx_first_in_use == I82586NULL)
 		lp->tx_first_in_use = txblock;
 
-	if (lp->tx_n_in_use < NTXBLOCKS - 1)
-		netif_wake_queue(dev);
+	if (lp->tx_n_in_use == (NTXBLOCKS - 1))
+		netif_stop_queue(dev);
+
+	wv_splx(lp, &flags);
 
-	restore_flags(flags);
 #ifdef DEBUG_CONFIG_TRACE
 	printk(KERN_DEBUG "%s: <-wv_82586_config()\n", dev->name);
 #endif
@@ -3539,10 +3555,6 @@
 	       (unsigned int) dev);
 #endif
 
-	/* If watchdog was activated, kill it! */
-	if (lp->watchdog.prev != (timer_list *) NULL)
-		del_timer(&lp->watchdog);
-
 	/* Increase the number of resets done. */
 	lp->nresets++;
 
@@ -3637,8 +3649,19 @@
 	lp = (net_local *) dev->priv;
 	ioaddr = dev->base_addr;
 
-	/* Prevent reentrance. What should we do here? */
+#ifdef DEBUG_INTERRUPT_ERROR
+	/* Check state of our spinlock (it should be cleared) */
+	if(spin_is_locked(&lp->spinlock))
+		printk(KERN_INFO
+		       "%s: wavelan_interrupt(): spinlock is already locked !!!\n",
+		       dev->name);
+#endif
+
+	/* Prevent reentrancy. It is safe because wv_splhi disable interrupts
+	 * before aquiring the spinlock */
+	spin_lock(&lp->spinlock);
 
+	/* Check modem interupt */
 	if ((hasr = hasr_read(ioaddr)) & HASR_MMC_INTR) {
 		u8 dce_status;
 
@@ -3655,6 +3678,7 @@
 #endif
 	}
 
+	/* Check if not controller interrupt */
 	if ((hasr & HASR_82586_INTR) == 0) {
 #ifdef DEBUG_INTERRUPT_ERROR
 		printk(KERN_INFO
@@ -3689,15 +3713,6 @@
 		       dev->name);
 #endif
 		wv_complete(dev, ioaddr, lp);
-
-		/* If watchdog was activated, kill it ! */
-		if (lp->watchdog.prev != (timer_list *) NULL)
-			del_timer(&lp->watchdog);
-		if (lp->tx_n_in_use > 0) {
-			/* set timer to expire in WATCHDOG_JIFFIES */
-			lp->watchdog.expires = jiffies + WATCHDOG_JIFFIES;
-			add_timer(&lp->watchdog);
-		}
 	}
 
 	/* Frame received. */
@@ -3710,9 +3725,13 @@
 		wv_receive(dev);
 	}
 
+	/* Release spinlock here so that wv_hw_reset() can grab it */
+	spin_unlock (&lp->lock);
+
 	/* Check the state of the command unit. */
 	if (((status & SCB_ST_CNA) == SCB_ST_CNA) ||
-	    (((status & SCB_ST_CUS) != SCB_ST_CUS_ACTV) && netif_running(dev))) {
+	    (((status & SCB_ST_CUS) != SCB_ST_CUS_ACTV) &&
+	     (netif_running(dev)))) {
 #ifdef DEBUG_INTERRUPT_ERROR
 		printk(KERN_INFO
 		       "%s: wavelan_interrupt(): CU inactive -- restarting\n",
@@ -3723,7 +3742,8 @@
 
 	/* Check the state of the command unit. */
 	if (((status & SCB_ST_RNR) == SCB_ST_RNR) ||
-	    (((status & SCB_ST_RUS) != SCB_ST_RUS_RDY) && netif_running(dev))) {
+	    (((status & SCB_ST_RUS) != SCB_ST_RUS_RDY) &&
+	     (netif_running(dev)))) {
 #ifdef DEBUG_INTERRUPT_ERROR
 		printk(KERN_INFO
 		       "%s: wavelan_interrupt(): RU not ready -- restarting\n",
@@ -3739,26 +3759,16 @@
 
 /*------------------------------------------------------------------*/
 /*
- * Watchdog: when we start a transmission, we set a timer in the
+ * Watchdog: when we start a transmission, a timer is set for us in the
  * kernel.  If the transmission completes, this timer is disabled. If
- * the timer expires, we try to unlock the hardware.
- *
- * Note: this watchdog doesn't work on the same principle as the
- * watchdog in the previous version of the ISA driver. I made it this
- * way because the overhead of add_timer() and del_timer() is nothing
- * and because it avoids calling the watchdog, saving some CPU.
+ * the timer expires, we are called and we try to unlock the hardware.
  */
-static void wavelan_watchdog(unsigned long a)
+static void wavelan_watchdog(device *	dev)
 {
-	device *dev;
-	net_local *lp;
-	unsigned long ioaddr;
-	unsigned long flags;
-	unsigned int nreaped;
-
-	dev = (device *) a;
-	ioaddr = dev->base_addr;
-	lp = (net_local *) dev->priv;
+	net_local *	lp = (net_local *)dev->priv;
+	u_long		ioaddr = dev->base_addr;
+	unsigned long	flags;
+	unsigned int	nreaped;
 
 #ifdef DEBUG_INTERRUPT_TRACE
 	printk(KERN_DEBUG "%s: ->wavelan_watchdog()\n", dev->name);
@@ -3769,18 +3779,16 @@
 	       dev->name);
 #endif
 
-	save_flags(flags);
-	cli();
-	
-	dev = (device *) a;
-	ioaddr = dev->base_addr;
-	lp = (net_local *) dev->priv;
+	wv_splhi(lp, &flags);
 
+	/* Check that we came here for something */
 	if (lp->tx_n_in_use <= 0) {
-		restore_flags(flags);
+		wv_splx(lp, &flags);
 		return;
 	}
 
+	/* Try to see if some buffers are not free (in case we missed
+	 * an interrupt */
 	nreaped = wv_complete(dev, ioaddr, lp);
 
 #ifdef DEBUG_INTERRUPT_INFO
@@ -3811,15 +3819,13 @@
 		       dev->name);
 #endif
 		wv_hw_reset(dev);
-	} else
-		/* Reset watchdog for next transmission. */
-	if (lp->tx_n_in_use > 0) {
-		/* set timer to expire in WATCHDOG_JIFFIES */
-		lp->watchdog.expires = jiffies + WATCHDOG_JIFFIES;
-		add_timer(&lp->watchdog);
 	}
 
-	restore_flags(flags);
+	/* At this point, we should have some free Tx buffer ;-) */
+	if (lp->tx_n_in_use < NTXBLOCKS - 1)
+		netif_wake_queue(dev);
+
+	wv_splx(lp, &flags);
 	
 #ifdef DEBUG_INTERRUPT_TRACE
 	printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name);
@@ -3840,7 +3846,8 @@
  */
 static int wavelan_open(device * dev)
 {
-	unsigned long flags;
+	net_local *	lp = (net_local *)dev->priv;
+	unsigned long	flags;
 
 #ifdef DEBUG_CALLBACK_TRACE
 	printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name,
@@ -3865,8 +3872,7 @@
 		return -EAGAIN;
 	}
 
-	save_flags(flags);
-	cli();
+	wv_splhi(lp, &flags);
 	
 	if (wv_hw_reset(dev) != -1) {
 		netif_start_queue(dev);
@@ -3879,7 +3885,7 @@
 #endif
 		return -EAGAIN;
 	}
-	restore_flags(flags);
+	wv_splx(lp, &flags);
 	
 	MOD_INC_USE_COUNT;
 
@@ -3896,8 +3902,6 @@
  */
 static int wavelan_close(device * dev)
 {
-	net_local *lp = (net_local *) dev->priv;
-
 #ifdef DEBUG_CALLBACK_TRACE
 	printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
 	       (unsigned int) dev);
@@ -3905,10 +3909,6 @@
 
 	netif_stop_queue(dev);
 
-	/* If watchdog was activated, kill it! */
-	if (lp->watchdog.prev != (timer_list *) NULL)
-		del_timer(&lp->watchdog);
-
 	/*
 	 * Flush the Tx and disable Rx.
 	 */
@@ -4001,11 +4001,13 @@
 
 	lp->hacr = HACR_DEFAULT;
 
-	lp->watchdog.function = wavelan_watchdog;
-	lp->watchdog.data = (unsigned long) dev;
+	/* Multicast stuff */
 	lp->promiscuous = 0;
 	lp->mc_count = 0;
 
+	/* Init spinlock */
+	spin_lock_init(&lp->lock);
+
 	/*
 	 * Fill in the fields of the device structure
 	 * with generic Ethernet values.
@@ -4017,6 +4019,8 @@
 	dev->hard_start_xmit = wavelan_packet_xmit;
 	dev->get_stats = wavelan_get_stats;
 	dev->set_multicast_list = &wavelan_set_multicast_list;
+        dev->tx_timeout		= &wavelan_watchdog;
+        dev->watchdog_timeo	= WATCHDOG_JIFFIES;
 #ifdef SET_MAC_ADDRESS
 	dev->set_mac_address = &wavelan_set_mac_address;
 #endif				/* SET_MAC_ADDRESS */
diff -u --recursive --new-file v2.3.47/linux/drivers/net/wavelan.p.h linux/drivers/net/wavelan.p.h
--- v2.3.47/linux/drivers/net/wavelan.p.h	Tue Dec  7 09:32:44 1999
+++ linux/drivers/net/wavelan.p.h	Mon Feb 21 20:51:51 2000
@@ -34,6 +34,25 @@
  *	I try to maintain a web page with the Wireless LAN Howto at :
  *	    http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html
  *
+ * SMP
+ * ---
+ *	We now *should* be SMP compliant.
+ *	I don't have a SMP box to verify that (my Pentium 90 is not), so
+ *	someone has to certify that from me.
+ *	Anyway, I spent enough time chasing interrupt re-entrancy during
+ *	errors or reconfigure, and I designed the locked/unlocked sections
+ *	of the driver with great care, and with the recent addition of
+ *	the spinlock (thanks to the new API), we should be quite close to
+ *	the truth.
+ *	The SMP/IRQ locking is quite coarse and conservative (i.e. not fast),
+ *	but better safe than sorry (especially at 2 Mb/s ;-).
+ *
+ *	I have also looked into disabling only our interrupt on the card
+ *	(via HACR) instead of all interrupts in the processor (via cli),
+ *	so that other driver are not impacted, and it look like it's
+ *	possible, but it's very tricky to do right (full of races). As
+ *	the gain would be mostly for SMP systems, it can wait...
+ *
  * Debugging and options
  * ---------------------
  *	You will find below a set of '#define" allowing a very fine control
@@ -171,7 +190,7 @@
  *
  * Thanks go also to:
  *	James Ashton <jaa101@syseng.anu.edu.au>,
- *	Alan Cox <iialan@iiit.swan.ac.uk>,
+ *	Alan Cox <alan@redhat.com>,
  *	Allan Creighton <allanc@cs.usyd.edu.au>,
  *	Matthew Geier <matthew@cs.usyd.edu.au>,
  *	Remo di Giovanni <remo@cs.usyd.edu.au>,
@@ -188,8 +207,9 @@
  *
  * Additional Credits:
  *
- *	My development has been done under Linux 2.0.x (Debian 1.1) with
- *	an HP Vectra XP/60.
+ *	My development has been done initially under Debian 1.1 (Linux 2.0.x)
+ *	and now	under Debian 2.2, initially with an HP Vectra XP/60, and now
+ *	an HP Vectra XP/90.
  *
  */
 
@@ -305,6 +325,21 @@
  *	- Fix check for root permission (break instead of exit)
  *	- New nwid & encoding setting (Wireless Extension 9)
  *
+ * Changes made for release in 2.3.49 :
+ * ----------------------------------
+ *	- Indentation reformating (Alan)
+ *	- Update to new network API (softnet - 2.3.43) :
+ *		o replace dev->tbusy (Alan)
+ *		o replace dev->tstart (Alan)
+ *		o remove dev->interrupt (Alan)
+ *		o add SMP locking via spinlock in splxx (me)
+ *		o add spinlock in interrupt handler (me)
+ *		o use kernel watchdog instead of ours (me)
+ *		o increase watchdog timeout (kernel is more sensitive) (me)
+ *		o verify that all the changes make sense and work (me)
+ *	- Fixup a potential gotcha when reconfiguring and thighten a bit
+ *		the interactions with Tx queue.
+ *
  * Wishes & dreams:
  * ----------------
  *	- roaming (see Pcmcia driver)
@@ -395,11 +430,11 @@
 /************************ CONSTANTS & MACROS ************************/
 
 #ifdef DEBUG_VERSION_SHOW
-static const char	*version	= "wavelan.c : v21 (wireless extensions) 16/10/99\n";
+static const char	*version	= "wavelan.c : v22 (wireless extensions) 21/02/00\n";
 #endif
 
 /* Watchdog temporisation */
-#define	WATCHDOG_JIFFIES	(256*HZ/100)
+#define	WATCHDOG_JIFFIES	(512*HZ/100)
 
 /* Macro to get the number of elements in an array */
 #define	NELS(a)				(sizeof(a) / sizeof(a[0]))
@@ -441,12 +476,12 @@
 {
   net_local *	next;		/* linked list of the devices */
   device *	dev;		/* reverse link */
+  spinlock_t	spinlock;	/* Serialize access to the hardware (SMP) */
   en_stats	stats;		/* Ethernet interface statistics */
   int		nresets;	/* number of hardware resets */
   u_char	reconfig_82586;	/* We need to reconfigure the controller. */
   u_char	promiscuous;	/* promiscuous mode */
   int		mc_count;	/* number of multicast addresses */
-  timer_list	watchdog;	/* to avoid blocking state */
   u_short	hacr;		/* current host interface state */
 
   int		tx_n_in_use;
@@ -475,10 +510,12 @@
 /**************************** PROTOTYPES ****************************/
 
 /* ----------------------- MISC. SUBROUTINES ------------------------ */
-static inline unsigned long	/* flags */
-	wv_splhi(void);		/* Disable interrupts */
 static inline void
-	wv_splx(unsigned long);	/* Enable interrupts:  flags */
+	wv_splhi(net_local *,		/* Disable interrupts, lock driver */
+		 unsigned long *);	/* flags */
+static inline void
+	wv_splx(net_local *,		/* Enable interrupts, unlock driver */
+		unsigned long *);	/* flags */
 static u_char
 	wv_irq_to_psa(int);
 static int
@@ -580,7 +617,7 @@
 		       int),
 	wv_receive(device *);	/* Read all packets waiting. */
 /* --------------------- PACKET TRANSMISSION --------------------- */
-static inline void
+static inline int
 	wv_packet_write(device *,	/* Write a packet to the Tx buffer. */
 			void *,
 			short);
@@ -607,7 +644,7 @@
 			  void *,
 			  struct pt_regs *);
 static void
-	wavelan_watchdog(u_long);	/* transmission watchdog */
+	wavelan_watchdog(device *);	/* transmission watchdog */
 /* ------------------- CONFIGURATION CALLBACKS ------------------- */
 static int
 	wavelan_open(device *),		/* Open the device. */
diff -u --recursive --new-file v2.3.47/linux/drivers/parport/daisy.c linux/drivers/parport/daisy.c
--- v2.3.47/linux/drivers/parport/daisy.c	Sat Jul  3 10:45:04 1999
+++ linux/drivers/parport/daisy.c	Tue Feb 22 22:42:16 2000
@@ -1,7 +1,7 @@
 /*
  * IEEE 1284.3 Parallel port daisy chain and multiplexor code
  * 
- * Copyright (C) 1999  Tim Waugh <tim@cyberelk.demon.co.uk>
+ * Copyright (C) 1999, 2000  Tim Waugh <tim@cyberelk.demon.co.uk>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -12,6 +12,7 @@
  * 31-01-1999: Make port-cloning transparent.
  * 13-02-1999: Move DeviceID technique from parport_probe.
  * 13-03-1999: Get DeviceID from non-IEEE 1284.3 devices too.
+ * 22-02-2000: Count devices that are actually detected.
  *
  */
 
@@ -80,9 +81,11 @@
 	return extra;
 }
 
-/* Discover the IEEE1284.3 topology on a port -- muxes and daisy chains. */
+/* Discover the IEEE1284.3 topology on a port -- muxes and daisy chains.
+ * Return value is number of devices actually detected. */
 int parport_daisy_init (struct parport *port)
 {
+	int detected = 0;
 	char *deviceid;
 	static const char *th[] = { /*0*/"th", "st", "nd", "rd", "th" };
 	int num_ports;
@@ -128,7 +131,7 @@
 		select_port (port);
 
 	parport_daisy_deselect_all (port);
-	assign_addrs (port);
+	detected += assign_addrs (port);
 
 	/* Count the potential legacy device at the end. */
 	add_dev (numdevs++, port, -1);
@@ -136,25 +139,31 @@
 	/* Find out the legacy device's IEEE 1284 device ID. */
 	deviceid = kmalloc (1000, GFP_KERNEL);
 	if (deviceid) {
-		parport_device_id (numdevs - 1, deviceid, 1000);
+		if (parport_device_id (numdevs - 1, deviceid, 1000) > 2)
+			detected++;
+
 		kfree (deviceid);
 	}
 
-	return 0;
+	return detected;
 }
 
 /* Forget about devices on a physical port. */
 void parport_daisy_fini (struct parport *port)
 {
 	struct daisydev *dev, *prev = topology;
-	while (prev && prev->port == port)
-		prev = topology = topology->next;
+	while (prev && prev->port == port) {
+		topology = topology->next;
+		kfree (prev);
+		prev = topology;
+	}
 
 	while (prev) {
 		dev = prev->next;
 		if (dev && dev->port == port)
 			prev->next = dev->next;
 
+		kfree (dev);
 		prev = prev->next;
 	}
 
@@ -162,7 +171,8 @@
            someone enumerate through all IEEE1284.3 devices in the
            topology?. */
 	if (!topology) numdevs = 0;
-	return; }
+	return;
+}
 
 /* Find a device by canonical device number. */
 struct pardevice *parport_open (int devnum, const char *name,
@@ -371,7 +381,7 @@
 		  | PARPORT_STATUS_ERROR)) {
 		DPRINTK (KERN_DEBUG "%s: assign_addrs: aa5500ff(%02x)\n",
 			 port->name, s);
-		return -ENXIO;
+		return 0;
 	}
 
 	parport_write_data (port, 0x87); udelay (2);
@@ -382,7 +392,7 @@
 	if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) {
 		DPRINTK (KERN_DEBUG "%s: assign_addrs: aa5500ff87(%02x)\n",
 			 port->name, s);
-		return -ENXIO;
+		return 0;
 	}
 
 	parport_write_data (port, 0x78); udelay (2);
@@ -421,7 +431,7 @@
 		parport_device_id (thisdev, deviceid, 1000);
 
 	kfree (deviceid);
-	return 0;
+	return numdevs - thisdev;
 }
 
 /* Find a device with a particular manufacturer and model string,
diff -u --recursive --new-file v2.3.47/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
--- v2.3.47/linux/drivers/parport/parport_pc.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/parport/parport_pc.c	Sat Feb 26 20:34:34 2000
@@ -681,6 +681,7 @@
 
 	/* Set up parallel port FIFO mode.*/
 	parport_pc_data_forward (port); /* Must be in PS2 mode */
+	parport_pc_frob_control (port, PARPORT_CONTROL_STROBE, 0);
 	change_mode (port, ECR_PPF); /* Parallel port FIFO */
 	port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;
 
@@ -747,6 +748,10 @@
 
 	/* Set up ECP parallel port mode.*/
 	parport_pc_data_forward (port); /* Must be in PS2 mode */
+	parport_pc_frob_control (port,
+				 PARPORT_CONTROL_STROBE |
+				 PARPORT_CONTROL_AUTOFD,
+				 0);
 	change_mode (port, ECR_ECP); /* ECP FIFO */
 	port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;
 
@@ -850,6 +855,10 @@
 
 	/* Set up ECP parallel port mode.*/
 	parport_pc_data_reverse (port); /* Must be in PS2 mode */
+	parport_pc_frob_control (port,
+				 PARPORT_CONTROL_STROBE |
+				 PARPORT_CONTROL_AUTOFD,
+				 0);
 	change_mode (port, ECR_ECP); /* ECP FIFO */
 	port->ieee1284.phase = IEEE1284_PH_REV_DATA;
 
@@ -989,7 +998,7 @@
 /*
  * Checks for port existence, all ports support SPP MODE
  */
-static int __maybe_init parport_SPP_supported(struct parport *pb)
+static int __devinit parport_SPP_supported(struct parport *pb)
 {
 	unsigned char r, w;
 
@@ -1066,7 +1075,7 @@
  * two bits of ECR aren't writable, so we check by writing ECR and
  * reading it back to see if it's what we expect.
  */
-static int __maybe_init parport_ECR_present(struct parport *pb)
+static int __devinit parport_ECR_present(struct parport *pb)
 {
 	struct parport_pc_private *priv = pb->private_data;
 	unsigned char r = 0xc;
@@ -1118,7 +1127,7 @@
  * be misdetected here is rather academic. 
  */
 
-static int __maybe_init parport_PS2_supported(struct parport *pb)
+static int __devinit parport_PS2_supported(struct parport *pb)
 {
 	int ok = 0;
   
@@ -1146,7 +1155,7 @@
 	return ok;
 }
 
-static int __maybe_init parport_ECP_supported(struct parport *pb)
+static int __devinit parport_ECP_supported(struct parport *pb)
 {
 	int i;
 	int config;
@@ -1257,7 +1266,7 @@
 	return 1;
 }
 
-static int __maybe_init parport_ECPPS2_supported(struct parport *pb)
+static int __devinit parport_ECPPS2_supported(struct parport *pb)
 {
 	const struct parport_pc_private *priv = pb->private_data;
 	int result;
@@ -1277,7 +1286,7 @@
 
 /* EPP mode detection  */
 
-static int __maybe_init parport_EPP_supported(struct parport *pb)
+static int __devinit parport_EPP_supported(struct parport *pb)
 {
 	const struct parport_pc_private *priv = pb->private_data;
 
@@ -1320,7 +1329,7 @@
 	return 1;
 }
 
-static int __maybe_init parport_ECPEPP_supported(struct parport *pb)
+static int __devinit parport_ECPEPP_supported(struct parport *pb)
 {
 	struct parport_pc_private *priv = pb->private_data;
 	int result;
@@ -1351,18 +1360,18 @@
 #else /* No IEEE 1284 support */
 
 /* Don't bother probing for modes we know we won't use. */
-static int __maybe_init parport_PS2_supported(struct parport *pb) { return 0; }
-static int __maybe_init parport_ECP_supported(struct parport *pb) { return 0; }
-static int __maybe_init parport_EPP_supported(struct parport *pb) { return 0; }
-static int __maybe_init parport_ECPEPP_supported(struct parport *pb){return 0;}
-static int __maybe_init parport_ECPPS2_supported(struct parport *pb){return 0;}
+static int __devinit parport_PS2_supported(struct parport *pb) { return 0; }
+static int __devinit parport_ECP_supported(struct parport *pb) { return 0; }
+static int __devinit parport_EPP_supported(struct parport *pb) { return 0; }
+static int __devinit parport_ECPEPP_supported(struct parport *pb){return 0;}
+static int __devinit parport_ECPPS2_supported(struct parport *pb){return 0;}
 
 #endif /* No IEEE 1284 support */
 
 /* --- IRQ detection -------------------------------------- */
 
 /* Only if supports ECP mode */
-static int __maybe_init programmable_irq_support(struct parport *pb)
+static int __devinit programmable_irq_support(struct parport *pb)
 {
 	int irq, intrLine;
 	unsigned char oecr = inb (ECONTROL (pb));
@@ -1379,7 +1388,7 @@
 	return irq;
 }
 
-static int __maybe_init irq_probe_ECP(struct parport *pb)
+static int __devinit irq_probe_ECP(struct parport *pb)
 {
 	int i;
 	unsigned long irqs;
@@ -1408,7 +1417,7 @@
  * This detection seems that only works in National Semiconductors
  * This doesn't work in SMC, LGS, and Winbond 
  */
-static int __maybe_init irq_probe_EPP(struct parport *pb)
+static int __devinit irq_probe_EPP(struct parport *pb)
 {
 #ifndef ADVANCED_DETECT
 	return PARPORT_IRQ_NONE;
@@ -1448,7 +1457,7 @@
 #endif /* Advanced detection */
 }
 
-static int __maybe_init irq_probe_SPP(struct parport *pb)
+static int __devinit irq_probe_SPP(struct parport *pb)
 {
 	/* Don't even try to do this. */
 	return PARPORT_IRQ_NONE;
@@ -1461,7 +1470,7 @@
  * When ECP is available we can autoprobe for IRQs.
  * NOTE: If we can autoprobe it, we can register the IRQ.
  */
-static int __maybe_init parport_irq_probe(struct parport *pb)
+static int __devinit parport_irq_probe(struct parport *pb)
 {
 	const struct parport_pc_private *priv = pb->private_data;
 
@@ -1495,7 +1504,7 @@
 /* --- DMA detection -------------------------------------- */
 
 /* Only if supports ECP mode */
-static int __maybe_init programmable_dma_support (struct parport *p)
+static int __devinit programmable_dma_support (struct parport *p)
 {
 	unsigned char oecr = inb (ECONTROL (p));
 	int dma;
@@ -1510,7 +1519,7 @@
 	return dma;
 }
 
-static int __maybe_init parport_dma_probe (struct parport *p)
+static int __devinit parport_dma_probe (struct parport *p)
 {
 	const struct parport_pc_private *priv = p->private_data;
 	if (priv->ecr)
@@ -1521,7 +1530,7 @@
 
 /* --- Initialisation code -------------------------------- */
 
-struct parport *__maybe_init parport_pc_probe_port (unsigned long int base,
+struct parport *__devinit parport_pc_probe_port (unsigned long int base,
 						    unsigned long int base_hi,
 						    int irq, int dma,
 						    struct pci_dev *dev)
@@ -1693,9 +1702,7 @@
 #endif /* CONFIG_PARPORT_PC_FIFO */
 	}
 
-	/* Done probing.  Now put the port into a sensible start-up state.
-	 * SELECT | INIT also puts IEEE1284-compliant devices into
-	 * compatibility mode. */
+	/* Done probing.  Now put the port into a sensible start-up state. */
 	if (priv->ecr)
 		/*
 		 * Put the ECP detected port in PS2 mode.
@@ -1714,9 +1721,143 @@
 	return p;
 }
 
+
+static int __devinit sio_via_686a_probe (struct pci_dev *pdev)
+{
+	u8 dma, irq, tmp;
+	unsigned port1, port2, have_eppecp;
+
+	/*
+	 * unlock super i/o configuration, set 0x85_1
+	 */
+	pci_read_config_byte (pdev, 0x85, &tmp);
+	tmp |= (1 << 1);
+	pci_write_config_byte (pdev, 0x85, tmp);
+	
+	/* 
+	 * Super I/O configuration, index port == 3f0h, data port == 3f1h
+	 */
+	
+	/* 0xE2_1-0: Parallel Port Mode / Enable */
+	outb (0xE2, 0x3F0);
+	tmp = inb (0x3F1);
+	
+	if ((tmp & 0x03) == 0x03) {
+		printk (KERN_INFO "parport_pc: Via 686A parallel port disabled in BIOS\n");
+		return 0;
+	}
+	
+	/* 0xE6: Parallel Port I/O Base Address, bits 9-2 */
+	outb (0xE6, 0x3F0);
+	port1 = inb (0x3F1) << 2;
+	
+	switch (port1) {
+	case 0x3bc: port2 = 0x7bc; break;
+	case 0x378: port2 = 0x778; break;
+	case 0x278: port2 = 0x678; break;
+	default:
+		printk (KERN_INFO "parport_pc: Via 686A weird parport base 0x%X, ignoring\n",
+			port1);
+		return 0;
+	}
+
+	/* 0xF0_5: EPP+ECP enable */
+	outb (0xF0, 0x3F0);
+	have_eppecp = (inb (0x3F1) & (1 << 5));
+	
+	/*
+	 * lock super i/o configuration, clear 0x85_1
+	 */
+	pci_read_config_byte (pdev, 0x85, &tmp);
+	tmp &= ~(1 << 1);
+	pci_write_config_byte (pdev, 0x85, tmp);
+
+	/*
+	 * Get DMA and IRQ from PCI->ISA bridge PCI config registers
+	 */
+
+	/* 0x50_3-2: PnP Routing for Parallel Port DRQ */
+	pci_read_config_byte (pdev, 0x50, &dma);
+	dma = ((dma >> 2) & 0x03);
+	
+	/* 0x51_7-4: PnP Routing for Parallel Port IRQ */
+	pci_read_config_byte (pdev, 0x51, &irq);
+	irq = ((irq >> 4) & 0x0F);
+
+	/* filter bogus IRQs */
+	switch (irq) {
+	case 0:
+	case 2:
+	case 8:
+	case 13:
+		irq = PARPORT_IRQ_NONE;
+		break;
+
+	default: /* do nothing */
+		break;
+	}
+
+	/* if ECP not enabled, DMA is not enabled, assumed bogus 'dma' value */
+	if (!have_eppecp)
+		dma = PARPORT_DMA_NONE;
+
+	/* finally, do the probe with values obtained */
+	if (parport_pc_probe_port (port1, port2, irq, dma, NULL)) {
+		printk (KERN_INFO "parport_pc: Via 686A parallel port: io=0x%X, irq=%d, dma=%d\n",
+			port1, irq, dma);
+		return 1;
+	}
+	
+	printk (KERN_WARNING "parport_pc: Strange, can't probe Via 686A parallel port: io=0x%X, irq=%d, dma=%d\n",
+		port1, irq, dma);
+	return 0;
+}
+
+
+enum parport_pc_sio_types {
+	sio_via_686a = 0,	/* Via VT82C686A motherboard Super I/O */
+};
+
+
+/* each element directly indexed from enum list, above */
+static struct parport_pc_superio {
+	int (*probe) (struct pci_dev *pdev);
+} parport_pc_superio_info[] __devinitdata = {
+	{ sio_via_686a_probe, },
+};
+
+
+static struct pci_device_id parport_pc_pci_tbl[] __devinitdata = {
+	{ 0x1106, 0x0686, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sio_via_686a },
+	{ 0, }, /* terminate list */
+};
+
+
+static int __devinit parport_pc_init_superio(void)
+{
+	const struct pci_device_id *id;
+	struct pci_dev *pdev;
+	
+	pci_for_each_dev(pdev) {
+		id = pci_match_device (parport_pc_pci_tbl, pdev);
+		if (id == NULL)
+			continue;
+		
+		return parport_pc_superio_info[id->driver_data].probe (pdev);
+	}
+	
+	return 0; /* zero devices found */
+}
+
+
 /* Look for PCI parallel port cards. */
 static int __init parport_pc_init_pci (int irq, int dma)
 {
+#ifndef PCI_VENDOR_ID_AFAVLAB
+#define PCI_VENDOR_ID_AFAVLAB		0x14db
+#define PCI_DEVICE_ID_AFAVLAB_TK9902	0x2120
+#endif
+
 	struct {
 		unsigned int vendor;
 		unsigned int device;
@@ -1800,6 +1941,9 @@
 		{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
 		  PCI_SUBVENDOR_ID_EXSYS, PCI_SUBDEVICE_ID_EXSYS_4014,
 		  2, { { 4, -1 }, { 5, -1 }, } },
+		{ PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_TK9902,
+		  PCI_ANY_ID, PCI_ANY_ID,
+		  1, { { 0, 1 }, } },
 		{ 0, }
 	};
 
diff -u --recursive --new-file v2.3.47/linux/drivers/parport/probe.c linux/drivers/parport/probe.c
--- v2.3.47/linux/drivers/parport/probe.c	Thu Feb 10 17:11:12 2000
+++ linux/drivers/parport/probe.c	Thu Feb 24 10:08:32 2000
@@ -150,13 +150,11 @@
 	if (!retval) {
 		int idlen;
 		unsigned char length[2];
-		mm_segment_t oldfs = get_fs ();
-		set_fs (get_ds ());
 
 		/* First two bytes are MSB,LSB of inclusive length. */
 		retval = parport_read (dev->port, length, 2);
 
-		if (retval != 2) goto restore_fs;
+		if (retval != 2) goto end_id;
 
 		idlen = (length[0] << 8) + length[1] - 2;
 		if (idlen < len)
@@ -169,8 +167,8 @@
 				len);
 
 		/* Some printer manufacturers mistakenly believe that
-                   the length field is supposed to be _exclusive_. */
-		/* In addition, there are broken devices out there
+                   the length field is supposed to be _exclusive_.
+		   In addition, there are broken devices out there
                    that don't even finish off with a semi-colon. */
 		if (buffer[len - 1] != ';') {
 			ssize_t diff;
@@ -196,9 +194,8 @@
 			}
 		}
 
-	restore_fs:
+	end_id:
 		buffer[len] = '\0';
-		set_fs (oldfs);
 		parport_negotiate (dev->port, IEEE1284_MODE_COMPAT);
 	}
 	parport_release (dev);
diff -u --recursive --new-file v2.3.47/linux/drivers/parport/share.c linux/drivers/parport/share.c
--- v2.3.47/linux/drivers/parport/share.c	Tue Jan  4 13:57:17 2000
+++ linux/drivers/parport/share.c	Tue Feb 22 22:42:16 2000
@@ -247,7 +247,19 @@
 {
 #ifdef CONFIG_PARPORT_1284
 	/* Analyse the IEEE1284.3 topology of the port. */
-	parport_daisy_init (port);
+	if (parport_daisy_init (port) == 0) {
+		/* No devices were detected.  Perhaps they are in some
+                   funny state; let's try to reset them and see if
+                   they wake up. */
+		parport_daisy_fini (port);
+		parport_write_control (port, PARPORT_CONTROL_SELECT);
+		udelay (50);
+		parport_write_control (port,
+				       PARPORT_CONTROL_SELECT |
+				       PARPORT_CONTROL_INIT);
+		udelay (50);
+		parport_daisy_init (port);
+	}
 #endif
 
 	/* Let drivers know that a new port has arrived. */
diff -u --recursive --new-file v2.3.47/linux/drivers/pci/pci.ids linux/drivers/pci/pci.ids
--- v2.3.47/linux/drivers/pci/pci.ids	Thu Feb 10 17:11:12 2000
+++ linux/drivers/pci/pci.ids	Sat Feb 26 20:32:14 2000
@@ -999,7 +999,7 @@
 10a7  Benchmarq Microelectronics
 10a8  Sierra Semiconductor
 	0000  STB Horizon 64
-10a9  Silicon Graphics
+10a9  Silicon Graphics, Inc.
 	0003  IOC3
 	0005  RAD Audio
 	0009  Alteon Gigabit Ethernet
@@ -2682,6 +2682,7 @@
 13c0  Microgate Corporation
 	0010  SyncLink WAN Adapter
 13c1  3ware Inc
+	1000  3ware ATA-RAID
 13c2  Technotrend Systemtechnik GmbH
 13c3  Janz Computer AG
 13c4  Phase Metrics
@@ -3424,6 +3425,7 @@
 	71a0  440GX - 82443GX Host bridge
 	71a1  440GX - 82443GX AGP bridge
 	71a2  440GX - 82443GX Host bridge (AGP disabled)
+	7601  82372FB PIIX4 IDE
 	7602  82372FB [PCI-to-USB UHCI]
 	7800  i740
 		1092 0100  Stealth II G460
diff -u --recursive --new-file v2.3.47/linux/drivers/pci/proc.c linux/drivers/pci/proc.c
--- v2.3.47/linux/drivers/pci/proc.c	Fri Jan 28 15:09:08 2000
+++ linux/drivers/pci/proc.c	Sat Feb 26 20:33:03 2000
@@ -197,10 +197,6 @@
 	write:	proc_bus_pci_write,
 };
 
-static struct inode_operations proc_bus_pci_inode_operations = {
-	&proc_bus_pci_operations, /* default base directory file-ops */
-};
-
 #if BITS_PER_LONG == 32
 #define LONG_FORMAT "\t%08lx"
 #else
@@ -265,7 +261,7 @@
 	e = dev->procent = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, de);
 	if (!e)
 		return -ENOMEM;
-	e->ops = &proc_bus_pci_inode_operations;
+	e->proc_fops = &proc_bus_pci_operations;
 	e->data = dev;
 	e->size = PCI_CFG_SPACE_SIZE;
 	return 0;
diff -u --recursive --new-file v2.3.47/linux/drivers/pcmcia/i82365.c linux/drivers/pcmcia/i82365.c
--- v2.3.47/linux/drivers/pcmcia/i82365.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/pcmcia/i82365.c	Mon Feb 21 21:30:55 2000
@@ -165,25 +165,6 @@
     u_char		ctl, ema;
 } vg46x_state_t;
 
-typedef struct ti113x_state_t {
-    u_int		sysctl;
-    u_char		cardctl, devctl, diag;
-} ti113x_state_t;
-
-typedef struct rl5c4xx_state_t {
-    u_short		misc, ctl, io, mem;
-} rl5c4xx_state_t;
-
-typedef struct o2micro_state_t {
-    u_char		mode_a, mode_b, mode_c, mode_d;
-    u_char		mhpg, fifo, mode_e;
-} o2micro_state_t;
-
-typedef struct topic_state_t {
-    u_char		slot, ccr, cdr;
-    u_int		rcr;
-} topic_state_t;
-
 typedef struct socket_info_t {
     u_short		type, flags;
     socket_cap_t	cap;
@@ -273,22 +254,6 @@
 };
 
 #define PCIC_COUNT	(sizeof(pcic)/sizeof(pcic_t))
-
-/*====================================================================*/
-
-/* Some PCI shortcuts */
-
-#define config_readb(sock, r, v)	pci_read_config_byte((sock)->pdev, r, v)
-#define config_readw(sock, r, v)	pci_read_config_word((sock)->pdev, r, v)
-#define config_readl(sock, r, v)	pci_read_config_dword((sock)->pdev, r, v)
-#define config_writeb(sock, r, v)	pci_write_config_byte((sock)->pdev, r, v)
-#define config_writew(sock, r, v)	pci_write_config_word((sock)->pdev, r, v)
-#define config_writel(sock, r, v)	pci_write_config_dword((sock)->pdev, r, v)
-
-#define cb_readb(s, r)		readb(socket[s].cb_virt + (r))
-#define cb_readl(s, r)		readl(socket[s].cb_virt + (r))
-#define cb_writeb(s, r, v)	writeb(v, socket[s].cb_virt + (r))
-#define cb_writel(s, r, v)	writel(v, socket[s].cb_virt + (r))
 
 /*====================================================================*/
 
diff -u --recursive --new-file v2.3.47/linux/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c
--- v2.3.47/linux/drivers/pcmcia/yenta.c	Thu Feb 10 17:11:12 2000
+++ linux/drivers/pcmcia/yenta.c	Wed Feb 23 08:49:46 2000
@@ -17,6 +17,12 @@
 #include "yenta.h"
 #include "i82365.h"
 
+#if 0
+#define DEBUG(x,args...)	printk(__FUNCTION__ ": " x,##args)
+#else
+#define DEBUG(x,args...)
+#endif
+
 /* Don't ask.. */
 #define to_cycles(ns)	((ns)/120)
 #define to_ns(cycles)	((cycles)*120)
@@ -26,13 +32,24 @@
  * regular memory space ("cb_xxx"), configuration space
  * ("config_xxx") and compatibility space ("exca_xxxx")
  */
-#define cb_readl(sock,reg)	readl((sock)->base + (reg))
-#define cb_writel(sock,reg,val) writel(val,(sock)->base + (reg))
+static inline u32 cb_readl(pci_socket_t *socket, unsigned reg)
+{
+	u32 val = readl(socket->base + reg);
+	DEBUG("%p %04x %08x\n", socket, reg, val);
+	return val;
+}
+
+static inline void cb_writel(pci_socket_t *socket, unsigned reg, u32 val)
+{
+	DEBUG("%p %04x %08x\n", socket, reg, val);
+	writel(val, socket->base + reg);
+}
 
 static inline u8 config_readb(pci_socket_t *socket, unsigned offset)
 {
 	u8 val;
 	pci_read_config_byte(socket->dev, offset, &val);
+	DEBUG("%p %04x %02x\n", socket, offset, val);
 	return val;
 }
 
@@ -40,6 +57,7 @@
 {
 	u16 val;
 	pci_read_config_word(socket->dev, offset, &val);
+	DEBUG("%p %04x %04x\n", socket, offset, val);
 	return val;
 }
 
@@ -47,25 +65,55 @@
 {
 	u32 val;
 	pci_read_config_dword(socket->dev, offset, &val);
+	DEBUG("%p %04x %08x\n", socket, offset, val);
 	return val;
 }
 
-#define config_writeb(s,off,val) pci_write_config_byte((s)->dev, (off), (val))
-#define config_writew(s,off,val) pci_write_config_word((s)->dev, (off), (val))
-#define config_writel(s,off,val) pci_write_config_dword((s)->dev, (off), (val))
+static inline void config_writeb(pci_socket_t *socket, unsigned offset, u8 val)
+{
+	DEBUG("%p %04x %02x\n", socket, offset, val);
+	pci_write_config_byte(socket->dev, offset, val);
+}
+
+static inline void config_writew(pci_socket_t *socket, unsigned offset, u16 val)
+{
+	DEBUG("%p %04x %04x\n", socket, offset, val);
+	pci_write_config_word(socket->dev, offset, val);
+}
 
-#define exca_readb(sock,reg)	readb((sock)->base + 0x800 + (reg))
-#define exca_writeb(sock,reg,v)	writeb((v), (sock)->base + 0x800 + (reg))
+static inline void config_writel(pci_socket_t *socket, unsigned offset, u32 val)
+{
+	DEBUG("%p %04x %08x\n", socket, offset, val);
+	pci_write_config_dword(socket->dev, offset, val);
+}
+
+static inline u8 exca_readb(pci_socket_t *socket, unsigned reg)
+{
+	u8 val = readb(socket->base + 0x800 + reg);
+	DEBUG("%p %04x %02x\n", socket, reg, val);
+	return val;
+}
+
+static inline u8 exca_readw(pci_socket_t *socket, unsigned reg)
+{
+	u16 val;
+	val = readb(socket->base + 0x800 + reg);
+	val |= readb(socket->base + 0x800 + reg + 1) << 8;
+	DEBUG("%p %04x %04x\n", socket, reg, val);
+	return val;
+}
 
-static u16 exca_readw(pci_socket_t *socket, unsigned reg)
+static inline void exca_writeb(pci_socket_t *socket, unsigned reg, u8 val)
 {
-	return exca_readb(socket, reg) | (exca_readb(socket, reg+1) << 8);
+	DEBUG("%p %04x %02x\n", socket, reg, val);
+	writeb(val, socket->base + 0x800 + reg);
 }
 
 static void exca_writew(pci_socket_t *socket, unsigned reg, u16 val)
 {
-	exca_writeb(socket, reg, val);
-	exca_writeb(socket, reg+1, val >> 8);
+	DEBUG("%p %04x %04x\n", socket, reg, val);
+	writeb(val, socket->base + 0x800 + reg);
+	writeb(val >> 8, socket->base + 0x800 + reg + 1);
 }
 
 /*
diff -u --recursive --new-file v2.3.47/linux/drivers/pnp/isapnp_proc.c linux/drivers/pnp/isapnp_proc.c
--- v2.3.47/linux/drivers/pnp/isapnp_proc.c	Thu Feb 10 17:11:12 2000
+++ linux/drivers/pnp/isapnp_proc.c	Sat Feb 26 20:33:03 2000
@@ -210,11 +210,6 @@
 	release:	isapnp_info_entry_release,
 };
 
-static struct inode_operations isapnp_info_entry_inode_operations =
-{
-	&isapnp_info_entry_operations,	/* default sound info directory file-ops */
-};
-
 static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence)
 {
 	loff_t new;
@@ -274,11 +269,6 @@
 	read:		isapnp_proc_bus_read,
 };
 
-static struct inode_operations isapnp_proc_bus_inode_operations =
-{
-	&isapnp_proc_bus_file_operations,
-};
-
 static int isapnp_proc_attach_device(struct pci_dev *dev)
 {
 	struct pci_bus *bus = dev->bus;
@@ -295,7 +285,7 @@
 	e = dev->procent = create_proc_entry(name, S_IFREG | S_IRUGO, de);
 	if (!e)
 		return -ENOMEM;
-	e->ops = &isapnp_proc_bus_inode_operations;
+	e->proc_fops = &isapnp_proc_bus_file_operations;
 	e->data = dev;
 	e->size = 256;
 	return 0;
@@ -378,7 +368,7 @@
 	isapnp_proc_entry = NULL;
 	p = create_proc_entry("isapnp", S_IFREG | S_IRUGO | S_IWUSR, &proc_root);
 	if (p)
-		p->ops = &isapnp_info_entry_inode_operations;
+		p->proc_fops = &isapnp_info_entry_operations;
 	isapnp_proc_entry = p;
 	isapnp_proc_bus_dir = proc_mkdir("isapnp", proc_bus);
 	isapnp_proc_devices_entry = create_proc_info_entry("devices", 0,
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/3w-xxxx.c linux/drivers/scsi/3w-xxxx.c
--- v2.3.47/linux/drivers/scsi/3w-xxxx.c	Fri Jan 28 15:09:08 2000
+++ linux/drivers/scsi/3w-xxxx.c	Sat Feb 26 20:32:15 2000
@@ -85,7 +85,7 @@
 static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
 
 /* Globals */
-char *tw_driver_version="0.4.001";
+char *tw_driver_version="1.0.000";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -2051,12 +2051,16 @@
 	command_packet->status = 0;
 	command_packet->flags = 0;
 
+	if ((srb->cmnd[0] == WRITE_6) || (srb->cmnd[0] == WRITE_10)) {
+		if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
+			command_packet->flags = 1;
+	}
+
 	if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
 		lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
 		num_sectors = (u32)srb->cmnd[4];
 	} else {
-		lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | 
-		       ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
+		lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
 		num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
 	}
   
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/ChangeLog.sym53c8xx linux/drivers/scsi/ChangeLog.sym53c8xx
--- v2.3.47/linux/drivers/scsi/ChangeLog.sym53c8xx	Tue Jan 11 22:31:41 2000
+++ linux/drivers/scsi/ChangeLog.sym53c8xx	Mon Feb 21 17:35:06 2000
@@ -1,3 +1,17 @@
+Sun Feb 20 11:00 2000 Gerard Roudier (groudier@club-internet.fr)
+	* version sym53c8xx-1.5j
+	- Add support for the new dynamic dma mapping kernel interface.
+	  Requires Linux-2.3.47 (tested with pre-2.3.47-6).
+	  Many thanks to David S. Miller for his preliminary changes 
+	  that have been useful guidelines, for having reviewed the 
+	  code and having tested this driver version on Ultra-Sparc.
+	- 2 tiny bugs fixed in the PCI wrapper that provides support 
+	  for early kernels without pci device structure.
+	- Get data transfer direction from the scsi command structure 
+	  (Scsi_Cmnd) with kernels that provide this information.
+	- Fix an old bug that only affected 896 rev. 1 when driver 
+	  profile support option was set in kernel configuration.
+
 Sat Jan 8  22:00 2000 Gerard Roudier (groudier@club-internet.fr)
 	* version sym53c8xx-1.5h
 	- Add year 2000 copyright.
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- v2.3.47/linux/drivers/scsi/Config.in	Wed Feb 16 17:03:52 2000
+++ linux/drivers/scsi/Config.in	Sat Feb 26 20:32:15 2000
@@ -34,6 +34,19 @@
 mainmenu_option next_comment
 comment 'SCSI low-level drivers'
 
+if [ "$CONFIG_SGI_IP22" = "y" ]; then
+   dep_tristate 'SGI WD93C93 SCSI Driver' CONFIG_SCSI_SGIWD93 $CONFIG_SCSI
+fi
+if [ "$CONFIG_DECSTATION" = "y" ]; then
+   if [ "$CONFIG_TC" = "y" ]; then
+      dep_tristate 'DEC NCR53C94 Scsi Driver' CONFIG_SCSI_DECNCR $CONFIG_SCSI
+   fi
+   dep_tristate 'DEC SII Scsi Driver' CONFIG_SCSI_DECSII $CONFIG_SCSI
+fi
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   dep_tristate '3ware Hardware ATA-RAID support (EXPERIMENTAL)' CONFIG_BLK_DEV_3W_XXXX_RAID $CONFIG_SCSI
+fi
 dep_tristate '7000FASST SCSI support' CONFIG_SCSI_7000FASST $CONFIG_SCSI
 dep_tristate 'ACARD SCSI support' CONFIG_SCSI_ACARD $CONFIG_SCSI
 dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
@@ -177,9 +190,6 @@
 fi
 if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then
    bool 'MIPS JAZZ FAS216 SCSI support' CONFIG_JAZZ_ESP
-fi
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   dep_tristate '3Ware Hardware ATA-RAID support (EXPERIMENTAL)' CONFIG_BLK_DEV_3W_XXXX_RAID $CONFIG_SCSI
 fi
 
 endmenu
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- v2.3.47/linux/drivers/scsi/Makefile	Wed Feb 16 17:03:52 2000
+++ linux/drivers/scsi/Makefile	Thu Feb 24 22:51:47 2000
@@ -689,6 +689,10 @@
 L_OBJS += NCR53C9x.o jazz_esp.o
 endif
 
+ifeq ($(CONFIG_SCSI_DECNCR),y)
+L_OBJS += NCR53C9x.o dec_esp.o
+endif
+
 ifeq ($(CONFIG_SUN3X_ESP),y)
 L_OBJS += NCR53C9x.o sun3x_esp.o
 endif
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/dec_esp.c linux/drivers/scsi/dec_esp.c
--- v2.3.47/linux/drivers/scsi/dec_esp.c	Fri Oct 15 15:25:14 1999
+++ linux/drivers/scsi/dec_esp.c	Thu Feb 24 22:51:47 2000
@@ -1,7 +1,9 @@
 /*
  * dec_esp.c: Driver for SCSI chips on IOASIC based TURBOchannel DECstations
+ *            and TURBOchannel PMAZ-A cards
  *
  * TURBOchannel changes by Harald Koerfgen
+ * PMAZ-A support by David Airlie
  *
  * based on jazz_esp.c:
  * Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
@@ -38,21 +40,43 @@
 
 static int  dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
 static void dma_drain(struct NCR_ESP *esp);
+static void pmaz_dma_drain(struct NCR_ESP *esp);
 static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd * sp);
 static void dma_dump_state(struct NCR_ESP *esp);
 static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
 static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
 static void dma_ints_off(struct NCR_ESP *esp);
 static void dma_ints_on(struct NCR_ESP *esp);
+static void pmaz_dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
+static void pmaz_dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
+static void pmaz_dma_ints_off(struct NCR_ESP *esp);
+static void pmaz_dma_ints_on(struct NCR_ESP *esp);
 static int  dma_irq_p(struct NCR_ESP *esp);
 static int  dma_ports_p(struct NCR_ESP *esp);
 static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
 static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp);
 static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp);
+static void pmaz_dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
+static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp);
+// static void pmaz_dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp);
 static void dma_advance_sg(Scsi_Cmnd * sp);
 
+#define TC_ESP_RAM_SIZE 0x20000
+#define ESP_TGT_DMA_SIZE ((TC_ESP_RAM_SIZE/7) & ~(sizeof(int)-1))
+#define ESP_NCMD 7
+
+#define TC_ESP_DMAR_MASK  0x1ffff
+#define TC_ESP_DMAR_WRITE 0x80000000
+#define TC_ESP_DMA_ADDR(x) ((unsigned)(x) & TC_ESP_DMAR_MASK)
+
+volatile unsigned char *scsi_pmaz_dma_ptrs_tc[ESP_NCMD];
+unsigned char scsi_pmaz_dma_buff_used[ESP_NCMD];
+unsigned char scsi_cur_buff = 1;	/* Leave space for command buffer */
+__u32 esp_virt_buffer;
+int scsi_current_length = 0;
 
 volatile unsigned char cmd_buffer[16];
+volatile unsigned char pmaz_cmd_buffer[16];
 				/* This is where all commands are put
 				 * before they are trasfered to the ESP chip
 				 * via PIO.
@@ -65,6 +89,8 @@
 volatile unsigned long *scsi_sdr0;
 volatile unsigned long *scsi_sdr1;
 
+volatile int *scsi_pmaz_dma_ptr_tc;
+
 static void scsi_dma_int(int, void *, struct pt_regs *);
 
 /***************************************************************** Detection */
@@ -72,6 +98,9 @@
 {
     struct NCR_ESP *esp;
     struct ConfigDev *esp_dev;
+	int slot, i;
+	unsigned long mem_start;
+	volatile unsigned char *buffer;
 
 	if (IOASIC) {
 	esp_dev = 0;
@@ -143,21 +172,88 @@
 		request_irq(SCSI_DMA_INT, scsi_dma_int, SA_INTERRUPT, "JUNKIO SCSI DMA",
 			    NULL);
 
-	/*
-	 * FIXME, look if the scsi id is availabe from NVRAM
-	 */
 	esp->scsi_id = 7;
 		
 	/* Check for differential SCSI-bus */
-	/* What is this stuff? */
 	esp->diff = 0;
 
 	esp_initialize(esp);
 	
+	}
+
+	if (TURBOCHANNEL) {
+		while ((slot = search_tc_card("PMAZ-AA")) >= 0) {
+			claim_tc_card(slot);
+			mem_start = get_tc_base_addr(slot);
+
+			esp_dev = 0;
+			esp = esp_allocate(tpnt, (void *) esp_dev);
+
+			esp->dregs = 0;
+			esp->eregs = (struct ESP_regs *) (mem_start + DEC_SCSI_SREG);
+			esp->do_pio_cmds = 1;
+
+			/* Set the command buffer */
+			esp->esp_command = (volatile unsigned char *) pmaz_cmd_buffer;
+
+			/* get virtual dma address for command buffer */
+			esp->esp_command_dvma = (__u32) KSEG0ADDR((volatile unsigned char *) pmaz_cmd_buffer);
+
+			buffer = (volatile unsigned char *) (mem_start + DEC_SCSI_SRAM);
+
+			scsi_pmaz_dma_ptr_tc = (volatile int *) (mem_start + DEC_SCSI_DMAREG);
+
+			for (i = 0; i < ESP_NCMD; i++) {
+				scsi_pmaz_dma_ptrs_tc[i] = (volatile unsigned char *) (buffer + ESP_TGT_DMA_SIZE * i);
+			}
+
+			scsi_pmaz_dma_buff_used[0] = 1;
+
+			esp->cfreq = get_tc_speed();
+
+			esp->irq = get_tc_irq_nr(slot);
+
+			/* Required functions */
+			esp->dma_bytes_sent = &dma_bytes_sent;
+			esp->dma_can_transfer = &dma_can_transfer;
+			esp->dma_dump_state = &dma_dump_state;
+			esp->dma_init_read = &pmaz_dma_init_read;
+			esp->dma_init_write = &pmaz_dma_init_write;
+			esp->dma_ints_off = &pmaz_dma_ints_off;
+			esp->dma_ints_on = &pmaz_dma_ints_on;
+			esp->dma_irq_p = &dma_irq_p;
+			esp->dma_ports_p = &dma_ports_p;
+			esp->dma_setup = &pmaz_dma_setup;
+
+			/* Optional functions */
+			esp->dma_barrier = 0;
+			esp->dma_drain = &pmaz_dma_drain;
+			esp->dma_invalidate = 0;
+			esp->dma_irq_entry = 0;
+			esp->dma_irq_exit = 0;
+			esp->dma_poll = 0;
+			esp->dma_reset = 0;
+			esp->dma_led_off = 0;
+			esp->dma_led_on = 0;
+
+			esp->dma_mmu_get_scsi_one = pmaz_dma_mmu_get_scsi_one;
+			esp->dma_mmu_get_scsi_sgl = 0;
+			esp->dma_mmu_release_scsi_one = 0;
+			esp->dma_mmu_release_scsi_sgl = 0;
+			esp->dma_advance_sg = 0;
+
+			request_irq(esp->irq, esp_intr, SA_INTERRUPT, "PMAZ-AA", NULL);
+			esp->scsi_id = 7;
+			esp->diff = 0;
+			esp_initialize(esp);
+		}
+	}
+
+	if(nesps) {
 		printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
 	esps_running = esps_in_use;
 	return esps_in_use;
-    }
+	} else
     return 0;
 }
 
@@ -172,18 +268,18 @@
 		*scsi_next_ptr = ((*scsi_dma_ptr + PAGE_SIZE) & PAGE_MASK) << 3;
 		*isr &= ~SCSI_PTR_LOADED;
 	} else {
-		printk("Got unexpected SCSI DMA Interrupt! < ");
 		if (*isr & SCSI_PAGOVRRUN)
-			printk("SCSI_PAGOVRRUN ");
-		if (*isr & SCSI_DMA_MEMRDERR)
+			*isr &= ~SCSI_PAGOVRRUN;
+		if (*isr & SCSI_DMA_MEMRDERR) {
+			printk("Got unexpected SCSI DMA Interrupt! < ");
 			printk("SCSI_DMA_MEMRDERR ");
 		printk(">\n");
-//		panic("stop");
-		*isr &= ~(SCSI_PAGOVRRUN || SCSI_DMA_MEMRDERR);
+			*isr &= ~SCSI_DMA_MEMRDERR;
+		}
 	}
 
 	/*
-	 * This driver will only work on IOASIC machines
+	 * This routine will only work on IOASIC machines
 	 * so we can avoid an indirect function call here
 	 * and flush the writeback buffer the fast way
 	 */
@@ -198,13 +294,13 @@
 
 static void dma_drain(struct NCR_ESP *esp)
 {
-	unsigned long nw;
+	unsigned long nw = *scsi_scr;
 	unsigned short *p = KSEG1ADDR((unsigned short *) ((*scsi_dma_ptr) >> 3));
 
     /*
 	 * Is there something in the dma buffers left?
      */
-	if (nw = *scsi_scr) {
+	if (nw) {
 		switch (nw) {
 		case 1:
 			*p = (unsigned short) *scsi_sdr0;
@@ -225,6 +321,12 @@
 	}
 }
 
+static void pmaz_dma_drain(struct NCR_ESP *esp)
+{
+	memcpy((volatile void *) (KSEG0ADDR(esp_virt_buffer)),
+		(void *) scsi_pmaz_dma_ptrs_tc[scsi_cur_buff], scsi_current_length);
+}
+
 static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd * sp)
 {
 	return sp->SCp.this_residual;;
@@ -298,6 +400,33 @@
 	enable_irq(SCSI_DMA_INT);
 }
 
+static void pmaz_dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
+{
+
+	if (length > ESP_TGT_DMA_SIZE)
+		length = ESP_TGT_DMA_SIZE;
+
+	*scsi_pmaz_dma_ptr_tc = TC_ESP_DMA_ADDR(scsi_pmaz_dma_ptrs_tc[scsi_cur_buff]);
+	esp_virt_buffer = vaddress;
+	scsi_current_length = length;
+}
+
+static void pmaz_dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
+{
+	memcpy(scsi_pmaz_dma_ptrs_tc[scsi_cur_buff], KSEG0ADDR((void *) vaddress), length);
+
+	*scsi_pmaz_dma_ptr_tc = TC_ESP_DMAR_WRITE | TC_ESP_DMA_ADDR(scsi_pmaz_dma_ptrs_tc[scsi_cur_buff]);
+
+}
+
+static void pmaz_dma_ints_off(struct NCR_ESP *esp)
+{
+}
+
+static void pmaz_dma_ints_on(struct NCR_ESP *esp)
+{
+}
+
 static int dma_irq_p(struct NCR_ESP *esp)
 {
     return (esp->eregs->esp_status & ESP_STAT_INTR);
@@ -322,6 +451,34 @@
     } else {
 	dma_init_write(esp, addr, count);
     }
+}
+
+static void pmaz_dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
+{
+	/* 
+	 * On the Sparc, DMA_ST_WRITE means "move data from device to memory"
+	 * so when (write) is true, it actually means READ!
+	 */
+	if (write) {
+		pmaz_dma_init_read(esp, addr, count);
+	} else {
+		pmaz_dma_init_write(esp, addr, count);
+	}
+}
+
+static void pmaz_dma_mmu_release_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp)
+{
+	int x;
+	for (x = 1; x < 6; x++)
+		if (sp->SCp.have_data_in == PHYSADDR(scsi_pmaz_dma_ptrs_tc[x]))
+			scsi_pmaz_dma_buff_used[x] = 0;
+}
+
+
+static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp)
+{
+	sp->SCp.have_data_in = (int) sp->SCp.ptr =
+	    (char *) KSEG0ADDR((sp->request_buffer));
 }
 
 /*
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/dec_esp.h linux/drivers/scsi/dec_esp.h
--- v2.3.47/linux/drivers/scsi/dec_esp.h	Thu Nov 11 20:11:46 1999
+++ linux/drivers/scsi/dec_esp.h	Thu Feb 24 22:51:47 2000
@@ -1,6 +1,7 @@
 /* dec_esp.h: Defines and structures for the JAZZ SCSI driver.
  *
  * DECstation changes Copyright (C) 1998 Harald Koerfgen
+ * and David Airlie
  *
  * based on jazz_esp.h:
  * Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
@@ -9,10 +10,12 @@
 #ifndef DEC_ESP_H
 #define DEC_ESP_H
 
-#define EREGS_PAD(n)     unchar n[3];
-
 #include "NCR53C9x.h"
 
+#define DEC_SCSI_SREG 0
+#define DEC_SCSI_DMAREG 0x40000
+#define DEC_SCSI_SRAM 0x80000
+#define DEC_SCSI_DIAG 0xC0000
 
 extern int dec_esp_detect(struct SHT *);
 extern const char *esp_info(struct Scsi_Host *);
@@ -26,7 +29,7 @@
 #define SCSI_DEC_ESP {                                         \
 		proc_name:      "esp",				\
 		proc_info:      &esp_proc_info,			\
-		name:           "PMAZ-AA",			\
+		name:           "NCR53C94",			\
 		detect:         dec_esp_detect,			\
 		info:           esp_info,			\
 		command:        esp_command,			\
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/eata_dma_proc.c linux/drivers/scsi/eata_dma_proc.c
--- v2.3.47/linux/drivers/scsi/eata_dma_proc.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/scsi/eata_dma_proc.c	Fri Feb 25 10:32:09 2000
@@ -167,7 +167,7 @@
 	cmnd[9] = 0;
 
 	scmd->cmd_len = 10;
-	scmd->sc_data_direction = DATA_READ;
+	scmd->sc_data_direction = SCSI_DATA_READ;
 	
 	/*
 	 * Do the command and wait for it to finish.
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c
--- v2.3.47/linux/drivers/scsi/hosts.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/scsi/hosts.c	Thu Feb 24 22:51:47 2000
@@ -345,6 +345,10 @@
 #include "jazz_esp.h"
 #endif
 
+#ifdef CONFIG_SCSI_DECNCR
+#include "dec_esp.h"
+#endif
+
 #ifdef CONFIG_SUN3X_ESP
 #include "sun3x_esp.h"
 #endif
@@ -638,10 +642,12 @@
 #ifdef CONFIG_IPHASE5526
 	IPH5526_SCSI_FC,
 #endif
+#ifdef CONFIG_SCSI_DECNCR	
+    SCSI_DEC_ESP,
+#endif
 #ifdef CONFIG_BLK_DEV_3W_XXXX_RAID
 	TWXXXX,
 #endif
-
 /* "Removable host adapters" below this line (Parallel Port/USB/other) */
 #ifdef CONFIG_SCSI_PPA
     PPA,
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/jazz_esp.c linux/drivers/scsi/jazz_esp.c
--- v2.3.47/linux/drivers/scsi/jazz_esp.c	Wed Aug 18 10:00:52 1999
+++ linux/drivers/scsi/jazz_esp.c	Thu Feb 24 22:51:47 2000
@@ -1,7 +1,7 @@
 /*
  * jazz_esp.c: Driver for SCSI chip on Mips Magnum Boards (JAZZ architecture)
  *
- * Copyright (C) 1997 Thomas Boegndoerfer (tsbogend@alpha.franken.de)
+ * Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
  *
  * jazz_esp is based on David S. Miller's ESP driver and cyber_esp
  */
@@ -161,7 +161,7 @@
 {
     
     ESPLOG(("esp%d: dma -- enable <%08x> residue <%08x\n",
-	    esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_resdiue((int)esp->dregs)));
+	    esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_residue((int)esp->dregs)));
 }
 
 static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/jazz_esp.h linux/drivers/scsi/jazz_esp.h
--- v2.3.47/linux/drivers/scsi/jazz_esp.h	Thu Nov 11 20:11:47 1999
+++ linux/drivers/scsi/jazz_esp.h	Thu Feb 24 22:51:47 2000
@@ -37,4 +37,3 @@
 		use_clustering: DISABLE_CLUSTERING, }
 
 #endif /* JAZZ_ESP_H */
-
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/pci2000.c linux/drivers/scsi/pci2000.c
--- v2.3.47/linux/drivers/scsi/pci2000.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/scsi/pci2000.c	Sat Feb 26 20:33:03 2000
@@ -60,9 +60,6 @@
 #include <linux/bios32.h>
 #endif
 
-struct proc_dir_entry Proc_Scsi_Pci2000 =
-	{ PROC_SCSI_PCI2000, 7, "pci2000", S_IFDIR | S_IRUGO | S_IXUGO, 2 };
-
 //#define DEBUG 1
 
 #ifdef DEBUG
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/pci2000.h linux/drivers/scsi/pci2000.h
--- v2.3.47/linux/drivers/scsi/pci2000.h	Sun Feb 20 21:12:39 2000
+++ linux/drivers/scsi/pci2000.h	Sat Feb 26 20:48:05 2000
@@ -200,59 +200,25 @@
 	#define NULL 0
 #endif
 
-extern struct proc_dir_entry Proc_Scsi_Pci2000;
-
-#if LINUX_VERSION_CODE >= LINUXVERSION(2,1,75)
-#define PCI2000 {																\
-		next:						NULL,										\
-		module:						NULL,										\
-		proc_dir:					&Proc_Scsi_Pci2000,							\
-		proc_info:					NULL,	/* let's not bloat the kernel */	\
-		name:						"PCI-2000 SCSI Intelligent Disk Controller",\
-		detect:						Pci2000_Detect,								\
-		release:					Pci2000_Release,							\
-		info:						NULL,	/* let's not bloat the kernel */	\
-		command:					Pci2000_Command,							\
-		queuecommand:				Pci2000_QueueCommand,						\
-		eh_strategy_handler:		NULL,										\
-		eh_abort_handler:			NULL,										\
-		eh_device_reset_handler:	NULL,										\
-		eh_bus_reset_handler:		NULL,										\
-		eh_host_reset_handler:		NULL,										\
-		abort:						Pci2000_Abort,								\
-		reset:						Pci2000_Reset,								\
-		slave_attach:				NULL,										\
-		bios_param:					Pci2000_BiosParam,							\
-		can_queue:					16,											\
-		this_id:					-1,											\
-		sg_tablesize:				16,											\
-		cmd_per_lun:				1,											\
-		present:					0,											\
-		unchecked_isa_dma:			0,											\
-		use_clustering:				DISABLE_CLUSTERING,							\
-		use_new_eh_code:			0											\
-		}
-#else
-#define PCI2000 { NULL, NULL,							\
-			&Proc_Scsi_Pci2000,/* proc_dir_entry */		\
-			NULL,		                				\
-			"PCI-2000 SCSI Intelligent Disk Controller",\
-			Pci2000_Detect,								\
-			Pci2000_Release,							\
-			NULL,	 									\
-			Pci2000_Command,							\
-			Pci2000_QueueCommand,						\
-			Pci2000_Abort,								\
-			Pci2000_Reset,								\
-			NULL,										\
-			Pci2000_BiosParam,                 			\
-			16, 										\
-			-1, 										\
-			16,		 									\
-			1, 											\
-			0, 											\
-			0, 											\
-			DISABLE_CLUSTERING }
-#endif
+/* screen is 80 columns wide, damnit! */
+#define PCI2000 {				\
+	proc_name:	"pci2000",					\
+	name:		"PCI-2000 SCSI Intelligent Disk Controller",	\
+	detect:		Pci2000_Detect,					\
+	release:	Pci2000_Release,				\
+	command:	Pci2000_Command,				\
+	queuecommand:	Pci2000_QueueCommand,				\
+	abort:		Pci2000_Abort,					\
+	reset:		Pci2000_Reset,					\
+	bios_param:	Pci2000_BiosParam,				\
+	can_queue:	16,						\
+	this_id:	-1,						\
+	sg_tablesize:	16,						\
+	cmd_per_lun:	1,						\
+	present:	0,						\
+	unchecked_isa_dma:0,						\
+	use_clustering:	DISABLE_CLUSTERING,				\
+	use_new_eh_code:0						\
+}
 
 #endif
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/pci2220i.c linux/drivers/scsi/pci2220i.c
--- v2.3.47/linux/drivers/scsi/pci2220i.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/scsi/pci2220i.c	Sat Feb 26 20:33:03 2000
@@ -67,9 +67,6 @@
 #define	WRITE_CMD				IDE_CMD_WRITE_MULTIPLE
 #define	MAX_BUS_MASTER_BLOCKS	SECTORSXFER		// This is the maximum we can bus master
 
-struct proc_dir_entry Proc_Scsi_Pci2220i =
-	{ PROC_SCSI_PCI2220I, 8, "pci2220i", S_IFDIR | S_IRUGO | S_IXUGO, 2 };
-
 #ifdef DEBUG
 #define DEB(x) x
 #define STOP_HERE()	{int st;for(st=0;st<100;st++){st=1;}}
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/pci2220i.h linux/drivers/scsi/pci2220i.h
--- v2.3.47/linux/drivers/scsi/pci2220i.h	Sun Feb 20 21:12:39 2000
+++ linux/drivers/scsi/pci2220i.h	Sat Feb 26 20:48:07 2000
@@ -39,59 +39,23 @@
 	#define NULL 0
 #endif
 
-extern struct proc_dir_entry Proc_Scsi_Pci2220i;
-
-#if LINUX_VERSION_CODE >= LINUXVERSION(2,1,75)
-#define PCI2220I {															\
-		next:						NULL,									\
-		module:						NULL,									\
-		proc_dir:					&Proc_Scsi_Pci2220i,					\
-		proc_info:					NULL,	/* let's not bloat the kernel */\
-		name:						"PCI-2220I/PCI-2240I",					\
-		detect:						Pci2220i_Detect,						\
-		release:					Pci2220i_Release,						\
-		info:						NULL,	/* let's not bloat the kernel */\
-		command:					Pci2220i_Command,						\
-		queuecommand:				Pci2220i_QueueCommand,					\
-		eh_strategy_handler:		NULL,									\
-		eh_abort_handler:			NULL,									\
-		eh_device_reset_handler:	NULL,									\
-		eh_bus_reset_handler:		NULL,									\
-		eh_host_reset_handler:		NULL,									\
-		abort:						Pci2220i_Abort,							\
-		reset:						Pci2220i_Reset,							\
-		slave_attach:				NULL,									\
-		bios_param:					Pci2220i_BiosParam,						\
-		can_queue:					1,										\
-		this_id:					-1,										\
-		sg_tablesize:				SG_ALL,								\
-		cmd_per_lun:				1,										\
-		present:					0,										\
-		unchecked_isa_dma:			0,										\
-		use_clustering:				DISABLE_CLUSTERING,						\
-		use_new_eh_code:			0										\
-		}
-#else
-#define PCI2220I { NULL, NULL,						\
-			&Proc_Scsi_Pci2220i,/* proc_dir_entry */\
-			NULL,		                			\
-			"PCI-2220I/PCI-2240I",					\
-			Pci2220i_Detect,						\
-			Pci2220i_Release,						\
-			NULL,	 								\
-			Pci2220i_Command,						\
-			Pci2220i_QueueCommand,					\
-			Pci2220i_Abort,							\
-			Pci2220i_Reset,							\
-			NULL,									\
-			Pci2220i_BiosParam,                 	\
-			1, 										\
-			-1, 									\
-			SG_ALL,		 						\
-			1, 										\
-			0, 										\
-			0, 										\
-			DISABLE_CLUSTERING }
-#endif
-
+#define PCI2220I {					\
+	proc_name:		"pci2220i",		\
+	name:			"PCI-2220I/PCI-2240I",	\
+	detect:			Pci2220i_Detect,	\
+	release:		Pci2220i_Release,	\
+	command:		Pci2220i_Command,	\
+	queuecommand:		Pci2220i_QueueCommand,	\
+	abort:			Pci2220i_Abort,		\
+	reset:			Pci2220i_Reset,		\
+	bios_param:		Pci2220i_BiosParam,	\
+	can_queue:		1,			\
+	this_id:		-1,			\
+	sg_tablesize:		SG_ALL,			\
+	cmd_per_lun:		1,			\
+	present:		0,			\
+	unchecked_isa_dma:	0,			\
+	use_clustering:		DISABLE_CLUSTERING,	\
+	use_new_eh_code:	0			\
+}
 #endif
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/qla1280.c linux/drivers/scsi/qla1280.c
--- v2.3.47/linux/drivers/scsi/qla1280.c	Sun Feb 13 19:29:04 2000
+++ linux/drivers/scsi/qla1280.c	Sat Feb 26 20:33:03 2000
@@ -426,25 +426,6 @@
 
 #endif
 
-
-/*
- * Our directory Entry in /proc/scsi for the user to 
- * access the driver. 
- */
-
-#if 0
-
-/* Need to add in proc_fs.h     PROC_SCSI_QL1280 */
-#define PROC_SCSI_QL1280  PROC_SCSI_QLOGICISP
-
-struct proc_dir_entry proc_scsi_qla1280 = {
-    PROC_SCSI_QL1280, 7, "qla1280",                           
-    S_IFDIR | S_IRUGO | S_IXUGO, 2,
-    0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-
-#endif
-
 /* We use the Scsi_Pointer structure that's included with each command
  * SCSI_Cmnd as a scratchpad for our SRB.
  *
@@ -2749,13 +2730,13 @@
     long         risc_code_size;
     uint16_t     mb[MAILBOX_REGISTER_COUNT];
 #ifdef QLA1280_UNUSED
+    uint8_t	*sp;
     int i;
 #endif
     uint16_t     cnt;
     int          num;
-    uint8_t    *tbuf, *sp;
+    uint8_t    *tbuf;
     u_long     p_tbuf;
-    int i;
 
 #ifdef QL_DEBUG_LEVEL_3
     ENTER("qla1280_setup_chip");
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c
--- v2.3.47/linux/drivers/scsi/qlogicfc.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/scsi/qlogicfc.c	Wed Feb 23 13:37:35 2000
@@ -18,6 +18,9 @@
 
 /* This is a version of the isp1020 driver which was modified by
  * Chris Loveland <cwl@iol.unh.edu> to support the isp2100 and isp2200
+ *
+ * Big endian support and dynamic DMA mapping added
+ * by Jakub Jelinek <jakub@redhat.com>.
  */
 
 /*
@@ -59,6 +62,24 @@
 
 #include "sd.h"
 #include "hosts.h"
+
+#if 1
+/* Once pci64_ DMA mapping interface is in, kill this. */
+typedef dma_addr_t dma64_addr_t;
+#define pci64_alloc_consistent(d,s,p) pci_alloc_consistent((d),(s),(p))
+#define pci64_free_consistent(d,s,c,a) pci_free_consistent((d),(s),(c),(a))
+#define pci64_map_single(d,c,s,dir) pci_map_single((d),(c),(s),(dir))
+#define pci64_map_sg(d,s,n,dir) pci_map_sg((d),(s),(n),(dir))
+#define pci64_unmap_single(d,a,s,dir) pci_unmap_single((d),(a),(s),(dir))
+#define pci64_unmap_sg(d,s,n,dir) pci_unmap_sg((d),(s),(n),(dir))
+#define pci64_dma_hi32(a) 0
+#define pci64_dma_lo32(a) (a)
+#define pci64_dma_build(hi,lo) (lo)
+#define sg_dma64_address(s) sg_dma_address(s)
+#define sg_dma64_len(s) sg_dma_len(s)
+#define PCI64_DMA_BITS	32
+#endif
+
 #include "qlogicfc.h"
 
 /* Configuration section **************************************************** */
@@ -157,18 +178,6 @@
 #endif				/* DEBUG ISP2x00_INTR */
 
 
-#if BITS_PER_LONG > 32
-#define virt_to_bus_low32(x)   ((u32) (0xffffffff & virt_to_bus(x)))
-#define virt_to_bus_high32(x)  ((u32) (0xffffffff & (virt_to_bus(x)>>32)))
-#define bus_to_virt_low32(x)   ((u32) (0xffffffff & bus_to_virt(x)))
-#define bus_to_virt_high32(x)  ((u32) (0xffffffff & (bus_to_virt(x)>>32)))
-#else
-#define virt_to_bus_low32(x)   virt_to_bus(x)
-#define virt_to_bus_high32(x)  0x0
-#define bus_to_virt_low32(x)   bus_to_virt(x)
-#define bus_to_virt_high32(x)  0x0
-#endif
-
 #define ISP2100_REV_ID1	       1
 #define ISP2100_REV_ID3        3
 #define ISP2200_REV_ID5        5
@@ -230,7 +239,7 @@
 };
 
 /* entry header type commands */
-#if BITS_PER_LONG > 32
+#if PCI64_DMA_BITS > 32
 #define ENTRY_COMMAND		0x19
 #define ENTRY_CONTINUATION	0x0a
 #else
@@ -247,34 +256,23 @@
 #define EFLAG_BAD_HEADER	4
 #define EFLAG_BAD_PAYLOAD	8
 
-#if BITS_PER_LONG > 32
+#if PCI64_DMA_BITS > 32
+
 struct dataseg {
 	u_int d_base;
 	u_int d_base_hi;
 	u_int d_count;
 };
 
-struct Command_Entry {
-	struct Entry_header hdr;
-	u_int handle;
-	u_char target_lun;
-	u_char target_id;
-	u_short expanded_lun;
-	u_short control_flags;
-	u_short rsvd2;
-	u_short time_out;
-	u_short segment_cnt;
-	u_char cdb[16];
-	u_int total_byte_cnt;
-	struct dataseg dataseg[DATASEGS_PER_COMMAND];
-};
-
 #else
+
 struct dataseg {
 	u_int d_base;
 	u_int d_count;
 };
 
+#endif
+
 struct Command_Entry {
 	struct Entry_header hdr;
 	u_int handle;
@@ -290,9 +288,6 @@
 	struct dataseg dataseg[DATASEGS_PER_COMMAND];
 };
 
-#endif
-
-
 /* command entry control flag definitions */
 #define CFLAG_NODISC		0x01
 #define CFLAG_HEAD_TAG		0x02
@@ -302,7 +297,7 @@
 #define CFLAG_READ		0x20
 #define CFLAG_WRITE		0x40
 
-#if BITS_PER_LONG > 32
+#if PCI64_DMA_BITS > 32
 struct Continuation_Entry {
 	struct Entry_header hdr;
 	struct dataseg dataseg[DATASEGS_PER_CONT];
@@ -650,6 +645,9 @@
 #define AS_REDO_FABRIC_PORTDB  2
 #define AS_REDO_LOOP_PORTDB    4
 
+#define RES_SIZE	((RES_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN)
+#define REQ_SIZE	((QLOGICFC_REQ_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN)
+
 struct isp2x00_hostdata {
 	u_char revision;
 	struct pci_dev *pci_dev;
@@ -730,6 +728,7 @@
 	struct isp2x00_hostdata *hostdata;
 	struct pci_dev *pdev = NULL;
 	unsigned short device_ids[2];
+	dma64_addr_t busaddr;
 	int i;
 
 
@@ -756,50 +755,43 @@
 
 			memset(hostdata, 0, sizeof(struct isp2x00_hostdata));
 			hostdata->pci_dev = pdev;
-			hostdata->res = (char *) kmalloc((RES_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN, GFP_KERNEL);
+			hostdata->res = pci64_alloc_consistent(pdev, RES_SIZE + REQ_SIZE, &busaddr);
+
 			if (!hostdata->res){
-			        printk("qlogicfc%d : could not allocate memory for response queue.\n", hostdata->host_id);
+			        printk("qlogicfc%d : could not allocate memory for request and response queue.\n", hostdata->host_id);
 			        scsi_unregister(host);
 				continue;
 			}
-			hostdata->req = (char *) kmalloc((QLOGICFC_REQ_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN, GFP_KERNEL);
-			if (!hostdata->req){
-			        printk("qlogicfc%d : could not allocate memory for request queue.\n", hostdata->host_id);
-			        kfree(hostdata->res);
-			        scsi_unregister(host);
-				continue;
-			}
-
+			hostdata->req = hostdata->res + (RES_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN;
 			hostdata->queued = 0;
 			/* set up the control block */
 			hostdata->control_block.version = 0x1;
-			hostdata->control_block.firm_opts = 0x800e;
-			hostdata->control_block.max_frame_len = 2048;
-			hostdata->control_block.max_iocb = QLOGICFC_REQ_QUEUE_LEN;
-			hostdata->control_block.exec_throttle = QLOGICFC_CMD_PER_LUN;
+			hostdata->control_block.firm_opts = cpu_to_le16(0x800e);
+			hostdata->control_block.max_frame_len = cpu_to_le16(2048);
+			hostdata->control_block.max_iocb = cpu_to_le16(QLOGICFC_REQ_QUEUE_LEN);
+			hostdata->control_block.exec_throttle = cpu_to_le16(QLOGICFC_CMD_PER_LUN);
 			hostdata->control_block.retry_delay = 5;
 			hostdata->control_block.retry_cnt = 1;
-			hostdata->control_block.node_name[0] = 0x0020;
-			hostdata->control_block.node_name[1] = 0xE000;
-			hostdata->control_block.node_name[2] = 0x008B;
-			hostdata->control_block.node_name[3] = 0x0000;
-			hostdata->control_block.hard_addr = 0x0003;
-			hostdata->control_block.req_queue_len = QLOGICFC_REQ_QUEUE_LEN + 1;
-			hostdata->control_block.res_queue_len = RES_QUEUE_LEN + 1;
-			hostdata->control_block.res_queue_addr_lo = virt_to_bus_low32(hostdata->res);
-			hostdata->control_block.res_queue_addr_high = virt_to_bus_high32(hostdata->res);
-			hostdata->control_block.req_queue_addr_lo = virt_to_bus_low32(hostdata->req);
-			hostdata->control_block.req_queue_addr_high = virt_to_bus_high32(hostdata->req);
+			hostdata->control_block.node_name[0] = cpu_to_le16(0x0020);
+			hostdata->control_block.node_name[1] = cpu_to_le16(0xE000);
+			hostdata->control_block.node_name[2] = cpu_to_le16(0x008B);
+			hostdata->control_block.node_name[3] = cpu_to_le16(0x0000);
+			hostdata->control_block.hard_addr = cpu_to_le16(0x0003);
+			hostdata->control_block.req_queue_len = cpu_to_le16(QLOGICFC_REQ_QUEUE_LEN + 1);
+			hostdata->control_block.res_queue_len = cpu_to_le16(RES_QUEUE_LEN + 1);
+			hostdata->control_block.res_queue_addr_lo = cpu_to_le32(pci64_dma_lo32(busaddr));
+			hostdata->control_block.res_queue_addr_high = cpu_to_le32(pci64_dma_hi32(busaddr));
+			hostdata->control_block.req_queue_addr_lo = cpu_to_le32(pci64_dma_lo32(busaddr + RES_SIZE));
+			hostdata->control_block.req_queue_addr_high = cpu_to_le32(pci64_dma_hi32(busaddr + RES_SIZE));
 
 
-			hostdata->control_block.add_firm_opts |= CONNECTION_PREFERENCE<<4;
+			hostdata->control_block.add_firm_opts |= cpu_to_le16(CONNECTION_PREFERENCE<<4);
 			hostdata->adapter_state = AS_LOOP_DOWN;
 			hostdata->explore_timer.data = 1;
 			hostdata->host_id = hosts;
 
 			if (isp2x00_init(host) || isp2x00_reset_hardware(host)) {
-			        kfree(hostdata->res);
-				kfree(hostdata->req);
+				pci64_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
 			        scsi_unregister(host);
 				continue;
 			}
@@ -808,8 +800,7 @@
 			if (request_irq(host->irq, do_isp2x00_intr_handler, SA_INTERRUPT | SA_SHIRQ, "qlogicfc", host)) {
 			        printk("qlogicfc%d : interrupt %d already in use\n",
 				       hostdata->host_id, host->irq);
-			        kfree(hostdata->res);
-				kfree(hostdata->req);
+				pci64_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
 				scsi_unregister(host);
 				continue;
 			}
@@ -818,8 +809,7 @@
 				       "in use\n",
 				       hostdata->host_id, host->io_port, host->io_port + 0xff);
 				free_irq(host->irq, host);
-			        kfree(hostdata->res);
-				kfree(hostdata->req);
+				pci64_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
 				scsi_unregister(host);
 				continue;
 			}
@@ -977,12 +967,13 @@
 	u_short loop_id = 0x81;
 	u_short scsi_id = cur_scsi_id;
 	u_int port_id;
-	struct sns_cb req;
-	u_char sns_response[608];
+	struct sns_cb *req;
+	u_char *sns_response;
+	dma64_addr_t busaddr;
 	struct isp2x00_hostdata *hostdata;
 
 	hostdata = (struct isp2x00_hostdata *) host->hostdata;
-
+	
 	DEBUG_FABRIC(printk("qlogicfc%d : Checking for a fabric.\n", hostdata->host_id));
 	param[0] = MBOX_GET_PORT_NAME;
 	param[1] = (u16)FABRIC_PORT << 8;
@@ -995,52 +986,60 @@
 	}
 	printk("qlogicfc%d : Fabric found.\n", hostdata->host_id);
 
+	req = (struct sns_cb *)pci64_alloc_consistent(hostdata->pci_dev, sizeof(*req) + 608, &busaddr);
+	
+	if (!req){
+		printk("qlogicfc%d : Could not allocate DMA resources for fabric initialization\n", hostdata->host_id);
+		return 0;
+	}
+	sns_response = (u_char *)(req + 1);
+
 	if (hostdata->adapter_state & AS_REDO_LOOP_PORTDB){
-	        memset(&req, 0, sizeof(req));
+	        memset(req, 0, sizeof(*req));
 	
-		req.len = 8;
-		req.response_low = virt_to_bus_low32(sns_response);
-		req.response_high = virt_to_bus_high32(sns_response);
-		req.sub_len = 22;
-		req.data[0] = 0x17;
-		req.data[1] = 0x02;
-		req.data[8] = (u_char) (hostdata->port_id & 0xff);
-		req.data[9] = (u_char) (hostdata->port_id >> 8 & 0xff);
-		req.data[10] = (u_char) (hostdata->port_id >> 16 & 0xff);
-		req.data[13] = 0x01;
+		req->len = cpu_to_le16(8);
+		req->response_low = cpu_to_le32(pci64_dma_lo32(busaddr + sizeof(*req)));
+		req->response_high = cpu_to_le32(pci64_dma_hi32(busaddr + sizeof(*req)));
+		req->sub_len = cpu_to_le16(22);
+		req->data[0] = 0x17;
+		req->data[1] = 0x02;
+		req->data[8] = (u_char) (hostdata->port_id & 0xff);
+		req->data[9] = (u_char) (hostdata->port_id >> 8 & 0xff);
+		req->data[10] = (u_char) (hostdata->port_id >> 16 & 0xff);
+		req->data[13] = 0x01;
 		param[0] = MBOX_SEND_SNS;
 		param[1] = 30;
-		param[2] = virt_to_bus_low32(&req) >> 16;
-		param[3] = virt_to_bus_low32(&req);
-		param[6] = virt_to_bus_high32(&req) >> 16;
-		param[7] = virt_to_bus_high32(&req);
-		
+		param[2] = pci64_dma_lo32(busaddr) >> 16;
+		param[3] = pci64_dma_lo32(busaddr);
+		param[6] = pci64_dma_hi32(busaddr) >> 16;
+		param[7] = pci64_dma_hi32(busaddr);
+
 		isp2x00_mbox_command(host, param);
 	
 		if (param[0] != MBOX_COMMAND_COMPLETE)
-		        printk("qlogicfc%d : error sending RFC-4\n", hostdata->host_id);	       
+		        printk("qlogicfc%d : error sending RFC-4\n", hostdata->host_id);
 	}
 
 	port_id = hostdata->port_id;
 	while (!done) {
-		memset(&req, 0, sizeof(req));
+		memset(req, 0, sizeof(*req));
 
-		req.len = 304;
-		req.response_low = virt_to_bus_low32(sns_response);
-		req.response_high = virt_to_bus_high32(sns_response);
-		req.sub_len = 6;
-		req.data[0] = 0x00;
-		req.data[1] = 0x01;
-		req.data[8] = (u_char) (port_id & 0xff);
-		req.data[9] = (u_char) (port_id >> 8 & 0xff);
-		req.data[10] = (u_char) (port_id >> 16 & 0xff);
+		req->len = cpu_to_le16(304);
+		req->response_low = cpu_to_le32(pci64_dma_lo32(busaddr + sizeof(*req)));
+		req->response_high = cpu_to_le32(pci64_dma_hi32(busaddr + sizeof(*req)));
+		req->sub_len = cpu_to_le16(6);
+		req->data[0] = 0x00;
+		req->data[1] = 0x01;
+		req->data[8] = (u_char) (port_id & 0xff);
+		req->data[9] = (u_char) (port_id >> 8 & 0xff);
+		req->data[10] = (u_char) (port_id >> 16 & 0xff);
 
 		param[0] = MBOX_SEND_SNS;
 		param[1] = 14;
-		param[2] = virt_to_bus_low32(&req) >> 16;
-		param[3] = virt_to_bus_low32(&req);
-		param[6] = virt_to_bus_high32(&req) >> 16;
-		param[7] = virt_to_bus_high32(&req);
+		param[2] = pci64_dma_lo32(busaddr) >> 16;
+		param[3] = pci64_dma_lo32(busaddr);
+		param[6] = pci64_dma_hi32(busaddr) >> 16;
+		param[7] = pci64_dma_hi32(busaddr);
 
 		isp2x00_mbox_command(host, param);
 
@@ -1089,10 +1088,12 @@
 				done = 1;
 		} else {
 			printk("qlogicfc%d : Get All Next failed %x.\n", hostdata->host_id, param[0]);
+			pci64_free_consistent(hostdata->pci_dev, sizeof(*req) + 608, req, busaddr);
 			return 0;
 		}
 	}
 
+	pci64_free_consistent(hostdata->pci_dev, sizeof(*req) + 608, req, busaddr);
 	return 1;
 }
 
@@ -1102,6 +1103,7 @@
 int isp2x00_release(struct Scsi_Host *host)
 {
 	struct isp2x00_hostdata *hostdata;
+	dma64_addr_t busaddr;
 
 	ENTER("isp2x00_release");
 
@@ -1112,8 +1114,9 @@
 
 	release_region(host->io_port, 0xff);
 
-	kfree(hostdata->res);
-	kfree(hostdata->req);
+	busaddr = pci64_dma_build(le32_to_cpu(hostdata->control_block.res_queue_addr_high),
+				  le32_to_cpu(hostdata->control_block.res_queue_addr_lo));
+	pci64_free_consistent(hostdata->pci_dev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
 
 	LEAVE("isp2x00_release");
 
@@ -1245,19 +1248,20 @@
 	cmd->hdr.entry_type = ENTRY_COMMAND;
 	cmd->hdr.entry_cnt = 1;
 	cmd->target_lun = Cmnd->lun;
-	cmd->expanded_lun = Cmnd->lun;
+	cmd->expanded_lun = cpu_to_le16(Cmnd->lun);
 #if ISP2x00_PORTDB
 	cmd->target_id = hostdata->port_db[Cmnd->target].loop_id;
 #else
 	cmd->target_id = Cmnd->target;
 #endif
-	cmd->total_byte_cnt = (u_int) Cmnd->request_bufflen;
+	cmd->total_byte_cnt = cpu_to_le32(Cmnd->request_bufflen);
 	cmd->time_out = 0;
 	memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len);
 
 	if (Cmnd->use_sg) {
-		cmd->segment_cnt = sg_count = Cmnd->use_sg;
 		sg = (struct scatterlist *) Cmnd->request_buffer;
+		sg_count = pci64_map_sg(hostdata->pci_dev, sg, Cmnd->use_sg, scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+		cmd->segment_cnt = cpu_to_le16(sg_count);
 		ds = cmd->dataseg;
 		/* fill in first two sg entries: */
 		n = sg_count;
@@ -1265,11 +1269,11 @@
 			n = DATASEGS_PER_COMMAND;
 
 		for (i = 0; i < n; i++) {
-			ds[i].d_base = virt_to_bus_low32(sg->address);
-#if BITS_PER_LONG > 32
-			ds[i].d_base_hi = virt_to_bus_high32(sg->address);
+			ds[i].d_base = cpu_to_le32(pci64_dma_lo32(sg_dma64_address(sg)));
+#if PCI64_DMA_BITS > 32
+			ds[i].d_base_hi = cpu_to_le32(pci64_dma_hi32(sg_dma64_address(sg)));
 #endif
-			ds[i].d_count = sg->length;
+			ds[i].d_count = cpu_to_le32(sg_dma64_len(sg));
 			++sg;
 		}
 		sg_count -= DATASEGS_PER_COMMAND;
@@ -1291,22 +1295,32 @@
 			if (n > DATASEGS_PER_CONT)
 				n = DATASEGS_PER_CONT;
 			for (i = 0; i < n; ++i) {
-				ds[i].d_base = virt_to_bus_low32(sg->address);
-#if BITS_PER_LONG > 32
-				ds[i].d_base_hi = virt_to_bus_high32(sg->address);
+				ds[i].d_base = cpu_to_le32(pci64_dma_lo32(sg_dma64_address(sg)));
+#if PCI64_DMA_BITS > 32
+				ds[i].d_base_hi = cpu_to_le32(pci64_dma_hi32(sg_dma64_address(sg)));
 #endif
-				ds[i].d_count = sg->length;
+				ds[i].d_count = cpu_to_le32(sg_dma64_len(sg));
 				++sg;
 			}
 			sg_count -= n;
 		}
+	} else if (Cmnd->request_bufflen) {
+		dma64_addr_t busaddr = pci64_map_single(hostdata->pci_dev, Cmnd->request_buffer, Cmnd->request_bufflen,
+							scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+
+		*(dma64_addr_t *)&Cmnd->SCp = busaddr;
+		cmd->dataseg[0].d_base = cpu_to_le32(pci64_dma_lo32(busaddr));
+#if PCI64_DMA_BITS > 32
+		cmd->dataseg[0].d_base_hi = cpu_to_le32(pci64_dma_hi32(busaddr));
+#endif
+		cmd->dataseg[0].d_count = cpu_to_le32(Cmnd->request_bufflen);
+		cmd->segment_cnt = cpu_to_le16(1);
 	} else {
-		cmd->dataseg[0].d_base = virt_to_bus_low32(Cmnd->request_buffer);
-#if BITS_PER_LONG > 32
-		cmd->dataseg[0].d_base_hi = virt_to_bus_high32(Cmnd->request_buffer);
+		cmd->dataseg[0].d_base = 0;
+#if PCI64_DMA_BITS > 32
+		cmd->dataseg[0].d_base_hi = 0;
 #endif
-		cmd->dataseg[0].d_count = (u_int) Cmnd->request_bufflen;
-		cmd->segment_cnt = 1;
+		cmd->segment_cnt = cpu_to_le16(1); /* Shouldn't this be 0? */
 	}
 
 	switch (Cmnd->cmnd[0]) {
@@ -1317,38 +1331,28 @@
 	case WRITE_6:
 	case WRITE_BUFFER:
 	case MODE_SELECT:
-		cmd->control_flags = CFLAG_WRITE;
-		break;
-	case REQUEST_SENSE:
-		/* scsi.c expects sense info in a different buffer */
-		cmd->dataseg[0].d_base = virt_to_bus_low32(Cmnd->sense_buffer);
-#if BITS_PER_LONG > 32
-		cmd->dataseg[0].d_base_hi = virt_to_bus_high32(Cmnd->sense_buffer);
-#endif
-		cmd->dataseg[0].d_count = sizeof(Cmnd->sense_buffer);
-		cmd->segment_cnt = 1;
-		cmd->control_flags = CFLAG_READ;
+		cmd->control_flags = cpu_to_le16(CFLAG_WRITE);
 		break;
 	default:
-		cmd->control_flags = CFLAG_READ;
+		cmd->control_flags = cpu_to_le16(CFLAG_READ);
 		break;
 	}
 
 
 	if (Cmnd->device->tagged_supported) {
 		if ((jiffies - hostdata->tag_ages[Cmnd->target]) > (2 * SCSI_TIMEOUT)) {
-			cmd->control_flags |= CFLAG_ORDERED_TAG;
+			cmd->control_flags |= cpu_to_le16(CFLAG_ORDERED_TAG);
 			hostdata->tag_ages[Cmnd->target] = jiffies;
 		} else
 			switch (Cmnd->tag) {
 			case HEAD_OF_QUEUE_TAG:
-				cmd->control_flags |= CFLAG_HEAD_TAG;
+				cmd->control_flags |= cpu_to_le16(CFLAG_HEAD_TAG);
 				break;
 			case ORDERED_QUEUE_TAG:
-				cmd->control_flags |= CFLAG_ORDERED_TAG;
+				cmd->control_flags |= cpu_to_le16(CFLAG_ORDERED_TAG);
 				break;
 			default:
-				cmd->control_flags |= CFLAG_SIMPLE_TAG;
+				cmd->control_flags |= cpu_to_le16(CFLAG_SIMPLE_TAG);
 				break;
 		}
 	}
@@ -1543,6 +1547,16 @@
 			if (sts->hdr.entry_type == ENTRY_STATUS && (Cmnd = hostdata->handle_ptrs[sts->handle])) {
 				Cmnd->result = isp2x00_return_status(Cmnd, sts);
 				hostdata->queued--;
+
+				if (Cmnd->use_sg)
+					pci64_unmap_sg(hostdata->pci_dev,
+						       (struct scatterlist *)Cmnd->buffer, Cmnd->use_sg,
+						       scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+				else if (Cmnd->request_bufflen)
+					pci64_unmap_single(hostdata->pci_dev, *(dma64_addr_t *)&Cmnd->SCp,
+							   Cmnd->request_bufflen,
+							   scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+
 				/* 
 				 * if any of the following are true we do not
 				 * call scsi_done.  if the status is CS_ABORTED
@@ -1550,7 +1564,7 @@
 				 * level should already know its aborted.
 				 */
 				if (hostdata->handle_serials[sts->handle] != Cmnd->serial_number 
-				    || sts->completion_status == CS_ABORTED){
+				    || le16_to_cpu(sts->completion_status) == CS_ABORTED){
 					hostdata->handle_serials[sts->handle] = 0;
 					hostdata->handle_ptrs[sts->handle] = NULL;
 					outw(out_ptr, host->io_port + MBOX5);
@@ -1564,7 +1578,7 @@
 				 * the device may well be back in a couple of
 				 * seconds.
 				 */
-				if ((hostdata->adapter_state == AS_LOOP_DOWN || sts->completion_status == CS_PORT_UNAVAILABLE || sts->completion_status == CS_PORT_LOGGED_OUT || sts->completion_status == CS_PORT_CONFIG_CHANGED) && hostdata->port_db[Cmnd->target].wwn){
+				if ((hostdata->adapter_state == AS_LOOP_DOWN || sts->completion_status == cpu_to_le16(CS_PORT_UNAVAILABLE) || sts->completion_status == cpu_to_le16(CS_PORT_LOGGED_OUT) || sts->completion_status == cpu_to_le16(CS_PORT_CONFIG_CHANGED)) && hostdata->port_db[Cmnd->target].wwn){
 					outw(out_ptr, host->io_port + MBOX5);
 					continue;
 				}
@@ -1575,12 +1589,11 @@
 
 			hostdata->handle_ptrs[sts->handle] = NULL;
 
-			if (sts->completion_status == CS_RESET_OCCURRED
-			    || (sts->status_flags & STF_BUS_RESET))
+			if (sts->completion_status == cpu_to_le16(CS_RESET_OCCURRED)
+			    || (sts->status_flags & cpu_to_le16(STF_BUS_RESET)))
 				hostdata->send_marker = 1;
 
-			memset(Cmnd->sense_buffer, 0, sizeof(Cmnd->sense_buffer));
-			if (sts->scsi_status & 0x0200)
+			if (le16_to_cpu(sts->scsi_status) & 0x0200)
 				memcpy(Cmnd->sense_buffer, sts->req_sense_data,
 				       sizeof(Cmnd->sense_buffer));
 
@@ -1638,9 +1651,9 @@
 	ENTER("isp2x00_return_status");
 
 	DEBUG(printk("qlogicfc : completion status = 0x%04x\n",
-		     sts->completion_status));
+		     le16_to_cpu(sts->completion_status)));
 
-	switch (sts->completion_status) {
+	switch (le16_to_cpu(sts->completion_status)) {
 	case CS_COMPLETE:
 		host_status = DID_OK;
 		break;
@@ -1660,7 +1673,7 @@
 		host_status = DID_ERROR;
 		break;
 	case CS_DATA_UNDERRUN:
-	        if (Cmnd->underflow <= (Cmnd->request_bufflen - sts->residual))
+	        if (Cmnd->underflow <= (Cmnd->request_bufflen - le32_to_cpu(sts->residual)))
 		        host_status = DID_OK;
 		else
 		        host_status = DID_ERROR;
@@ -1675,17 +1688,17 @@
 		break;
 	default:
 		printk("qlogicfc : unknown completion status 0x%04x\n",
-		       sts->completion_status);
+		       le16_to_cpu(sts->completion_status));
 		host_status = DID_ERROR;
 		break;
 	}
 
 	DEBUG_INTR(printk("qlogicfc : host status (%s) scsi status %x\n",
-			  reason[host_status], sts->scsi_status));
+			  reason[host_status], le16_to_cpu(sts->scsi_status)));
 
 	LEAVE("isp2x00_return_status");
 
-	return (sts->scsi_status & STATUS_MASK) | (host_status << 16);
+	return (le16_to_cpu(sts->scsi_status) & STATUS_MASK) | (host_status << 16);
 }
 
 
@@ -1802,6 +1815,7 @@
 	u_short param[8];
 	struct isp2x00_hostdata *hostdata;
 	int loop_count;
+	dma64_addr_t busaddr;
 
 	ENTER("isp2x00_reset_hardware");
 
@@ -1896,6 +1910,14 @@
 	}
 #endif
 
+#ifdef __BIG_ENDIAN
+	{
+		u64 val;
+		memcpy(&val, &hostdata->control_block.node_name, sizeof(u64));
+		hostdata->wwn = ((val & 0xff00ff00ff00ff00ULL) >> 8)
+			      | ((val & 0x00ff00ff00ff00ffULL) << 8);
+	}
+#else
 	hostdata->wwn = (u64) (hostdata->control_block.node_name[0]) << 56;
 	hostdata->wwn |= (u64) (hostdata->control_block.node_name[0] & 0xff00) << 48;
 	hostdata->wwn |= (u64) (hostdata->control_block.node_name[1] & 0xff00) << 24;
@@ -1904,26 +1926,37 @@
 	hostdata->wwn |= (u64) (hostdata->control_block.node_name[2] & 0xff00) << 8;
 	hostdata->wwn |= (u64) (hostdata->control_block.node_name[3] & 0x00ff) << 8;
 	hostdata->wwn |= (u64) (hostdata->control_block.node_name[3] & 0xff00) >> 8;
+#endif
+
+	/* FIXME: If the DMA transfer goes one way only, this should use PCI_DMA_TODEVICE and below as well. */
+	busaddr = pci64_map_single(hostdata->pci_dev, &hostdata->control_block, sizeof(hostdata->control_block),
+				   PCI_DMA_BIDIRECTIONAL);
 
 	param[0] = MBOX_INIT_FIRMWARE;
-	param[2] = (u_short) (virt_to_bus_low32(&hostdata->control_block) >> 16);
-	param[3] = (u_short) (virt_to_bus_low32(&hostdata->control_block) & 0xffff);
+	param[2] = (u_short) (pci64_dma_lo32(busaddr) >> 16);
+	param[3] = (u_short) (pci64_dma_lo32(busaddr) & 0xffff);
 	param[4] = 0;
 	param[5] = 0;
-	param[6] = (u_short) (virt_to_bus_high32(&hostdata->control_block) >> 16);
-	param[7] = (u_short) (virt_to_bus_high32(&hostdata->control_block) & 0xffff);
+	param[6] = (u_short) (pci64_dma_hi32(busaddr) >> 16);
+	param[7] = (u_short) (pci64_dma_hi32(busaddr) & 0xffff);
 	isp2x00_mbox_command(host, param);
 	if (param[0] != MBOX_COMMAND_COMPLETE) {
 		printk("qlogicfc%d.c: Ouch 0x%04x\n", hostdata->host_id,  param[0]);
+		pci64_unmap_single(hostdata->pci_dev, busaddr, sizeof(hostdata->control_block),
+				   PCI_DMA_BIDIRECTIONAL);
 		return 1;
 	}
 	param[0] = MBOX_GET_FIRMWARE_STATE;
 	isp2x00_mbox_command(host, param);
 	if (param[0] != MBOX_COMMAND_COMPLETE) {
 		printk("qlogicfc%d.c: 0x%04x\n", hostdata->host_id,  param[0]);
+		pci64_unmap_single(hostdata->pci_dev, busaddr, sizeof(hostdata->control_block),
+				   PCI_DMA_BIDIRECTIONAL);
 		return 1;
 	}
 
+	pci64_unmap_single(hostdata->pci_dev, busaddr, sizeof(hostdata->control_block),
+			   PCI_DMA_BIDIRECTIONAL);
 	LEAVE("isp2x00_reset_hardware");
 
 	return 0;
@@ -1939,11 +1972,11 @@
 		return 1;
 
 	value = isp2x00_read_nvram_word(host, 8);
-	control_block->node_name[0] = isp2x00_read_nvram_word(host, 9);
-	control_block->node_name[1] = isp2x00_read_nvram_word(host, 10);
-	control_block->node_name[2] = isp2x00_read_nvram_word(host, 11);
-	control_block->node_name[3] = isp2x00_read_nvram_word(host, 12);
-	control_block->hard_addr = isp2x00_read_nvram_word(host, 13);
+	control_block->node_name[0] = cpu_to_le16(isp2x00_read_nvram_word(host, 9));
+	control_block->node_name[1] = cpu_to_le16(isp2x00_read_nvram_word(host, 10));
+	control_block->node_name[2] = cpu_to_le16(isp2x00_read_nvram_word(host, 11));
+	control_block->node_name[3] = cpu_to_le16(isp2x00_read_nvram_word(host, 12));
+	control_block->hard_addr = cpu_to_le16(isp2x00_read_nvram_word(host, 13));
 
 	return 0;
 
@@ -2156,12 +2189,12 @@
 	printk("qlogicfc : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n", 
 	status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags);
 	printk("qlogicfc : scsi status = 0x%04x, completion status = 0x%04x\n",
-	       status->scsi_status, status->completion_status);
+	       le16_to_cpu(status->scsi_status), le16_to_cpu(status->completion_status));
 	printk("qlogicfc : state flags = 0x%04x, status flags = 0x%04x\n", 
-	       status->state_flags, status->status_flags);
+	       le16_to_cpu(status->state_flags), le16_to_cpu(status->status_flags));
 	printk("qlogicfc : response info length = 0x%04x, request sense length = 0x%04x\n",
-	       status->res_info_len, status->req_sense_len);
-	printk("qlogicfc : residual transfer length = 0x%08x, response = 0x%02x\n", status->residual, status->res_info[3]);
+	       le16_to_cpu(status->res_info_len), le16_to_cpu(status->req_sense_len));
+	printk("qlogicfc : residual transfer length = 0x%08x, response = 0x%02x\n", le32_to_cpu(status->residual), status->res_info[3]);
 
 }
 
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/qlogicfc.h linux/drivers/scsi/qlogicfc.h
--- v2.3.47/linux/drivers/scsi/qlogicfc.h	Thu Nov 18 20:25:37 1999
+++ linux/drivers/scsi/qlogicfc.h	Wed Feb 23 13:37:35 2000
@@ -62,7 +62,7 @@
  * determined for each queue request anew.
  */
 
-#if BITS_PER_LONG > 32
+#if PCI64_DMA_BITS > 32
 #define DATASEGS_PER_COMMAND 2
 #define DATASEGS_PER_CONT 5
 #else
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/sgiwd93.c linux/drivers/scsi/sgiwd93.c
--- v2.3.47/linux/drivers/scsi/sgiwd93.c	Wed Dec  8 14:11:26 1999
+++ linux/drivers/scsi/sgiwd93.c	Thu Feb 24 22:51:47 2000
@@ -2,10 +2,12 @@
  * sgiwd93.c: SGI WD93 scsi driver.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
+ *		 1999 Andrew R. Baker (andrewb@uab.edu)
+ *		      - Support for 2nd SCSI controller on Indigo2
+ * 
  * (In all truth, Jed Schimmel wrote all this code.)
  *
- * $Id: sgiwd93.c,v 1.13 1999/03/28 23:06:06 tsbogend Exp $
+ * $Id: sgiwd93.c,v 1.20 2000/02/21 15:05:48 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/types.h>
@@ -13,16 +15,16 @@
 #include <linux/blk.h>
 #include <linux/version.h>
 #include <linux/delay.h>
+#include <linux/spinlock.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <asm/sgi.h>
 #include <asm/sgialib.h>
-#include <asm/sgimc.h>
-#include <asm/sgihpc.h>
-#include <asm/sgint23.h>
+#include <asm/sgi/sgi.h>
+#include <asm/sgi/sgimc.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
 #include <asm/irq.h>
-#include <asm/spinlock.h>
 #include <asm/io.h>
 
 #include "scsi.h"
@@ -38,6 +40,7 @@
 };
 
 struct Scsi_Host *sgiwd93_host = NULL;
+struct Scsi_Host *sgiwd93_host1 = NULL;
 
 /* Wuff wuff, wuff, wd33c93.c, wuff wuff, object oriented, bow wow. */
 static inline void write_wd33c93_count(wd33c93_regs *regp, unsigned long value)
@@ -65,7 +68,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&io_request_lock, flags);
-	wd33c93_intr(sgiwd93_host);
+	wd33c93_intr((struct Scsi_Host *) dev_id);
 	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
@@ -231,9 +234,9 @@
 #endif
 }
 
-void sgiwd93_reset(void)
+void sgiwd93_reset(uchar *base)
 {
-	struct hpc3_scsiregs *hregs = &hpc3c0->scsi_chan0;
+	struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) base;
 
 	hregs->ctrl = HPC3_SCTRL_CRESET;
 	udelay (50);
@@ -261,9 +264,11 @@
 {
 	static unsigned char called = 0;
 	struct hpc3_scsiregs *hregs = &hpc3c0->scsi_chan0;
+	struct hpc3_scsiregs *hregs1 = &hpc3c0->scsi_chan1;
 	struct WD33C93_hostdata *hdata;
+	struct WD33C93_hostdata *hdata1;
 	uchar *buf;
-
+	
 	if(called)
 		return 0; /* Should bitch on the console about this... */
 
@@ -271,12 +276,12 @@
 
 	sgiwd93_host = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata));
 	sgiwd93_host->base = (unsigned char *) hregs;
-	sgiwd93_host->irq = 1;
+	sgiwd93_host->irq = SGI_WD93_0_IRQ;
 
 	buf = (uchar *) get_free_page(GFP_KERNEL);
 	init_hpc_chain(buf);
 	dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
-
+	/* HPC_SCSI_REG0 | 0x03 | KSEG1 */
 	wd33c93_init(sgiwd93_host, (wd33c93_regs *) 0xbfbc0003,
 		     dma_setup, dma_stop, WD33C93_FS_16_20);
 
@@ -285,7 +290,28 @@
 	hdata->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf));
 	dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
 
-	request_irq(1, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host);
+	request_irq(SGI_WD93_0_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host);
+        /* set up second controller on the Indigo2 */
+	if(!sgi_guiness) {
+		sgiwd93_host1 = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata));
+		sgiwd93_host1->base = (unsigned char *) hregs1;
+		sgiwd93_host1->irq = SGI_WD93_1_IRQ;
+
+		buf = (uchar *) get_free_page(GFP_KERNEL);
+		init_hpc_chain(buf);
+		dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
+		/* HPC_SCSI_REG1 | 0x03 | KSEG1 */
+		wd33c93_init(sgiwd93_host1, (wd33c93_regs *) 0xbfbc8003,
+			     dma_setup, dma_stop, WD33C93_FS_16_20);
+
+		hdata1 = (struct WD33C93_hostdata *)sgiwd93_host1->hostdata;
+		hdata1->no_sync = 0;
+		hdata1->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf));
+		dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
+
+		request_irq(SGI_WD93_1_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host1);
+	}
+	
 	called = 1;
 
 	return 1; /* Found one. */
@@ -306,9 +332,14 @@
 int sgiwd93_release(struct Scsi_Host *instance)
 {
 #ifdef MODULE
-	free_irq(1, sgiwd93_intr);
+	free_irq(SGI_WD93_0_IRQ, sgiwd93_intr);
 	free_page(KSEG0ADDR(hdata->dma_bounce_buffer));
 	wd33c93_release();
+	if(!sgi_guiness) {
+		free_irq(SGI_WD93_1_IRQ, sgiwd93_intr);
+		free_page(KSEG0ADDR(hdata1->dma_bounce_buffer));
+		wd33c93_release();
+	}
 #endif
 	return 1;
 }
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/sgiwd93.h linux/drivers/scsi/sgiwd93.h
--- v2.3.47/linux/drivers/scsi/sgiwd93.h	Thu Nov 11 20:11:48 1999
+++ linux/drivers/scsi/sgiwd93.h	Thu Feb 24 22:51:47 2000
@@ -1,4 +1,4 @@
-/* $Id: sgiwd93.h,v 1.5 1998/08/25 09:18:50 ralf Exp $
+/* $Id: sgiwd93.h,v 1.6 2000/01/29 01:42:18 ralf Exp $
  * sgiwd93.h: SGI WD93 scsi definitions.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- v2.3.47/linux/drivers/scsi/sr_ioctl.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/scsi/sr_ioctl.c	Tue Feb 22 22:19:07 2000
@@ -149,7 +149,7 @@
 	sr_cmd[0] = GPCMD_TEST_UNIT_READY;
 	sr_cmd[1] = ((scsi_CDs[minor].device->lun) << 5);
 	sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
-	return sr_do_ioctl(minor, sr_cmd, NULL, 255, 1, SCSI_DATA_NONE);
+	return sr_do_ioctl(minor, sr_cmd, NULL, 0, 1, SCSI_DATA_NONE);
 }
 
 int sr_tray_move(struct cdrom_device_info *cdi, int pos)
@@ -161,7 +161,7 @@
 	sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
 	sr_cmd[4] = (pos == 0) ? 0x03 /* close */ : 0x02 /* eject */ ;
 
-	return sr_do_ioctl(MINOR(cdi->dev), sr_cmd, NULL, 255, 0, SCSI_DATA_NONE);
+	return sr_do_ioctl(MINOR(cdi->dev), sr_cmd, NULL, 0, 0, SCSI_DATA_NONE);
 }
 
 int sr_lock_door(struct cdrom_device_info *cdi, int lock)
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/sun3_scsi.c linux/drivers/scsi/sun3_scsi.c
--- v2.3.47/linux/drivers/scsi/sun3_scsi.c	Sun Feb 13 19:29:04 2000
+++ linux/drivers/scsi/sun3_scsi.c	Sat Feb 26 20:33:03 2000
@@ -121,10 +121,6 @@
 /* minimum number of bytes to to dma on */
 #define SUN3_DMA_MINSIZE 128
 
-static struct proc_dir_entry proc_scsi_sun3_5380 = {
-	PROC_SCSI_MAC, 13, "Sun3 5380 SCSI", S_IFDIR | S_IRUGO, S_IXUGO, 2
-};
-
 static volatile unsigned char *sun3_scsi_regp;
 static volatile struct sun3_dma_regs *dregs;
 static unsigned char *dmabuf = NULL; /* dma memory buffer */
@@ -196,7 +192,7 @@
 	if(called)
 		return 0;
 
-	tpnt->proc_dir = &proc_scsi_sun3_5380;
+	tpnt->proc_name = "Sun3 5380 SCSI";
 
 	/* setup variables */
 	tpnt->can_queue =
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c
--- v2.3.47/linux/drivers/scsi/sym53c8xx.c	Tue Jan 11 22:31:41 2000
+++ linux/drivers/scsi/sym53c8xx.c	Mon Feb 21 17:35:06 2000
@@ -55,7 +55,7 @@
 */
 
 /*
-**	January 9 2000, sym53c8xx 1.5h
+**	February 20 2000, sym53c8xx 1.5j
 **
 **	Supported SCSI features:
 **	    Synchronous data transfers
@@ -84,7 +84,7 @@
 /*
 **	Name and version of the driver
 */
-#define SCSI_NCR_DRIVER_NAME	"sym53c8xx - version 1.5h"
+#define SCSI_NCR_DRIVER_NAME	"sym53c8xx - version 1.5j"
 
 /* #define DEBUG_896R1 */
 #define SCSI_NCR_OPTIMIZE_896
@@ -174,6 +174,15 @@
 
 #include "sym53c8xx.h"
 
+/*
+**	Hmmm... What complex some PCI-HOST bridges actually are, 
+**	despite the fact that the PCI specifications are looking 
+**	so smart and simple! ;-)
+*/
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,47)
+#define SCSI_NCR_DYNAMIC_DMA_MAPPING
+#endif
+
 /*==========================================================
 **
 **	A la VMS/CAM-3 queue management.
@@ -501,7 +510,7 @@
 typedef unsigned int pcidev_t;
 #define PCIDEV_NULL		(~0u)
 #define PciBusNumber(d)		((d)>>8)
-#define PciDeviceFn(n)		((d)&0xff)
+#define PciDeviceFn(d)		((d)&0xff)
 #define __PciDev(busn, devfn)	(((busn)<<8)+(devfn))
 
 #define pci_present pcibios_present
@@ -539,7 +548,7 @@
 static u_short __init PciVendorId(pcidev_t dev)
 {
 	u_short vendor_id;
-	pcibios_read_config_word(dev, PCI_VENDOR_ID, &vendor_id);
+	pci_read_config_word(dev, PCI_VENDOR_ID, &vendor_id);
 	return vendor_id;
 }
 
@@ -552,7 +561,7 @@
 
 static u_int __init PciIrqLine(pcidev_t dev)
 {
-	u_short irq;
+	u_char irq;
 	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
 	return irq;
 }
@@ -652,17 +661,6 @@
 #endif
 
 /*
-**	Address translation
-**
-**	The driver has to provide bus memory addresses to 
-**	the script processor. Because some architectures use 
-**	different physical addressing scheme from the PCI BUS, 
-**	we use virt_to_bus() instead of virt_to_phys().
-*/
-
-#define vtobus(p)	virt_to_bus(p)
-
-/*
 **	Memory mapped IO
 **
 **	Since linux-2.1, we must use ioremap() to map the io memory space.
@@ -736,44 +734,76 @@
 **	this allocator allows simple and fast address calculations  
 **	from the SCRIPTS code. In addition, cache line alignment 
 **	is guaranteed for power of 2 cache line size.
+**	Enhanced in linux-2.3.44 to provide a memory pool per pcidev 
+**	to support dynamic dma mapping. (I would have preferred a 
+**	real bus astraction, btw).
 */
 
-#define MEMO_SHIFT	4	/* 16 bytes minimum memory chunk */
-#define MEMO_PAGE_ORDER	0	/* 1 PAGE maximum (for now (ever?) */
-typedef unsigned long addr;	/* Enough bits to bit-hack addresses */
-
-#define MEMO_FREE_UNUSED	/* Free unused pages immediately */
-
-struct m_link {
-	struct m_link *next;	/* Simple links are enough */
-};
-
-#ifndef GFP_DMA_32BIT
-#define GFP_DMA_32BIT	0	/* Will this flag ever exist */
-#endif
-
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,0)
-#define GetPages(order) __get_free_pages(GFP_ATOMIC | GFP_DMA_32BIT, order)
+#define __GetFreePages(flags, order) __get_free_pages(flags, order)
 #else
-#define GetPages(order) __get_free_pages(GFP_ATOMIC | GFP_DMA_32BIT, order, 0)
+#define __GetFreePages(flags, order) __get_free_pages(flags, order, 0)
 #endif
 
-/*
-**	Lists of available memory chunks.
-**	Starts with 16 bytes chunks until 1 PAGE chunks.
-*/
-static struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1];
+#define MEMO_SHIFT	4	/* 16 bytes minimum memory chunk */
+#if PAGE_SIZE >= 8192
+#define MEMO_PAGE_ORDER	0	/* 1 PAGE  maximum */
+#else
+#define MEMO_PAGE_ORDER	1	/* 2 PAGES maximum */
+#endif
+#define MEMO_FREE_UNUSED	/* Free unused pages immediately */
+#define MEMO_WARN	1
+#define MEMO_GFP_FLAGS	GFP_ATOMIC
+#define MEMO_CLUSTER_SHIFT	(PAGE_SHIFT+MEMO_PAGE_ORDER)
+#define MEMO_CLUSTER_SIZE	(1UL << MEMO_CLUSTER_SHIFT)
+#define MEMO_CLUSTER_MASK	(MEMO_CLUSTER_SIZE-1)
+
+typedef u_long m_addr_t;	/* Enough bits to bit-hack addresses */
+typedef pcidev_t m_bush_t;	/* Something that addresses DMAable */
+
+typedef struct m_link {		/* Link between free memory chunks */
+	struct m_link *next;
+} m_link_s;
+
+#ifdef	SCSI_NCR_DYNAMIC_DMA_MAPPING
+typedef struct m_vtob {		/* Virtual to Bus address translation */
+	struct m_vtob *next;
+	m_addr_t vaddr;
+	m_addr_t baddr;
+} m_vtob_s;
+#define VTOB_HASH_SHIFT		5
+#define VTOB_HASH_SIZE		(1UL << VTOB_HASH_SHIFT)
+#define VTOB_HASH_MASK		(VTOB_HASH_SIZE-1)
+#define VTOB_HASH_CODE(m)	\
+	((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK)
+#endif
+
+typedef struct m_pool {		/* Memory pool of a given kind */
+#ifdef	SCSI_NCR_DYNAMIC_DMA_MAPPING
+	m_bush_t bush;
+	m_addr_t (*getp)(struct m_pool *);
+	void (*freep)(struct m_pool *, m_addr_t);
+#define M_GETP()		mp->getp(mp)
+#define M_FREEP(p)		mp->freep(mp, p)
+#define GetPages()		__GetFreePages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER)
+#define FreePages(p)		free_pages(p, MEMO_PAGE_ORDER)
+	int nump;
+	m_vtob_s *(vtob[VTOB_HASH_SIZE]);
+	struct m_pool *next;
+#else
+#define M_GETP()		__GetFreePages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER)
+#define M_FREEP(p)		free_pages(p, MEMO_PAGE_ORDER)
+#endif	/* SCSI_NCR_DYNAMIC_DMA_MAPPING */
+	struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1];
+} m_pool_s;
 
-/*
-**	Allocate a memory area aligned on the lowest power of 2 
-**	greater than the requested size.
-*/
-static void *__m_alloc(int size)
+static void *___m_alloc(m_pool_s *mp, int size)
 {
 	int i = 0;
 	int s = (1 << MEMO_SHIFT);
 	int j;
-	addr a ;
+	m_addr_t a;
+	m_link_s *h = mp->h;
 
 	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
 		return 0;
@@ -786,7 +816,7 @@
 	j = i;
 	while (!h[j].next) {
 		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
-			h[j].next = (struct m_link *) GetPages(MEMO_PAGE_ORDER);
+			h[j].next = (m_link_s *) M_GETP();
 			if (h[j].next)
 				h[j].next->next = 0;
 			break;
@@ -794,36 +824,32 @@
 		++j;
 		s <<= 1;
 	}
-	a = (addr) h[j].next;
+	a = (m_addr_t) h[j].next;
 	if (a) {
 		h[j].next = h[j].next->next;
 		while (j > i) {
 			j -= 1;
 			s >>= 1;
-			h[j].next = (struct m_link *) (a+s);
+			h[j].next = (m_link_s *) (a+s);
 			h[j].next->next = 0;
 		}
 	}
 #ifdef DEBUG
-	printk("m_alloc(%d) = %p\n", size, (void *) a);
+	printk("___m_alloc(%d) = %p\n", size, (void *) a);
 #endif
 	return (void *) a;
 }
 
-/*
-**	Free a memory area allocated using m_alloc().
-**	Coalesce buddies.
-**	Free pages that become unused if MEMO_FREE_UNUSED is defined.
-*/
-static void __m_free(void *ptr, int size)
+static void ___m_free(m_pool_s *mp, void *ptr, int size)
 {
 	int i = 0;
 	int s = (1 << MEMO_SHIFT);
-	struct m_link *q;
-	addr a, b;
+	m_link_s *q;
+	m_addr_t a, b;
+	m_link_s *h = mp->h;
 
 #ifdef DEBUG
-	printk("m_free(%p, %d)\n", ptr, size);
+	printk("___m_free(%p, %d)\n", ptr, size);
 #endif
 
 	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
@@ -834,23 +860,23 @@
 		++i;
 	}
 
-	a = (addr) ptr;
+	a = (m_addr_t) ptr;
 
 	while (1) {
 #ifdef MEMO_FREE_UNUSED
 		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
-			free_pages(a, MEMO_PAGE_ORDER);
+			M_FREEP(a);
 			break;
 		}
 #endif
 		b = a ^ s;
 		q = &h[i];
-		while (q->next && q->next != (struct m_link *) b) {
+		while (q->next && q->next != (m_link_s *) b) {
 			q = q->next;
 		}
 		if (!q->next) {
-			((struct m_link *) a)->next = h[i].next;
-			h[i].next = (struct m_link *) a;
+			((m_link_s *) a)->next = h[i].next;
+			h[i].next = (m_link_s *) a;
 			break;
 		}
 		q->next = q->next->next;
@@ -860,45 +886,338 @@
 	}
 }
 
-#define MEMO_WARN	1
-
-/*
-**	The memory pool is shared by all instances.
-**	We use a global SMP LOCK to be SMP safe.
-*/
-
-static void *m_calloc(int size, char *name, int uflags)
+static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags)
 {
-	u_long flags;
 	void *p;
 
-	NCR_LOCK_DRIVER(flags);
-	p = __m_alloc(size);
-	NCR_UNLOCK_DRIVER(flags);
+	p = ___m_alloc(mp, size);
 
 	if (DEBUG_FLAGS & DEBUG_ALLOC)
 		printk ("new %-10s[%4d] @%p.\n", name, size, p);
 
 	if (p)
-		memset(p, 0, size);
+		bzero(p, size);
 	else if (uflags & MEMO_WARN)
 		printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size);
 
 	return p;
 }
 
+#define __m_calloc(mp, s, n)	__m_calloc2(mp, s, n, MEMO_WARN)
+
+static void __m_free(m_pool_s *mp, void *ptr, int size, char *name)
+{
+	if (DEBUG_FLAGS & DEBUG_ALLOC)
+		printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr);
+
+	___m_free(mp, ptr, size);
+
+}
+
+/*
+ * With pci bus iommu support, we use a default pool of unmapped memory 
+ * for memory we donnot need to DMA from/to and one pool per pcidev for 
+ * memory accessed by the PCI chip. `mp0' is the default not DMAable pool.
+ */
+
+#ifndef	SCSI_NCR_DYNAMIC_DMA_MAPPING
+
+static m_pool_s mp0;
+
+#else
+
+static m_addr_t ___mp0_getp(m_pool_s *mp)
+{
+	m_addr_t m = GetPages();
+	if (m)
+		++mp->nump;
+	return m;
+}
+
+static void ___mp0_freep(m_pool_s *mp, m_addr_t m)
+{
+	FreePages(m);
+	--mp->nump;
+}
+
+static m_pool_s mp0 = {0, ___mp0_getp, ___mp0_freep};
+
+#endif	/* SCSI_NCR_DYNAMIC_DMA_MAPPING */
+
+static void *m_calloc(int size, char *name)
+{
+	u_long flags;
+	void *m;
+	NCR_LOCK_DRIVER(flags);
+	m = __m_calloc(&mp0, size, name);
+	NCR_UNLOCK_DRIVER(flags);
+	return m;
+}
+
 static void m_free(void *ptr, int size, char *name)
 {
 	u_long flags;
+	NCR_LOCK_DRIVER(flags);
+	__m_free(&mp0, ptr, size, name);
+	NCR_UNLOCK_DRIVER(flags);
+}
 
-	if (DEBUG_FLAGS & DEBUG_ALLOC)
-		printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr);
+/*
+ * DMAable pools.
+ */
+
+#ifndef	SCSI_NCR_DYNAMIC_DMA_MAPPING
+
+/* Without pci bus iommu support, all the memory is assumed DMAable */
+
+#define __m_calloc_dma(b, s, n)		m_calloc(s, n)
+#define __m_free_dma(b, p, s, n)	m_free(p, s, n)
+#define __vtobus(b, p)			virt_to_bus(p)
+
+#else
+
+/*
+ * With pci bus iommu support, we maintain one pool per pcidev and a 
+ * hashed reverse table for virtual to bus physical address translations.
+ */
+static m_addr_t ___dma_getp(m_pool_s *mp)
+{
+	m_addr_t vp;
+	m_vtob_s *vbp;
+
+	vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");
+	if (vbp) {
+		dma_addr_t daddr;
+		vp = (m_addr_t) pci_alloc_consistent(mp->bush,
+						PAGE_SIZE<<MEMO_PAGE_ORDER,
+						&daddr);
+		if (vp) {
+			int hc = VTOB_HASH_CODE(vp);
+			vbp->vaddr = vp;
+			vbp->baddr = daddr;
+			vbp->next = mp->vtob[hc];
+			mp->vtob[hc] = vbp;
+			++mp->nump;
+			return vp;
+		}
+	}
+	__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
+	return 0;
+}
+
+static void ___dma_freep(m_pool_s *mp, m_addr_t m)
+{
+	m_vtob_s **vbpp, *vbp;
+	int hc = VTOB_HASH_CODE(m);
+
+	vbpp = &mp->vtob[hc];
+	while (*vbpp && (*vbpp)->vaddr != m)
+		vbpp = &(*vbpp)->next;
+	if (*vbpp) {
+		vbp = *vbpp;
+		*vbpp = (*vbpp)->next;
+		pci_free_consistent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
+				    (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
+		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
+		--mp->nump;
+	}
+}
+
+static inline m_pool_s *___get_dma_pool(m_bush_t bush)
+{
+	m_pool_s *mp;
+	for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next);
+	return mp;
+}
+
+static m_pool_s *___cre_dma_pool(m_bush_t bush)
+{
+	m_pool_s *mp;
+	mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL");
+	if (mp) {
+		bzero(mp, sizeof(*mp));
+		mp->bush = bush;
+		mp->getp = ___dma_getp;
+		mp->freep = ___dma_freep;
+		mp->next = mp0.next;
+		mp0.next = mp;
+	}
+	return mp;
+}
+
+static void ___del_dma_pool(m_pool_s *p)
+{
+	struct m_pool **pp = &mp0.next;
+
+	while (*pp && *pp != p)
+		pp = &(*pp)->next;
+	if (*pp) {
+		*pp = (*pp)->next;
+		__m_free(&mp0, p, sizeof(*p), "MPOOL");
+	}
+}
+
+static void *__m_calloc_dma(m_bush_t bush, int size, char *name)
+{
+	u_long flags;
+	struct m_pool *mp;
+	void *m = 0;
+
+	NCR_LOCK_DRIVER(flags);
+	mp = ___get_dma_pool(bush);
+	if (!mp)
+		mp = ___cre_dma_pool(bush);
+	if (mp)
+		m = __m_calloc(mp, size, name);
+	if (mp && !mp->nump)
+		___del_dma_pool(mp);
+	NCR_UNLOCK_DRIVER(flags);
+
+	return m;
+}
+
+static void __m_free_dma(m_bush_t bush, void *m, int size, char *name)
+{
+	u_long flags;
+	struct m_pool *mp;
+
+	NCR_LOCK_DRIVER(flags);
+	mp = ___get_dma_pool(bush);
+	if (mp)
+		__m_free(mp, m, size, name);
+	if (mp && !mp->nump)
+		___del_dma_pool(mp);
+	NCR_UNLOCK_DRIVER(flags);
+}
+
+static m_addr_t __vtobus(m_bush_t bush, void *m)
+{
+	u_long flags;
+	m_pool_s *mp;
+	int hc = VTOB_HASH_CODE(m);
+	m_vtob_s *vp = 0;
+	m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK;
 
 	NCR_LOCK_DRIVER(flags);
-	__m_free(ptr, size);
+	mp = ___get_dma_pool(bush);
+	if (mp) {
+		vp = mp->vtob[hc];
+		while (vp && (m_addr_t) vp->vaddr != a)
+			vp = vp->next;
+	}
 	NCR_UNLOCK_DRIVER(flags);
+	return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;
+}
+
+#endif	/* SCSI_NCR_DYNAMIC_DMA_MAPPING */
+
+#define _m_calloc_dma(np, s, n)		__m_calloc_dma(np->pdev, s, n)
+#define _m_free_dma(np, p, s, n)	__m_free_dma(np->pdev, p, s, n)
+#define m_calloc_dma(s, n)		_m_calloc_dma(np, s, n)
+#define m_free_dma(p, s, n)		_m_free_dma(np, p, s, n)
+#define _vtobus(np, p)			__vtobus(np->pdev, p)
+#define vtobus(p)			_vtobus(np, p)
+
+/*
+ *  Deal with DMA mapping/unmapping.
+ */
+
+#ifndef SCSI_NCR_DYNAMIC_DMA_MAPPING
+
+/* Linux versions prior to pci bus iommu kernel interface */
+
+#define __unmap_scsi_data(pdev, cmd)	do {; } while (0)
+#define __map_scsi_single_data(pdev, cmd) (__vtobus(pdev,(cmd)->request_buffer))
+#define __map_scsi_sg_data(pdev, cmd)	((cmd)->use_sg)
+#define __sync_scsi_data(pdev, cmd)	do {; } while (0)
+
+#define scsi_sg_dma_address(sc)		vtobus((sc)->address)
+#define scsi_sg_dma_len(sc)		((sc)->length)
+
+#else
+
+/* Linux version with pci bus iommu kernel interface */
+
+/* To keep track of the dma mapping (sg/single) that has been set */
+#define __data_mapped	SCp.phase
+#define __data_mapping	SCp.have_data_in
+
+static void __unmap_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd)
+{
+	int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+
+	switch(cmd->__data_mapped) {
+	case 2:
+		pci_unmap_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
+		break;
+	case 1:
+		pci_unmap_single(pdev, cmd->__data_mapping,
+				 cmd->request_bufflen, dma_dir);
+		break;
+	}
+	cmd->__data_mapped = 0;
+}
+
+static u_long __map_scsi_single_data(pcidev_t pdev, Scsi_Cmnd *cmd)
+{
+	dma_addr_t mapping;
+	int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+
+	if (cmd->request_bufflen == 0)
+		return 0;
+
+	mapping = pci_map_single(pdev, cmd->request_buffer,
+				 cmd->request_bufflen, dma_dir);
+	cmd->__data_mapped = 1;
+	cmd->__data_mapping = mapping;
+
+	return mapping;
 }
 
+static int __map_scsi_sg_data(pcidev_t pdev, Scsi_Cmnd *cmd)
+{
+	int use_sg;
+	int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+
+	if (cmd->use_sg == 0)
+		return 0;
+
+	use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
+	cmd->__data_mapped = 2;
+	cmd->__data_mapping = use_sg;
+
+	return use_sg;
+}
+
+static void __sync_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd)
+{
+	int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+
+	switch(cmd->__data_mapped) {
+	case 2:
+		pci_dma_sync_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
+		break;
+	case 1:
+		pci_dma_sync_single(pdev, cmd->__data_mapping,
+				    cmd->request_bufflen, dma_dir);
+		break;
+	}
+}
+
+#define scsi_sg_dma_address(sc)		sg_dma_address(sc)
+#define scsi_sg_dma_len(sc)		sg_dma_len(sc)
+
+#endif	/* SCSI_NCR_DYNAMIC_DMA_MAPPING */
+
+#define unmap_scsi_data(np, cmd)	__unmap_scsi_data(np->pdev, cmd)
+#define map_scsi_single_data(np, cmd)	__map_scsi_single_data(np->pdev, cmd)
+#define map_scsi_sg_data(np, cmd)	__map_scsi_sg_data(np->pdev, cmd)
+#define sync_scsi_data(np, cmd)		__sync_scsi_data(np->pdev, cmd)
+
+
+/*
+ * Print out some buffer.
+ */
 static void ncr_print_hex(u_char *p, int n)
 {
 	while (n-- > 0)
@@ -915,21 +1234,49 @@
 /*
 **	Transfer direction
 **
-**	Low-level scsi drivers under Linux do not receive the expected 
-**	data transfer direction from upper scsi drivers.
-**	The driver will only check actual data direction for common 
-**	scsi opcodes. Other ones may cause problem, since they may 
-**	depend on device type or be vendor specific.
-**	I would prefer to never trust the device for data direction, 
-**	but that is not possible.
-**
-**	The original driver requires the expected direction to be known.
-**	The Linux version of the driver has been enhanced in order to 
-**	be able to transfer data in the direction choosen by the target. 
+**	Until some linux kernel version near 2.3.40, low-level scsi 
+**	drivers were not told about data transfer direction.
+**	We check the existence of this feature that has been expected 
+**	for a _long_ time by all SCSI driver developers by just 
+**	testing against the definition of SCSI_DATA_UNKNOWN. Indeed 
+**	this is a hack, but testing against a kernel version would 
+**	have been a shame. ;-)
 */
+#ifdef	SCSI_DATA_UNKNOWN
+
+#define scsi_data_direction(cmd)	(cmd->sc_data_direction)
 
-#define XFER_IN		(1)
-#define XFER_OUT	(2)
+#else
+
+#define	SCSI_DATA_UNKNOWN	0
+#define	SCSI_DATA_WRITE		1
+#define	SCSI_DATA_READ		2
+#define	SCSI_DATA_NONE		3
+
+static __inline__ scsi_data_direction(Scsi_Cmnd *cmd)
+{
+	int direction;
+
+	switch((int) cmd->cmnd[0]) {
+	case 0x08:  /*	READ(6)				08 */
+	case 0x28:  /*	READ(10)			28 */
+	case 0xA8:  /*	READ(12)			A8 */
+		direction = SCSI_DATA_READ;
+		break;
+	case 0x0A:  /*	WRITE(6)			0A */
+	case 0x2A:  /*	WRITE(10)			2A */
+	case 0xAA:  /*	WRITE(12)			AA */
+		direction = SCSI_DATA_WRITE;
+		break;
+	default:
+		direction = SCSI_DATA_UNKNOWN;
+		break;
+	}
+
+	return direction;
+}
+
+#endif	/* SCSI_DATA_UNKNOWN */
 
 /*
 **	Head of list of NCR boards
@@ -1039,6 +1386,7 @@
 **	to save data on each detected board for ncr_attach().
 */
 typedef struct {
+	pcidev_t  pdev;
 	ncr_slot  slot;
 	ncr_chip  chip;
 	ncr_nvram *nvram;
@@ -1796,6 +2144,8 @@
 	**----------------------------------------------------------------
 	*/
 	Scsi_Cmnd	*cmd;		/* SCSI command 		*/
+	u_char		cdb_buf[16];	/* Copy of CDB			*/
+	u_char		sense_buf[64];
 	int		data_len;	/* Total data length		*/
 	int		segments;	/* Number of SG segments	*/
 
@@ -1964,6 +2314,7 @@
 	**	General controller parameters and configuration.
 	**----------------------------------------------------------------
 	*/
+	pcidev_t	pdev;
 	u_short		device_id;	/* PCI device id		*/
 	u_char		revision_id;	/* PCI device revision id	*/
 	u_char		bus;		/* PCI BUS number		*/
@@ -1995,7 +2346,8 @@
 	**	SCRIPTS processor in order to start SCSI commands.
 	**----------------------------------------------------------------
 	*/
-	u_int32		*squeue;	/* Start queue			*/
+	u_long		p_squeue;	/* Start queue BUS address	*/
+	u_int32		*squeue;	/* Start queue virtual address	*/
 	u_short		squeueput;	/* Next free slot of the queue	*/
 	u_short		actccbs;	/* Number of allocated CCBs	*/
 	u_short		queuedepth;	/* Start queue depth		*/
@@ -2045,6 +2397,7 @@
 	u_char		order;		/* Tag order to use		*/
 	u_char		verbose;	/* Verbosity for this controller*/
 	u_int32		ncr_cache;	/* Used for cache test at init.	*/
+	u_long		p_ncb;		/* BUS address of this NCB	*/
 
 	/*----------------------------------------------------------------
 	**	CCB lists and queue.
@@ -2085,7 +2438,7 @@
 	**	We use a different scatter function for 896 rev 1.
 	**----------------------------------------------------------------
 	*/
-	int (*scatter) (ccb_p, Scsi_Cmnd *);
+	int (*scatter) (ncb_p, ccb_p, Scsi_Cmnd *);
 
 	/*----------------------------------------------------------------
 	**	Command abort handling.
@@ -2106,6 +2459,7 @@
 	u_char		release_stage;	/* Synchronisation stage on release  */
 };
 
+#define NCB_PHYS(np, lbl)	 (np->p_ncb + offsetof(struct ncb, lbl))
 #define NCB_SCRIPT_PHYS(np,lbl)	 (np->p_script  + offsetof (struct script, lbl))
 #define NCB_SCRIPTH_PHYS(np,lbl) (np->p_scripth + offsetof (struct scripth,lbl))
 #define NCB_SCRIPTH0_PHYS(np,lbl) (np->p_scripth0+offsetof (struct scripth,lbl))
@@ -2336,8 +2690,8 @@
 static	void	ncr_script_copy_and_bind
 				(ncb_p np, ncrcmd *src, ncrcmd *dst, int len);
 static  void    ncr_script_fill (struct script * scr, struct scripth * scripth);
-static	int	ncr_scatter_896R1 (ccb_p cp, Scsi_Cmnd *cmd);
-static	int	ncr_scatter	(ccb_p cp, Scsi_Cmnd *cmd);
+static	int	ncr_scatter_896R1 (ncb_p np, ccb_p cp, Scsi_Cmnd *cmd);
+static	int	ncr_scatter	(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd);
 static	void	ncr_getsync	(ncb_p np, u_char sfac, u_char *fakp, u_char *scntl3p);
 static	void	ncr_setsync	(ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer);
 static	void	ncr_setup_tags	(ncb_p np, u_char tn, u_char ln);
@@ -4529,7 +4883,7 @@
 				new = (old & ~RELOC_MASK) + np->p_scripth;
 				break;
 			case RELOC_SOFTC:
-				new = (old & ~RELOC_MASK) + vtobus(np);
+				new = (old & ~RELOC_MASK) + np->p_ncb;
 				break;
 #ifdef	RELOC_KVAR
 			case RELOC_KVAR:
@@ -5191,10 +5545,12 @@
 	/*
 	**	Allocate the host control block.
 	*/
-	np = m_calloc(sizeof(struct ncb), "NCB", MEMO_WARN);
+	np = __m_calloc_dma(device->pdev, sizeof(struct ncb), "NCB");
 	if (!np)
 		goto attach_error;
 	NCR_INIT_LOCK_NCB(np);
+	np->pdev  = device->pdev;
+	np->p_ncb = __vtobus(device->pdev, np);
 	host_data->ncb = np;
 
 	/*
@@ -5218,22 +5574,23 @@
 	**	Allocate the start queue.
 	*/
 	np->squeue = (ncrcmd *)
-		m_calloc(sizeof(ncrcmd)*(MAX_START*2), "SQUEUE", MEMO_WARN);
+		m_calloc_dma(sizeof(ncrcmd)*(MAX_START*2), "SQUEUE");
 	if (!np->squeue)
 		goto attach_error;
+	np->p_squeue = vtobus(np->squeue);
 
 	/*
 	**	Allocate the done queue.
 	*/
 	np->dqueue = (ncrcmd *)
-		m_calloc(sizeof(ncrcmd)*(MAX_START*2), "DQUEUE", MEMO_WARN);
+		m_calloc_dma(sizeof(ncrcmd)*(MAX_START*2), "DQUEUE");
 	if (!np->dqueue)
 		goto attach_error;
 
 	/*
 	**	Allocate the target bus address array.
 	*/
-	np->targtbl = (u_int32 *) m_calloc(256, "TARGTBL", MEMO_WARN);
+	np->targtbl = (u_int32 *) m_calloc_dma(256, "TARGTBL");
 	if (!np->targtbl)
 		goto attach_error;
 
@@ -5241,11 +5598,11 @@
 	**	Allocate SCRIPTS areas
 	*/
 	np->script0	= (struct script *) 
-		m_calloc(sizeof(struct script),  "SCRIPT",  MEMO_WARN);
+		m_calloc_dma(sizeof(struct script),  "SCRIPT");
 	if (!np->script0)
 		goto attach_error;
 	np->scripth0	= (struct scripth *)
-		m_calloc(sizeof(struct scripth), "SCRIPTH", MEMO_WARN);
+		m_calloc_dma(sizeof(struct scripth), "SCRIPTH");
 	if (!np->scripth0)
 		goto attach_error;
 
@@ -5457,24 +5814,24 @@
 	*/
 	np->idletask.start	= cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
 	np->idletask.restart	= cpu_to_scr(NCB_SCRIPTH_PHYS (np, bad_i_t_l));
-	np->p_idletask		= vtobus(&np->idletask);
+	np->p_idletask		= NCB_PHYS(np, idletask);
 
 	np->notask.start	= cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
 	np->notask.restart	= cpu_to_scr(NCB_SCRIPTH_PHYS (np, bad_i_t_l));
-	np->p_notask		= vtobus(&np->notask);
+	np->p_notask		= NCB_PHYS(np, notask);
 
 	np->bad_i_t_l.start	= cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
 	np->bad_i_t_l.restart	= cpu_to_scr(NCB_SCRIPTH_PHYS (np, bad_i_t_l));
-	np->p_bad_i_t_l		= vtobus(&np->bad_i_t_l);
+	np->p_bad_i_t_l		= NCB_PHYS(np, bad_i_t_l);
 
 	np->bad_i_t_l_q.start	= cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
 	np->bad_i_t_l_q.restart	= cpu_to_scr(NCB_SCRIPTH_PHYS (np,bad_i_t_l_q));
-	np->p_bad_i_t_l_q	= vtobus(&np->bad_i_t_l_q);
+	np->p_bad_i_t_l_q	= NCB_PHYS(np, bad_i_t_l_q);
 
 	/*
 	**	Allocate and prepare the bad lun table.
 	*/
-	np->badluntbl = m_calloc(256, "BADLUNTBL", MEMO_WARN);
+	np->badluntbl = m_calloc_dma(256, "BADLUNTBL");
 	if (!np->badluntbl)
 		goto attach_error;
 
@@ -5482,16 +5839,16 @@
 	np->resel_badlun = cpu_to_scr(NCB_SCRIPTH_PHYS(np, bad_identify));
 
 	for (i = 0 ; i < 64 ; i++)
-		np->badluntbl[i] = cpu_to_scr(vtobus(&np->resel_badlun));
+		np->badluntbl[i] = cpu_to_scr(NCB_PHYS(np, resel_badlun));
 
 	/*
 	**	Prepare the target bus address array.
 	*/
 	np->scripth0->targtbl[0] = cpu_to_scr(vtobus(np->targtbl));
 	for (i = 0 ; i < MAX_TARGET ; i++) {
-		np->targtbl[i] = cpu_to_scr(vtobus(&np->target[i]));
+		np->targtbl[i] = cpu_to_scr(NCB_PHYS(np, target[i]));
 		np->target[i].b_luntbl = cpu_to_scr(vtobus(np->badluntbl));
-		np->target[i].b_lun0   = cpu_to_scr(vtobus(&np->resel_badlun));
+		np->target[i].b_lun0   = cpu_to_scr(NCB_PHYS(np, resel_badlun));
 	}
 
 	/*
@@ -5533,7 +5890,7 @@
 #ifndef SCSI_NCR_PROFILE_SUPPORT
 #define XXX	0
 #else
-#define XXX	3
+#define XXX	2
 #endif
 		np->script0->dataphase[XXX] = cpu_to_scr(SCR_JUMP);
 		np->script0->dataphase[XXX+1] = 
@@ -5699,21 +6056,21 @@
 		unmap_pci_mem(np->base2_va, np->base2_ws);
 #endif
 	if (np->scripth0)
-		m_free(np->scripth0, sizeof(struct scripth), "SCRIPTH");
+		m_free_dma(np->scripth0, sizeof(struct scripth), "SCRIPTH");
 	if (np->script0)
-		m_free(np->script0, sizeof(struct script), "SCRIPT");
+		m_free_dma(np->script0, sizeof(struct script), "SCRIPT");
 	if (np->squeue)
-		m_free(np->squeue, sizeof(ncrcmd)*(MAX_START*2), "SQUEUE");
+		m_free_dma(np->squeue, sizeof(ncrcmd)*(MAX_START*2), "SQUEUE");
 	if (np->dqueue)
-		m_free(np->dqueue, sizeof(ncrcmd)*(MAX_START*2),"DQUEUE");
+		m_free_dma(np->dqueue, sizeof(ncrcmd)*(MAX_START*2),"DQUEUE");
 
 	while ((cp = np->ccbc) != NULL) {
 		np->ccbc = cp->link_ccb;
-		m_free(cp, sizeof(*cp), "CCB");
+		m_free_dma(cp, sizeof(*cp), "CCB");
 	}
 
 	if (np->badluntbl)
-		m_free(np->badluntbl, 256,"BADLUNTBL");
+		m_free_dma(np->badluntbl, 256,"BADLUNTBL");
 
 	for (target = 0; target < MAX_TARGET ; target++) {
 		tp = &np->target[target];
@@ -5722,18 +6079,23 @@
 			if (!lp)
 				continue;
 			if (lp->tasktbl != &lp->tasktbl_0)
-				m_free(lp->tasktbl, MAX_TASKS*4, "TASKTBL");
+				m_free_dma(lp->tasktbl, MAX_TASKS*4, "TASKTBL");
 			if (lp->cb_tags)
 				m_free(lp->cb_tags, MAX_TAGS, "CB_TAGS");
-			m_free(lp, sizeof(*lp), "LCB");
+			m_free_dma(lp, sizeof(*lp), "LCB");
 		}
 #if MAX_LUN > 1
 		if (tp->lmp)
 			m_free(tp->lmp, MAX_LUN * sizeof(lcb_p), "LMP");
+		if (tp->luntbl)
+			m_free_dma(tp->luntbl, 256, "LUNTBL");
 #endif 
 	}
 
-	m_free(np, sizeof(*np), "NCB");
+	if (np->targtbl)
+		m_free_dma(np->targtbl, 256, "TARGTBL");
+
+	m_free_dma(np, sizeof(*np), "NCB");
 }
 
 
@@ -5761,13 +6123,14 @@
 	np->done_list = cmd;
 }
 
-static inline void ncr_flush_done_cmds(Scsi_Cmnd *lcmd)
+static inline void ncr_flush_done_cmds(pcidev_t pdev, Scsi_Cmnd *lcmd)
 {
 	Scsi_Cmnd *cmd;
 
 	while (lcmd) {
 		cmd = lcmd;
 		lcmd = (Scsi_Cmnd *) cmd->host_scribble;
+		__unmap_scsi_data(pdev, cmd);
 		cmd->scsi_done(cmd);
 	}
 }
@@ -6013,7 +6376,7 @@
 	**----------------------------------------------------
 	*/
 
-	cp->segments = segments = np->scatter (cp, cp->cmd);
+	cp->segments = segments = np->scatter (np, cp, cp->cmd);
 
 	if (segments < 0) {
 		ncr_free_ccb(np, cp);
@@ -6027,61 +6390,34 @@
 	**----------------------------------------------------
 	*/
 	if (!cp->data_len)
-		direction = 0;
-	else {
-		switch((int) cmd->cmnd[0]) {
-		case 0x08:  /*	READ(6)				08 */
-		case 0x28:  /*	READ(10)			28 */
-		case 0xA8:  /*	READ(12)			A8 */
-			direction = XFER_IN;
-			break;
-		case 0x0A:  /*	WRITE(6)			0A */
-		case 0x2A:  /*	WRITE(10)			2A */
-		case 0xAA:  /*	WRITE(12)			AA */
-			direction = XFER_OUT;
-			break;
-		default:
-			direction = (XFER_IN|XFER_OUT);
-			break;
-		}
-	}
-
-	/*----------------------------------------------------
-	**
-	**	Set the DATA POINTER.
-	**
-	**----------------------------------------------------
-	*/
-
-	/*
-	**	Default to no data transfer.
-	*/
-	lastp = goalp = NCB_SCRIPTH_PHYS (np, no_data);
+		direction = SCSI_DATA_NONE;
+	else
+		direction = scsi_data_direction(cmd);
 
 	/*
-	**	Compute data out pointers, if needed.
+	**	If data direction is UNKNOWN, speculate DATA_READ 
+	**	but prepare alternate pointers for WRITE in case 
+	**	of our speculation will be just wrong.
+	**	SCRIPTS will swap values if needed.
 	*/
-	if (direction & XFER_OUT) {
+	switch(direction) {
+	case SCSI_DATA_UNKNOWN:
+	case SCSI_DATA_WRITE:
 		goalp = NCB_SCRIPT_PHYS (np, data_out2) + 8;
 		lastp = goalp - 8 - (segments * (SCR_SG_SIZE*4));
-
-		/*
-		**	If actual data direction is unknown, save pointers 
-		**	in header. The SCRIPTS will swap them to current 
-		**	if target decision will be data out.
-		*/
-		if (direction & XFER_IN) {
-			cp->phys.header.wgoalp	= cpu_to_scr(goalp);
-			cp->phys.header.wlastp	= cpu_to_scr(lastp);
-		}
-	}
-
-	/*
-	**	Compute data in pointers, if needed.
-	*/
-	if (direction & XFER_IN) {
+		if (direction != SCSI_DATA_UNKNOWN)
+			break;
+		cp->phys.header.wgoalp	= cpu_to_scr(goalp);
+		cp->phys.header.wlastp	= cpu_to_scr(lastp);
+		/* fall through */
+	case SCSI_DATA_READ:
 		goalp = NCB_SCRIPT_PHYS (np, data_in2) + 8;
 		lastp = goalp - 8 - (segments * (SCR_SG_SIZE*4));
+		break;
+	default:
+	case SCSI_DATA_NONE:
+		lastp = goalp = NCB_SCRIPTH_PHYS (np, no_data);
+		break;
 	}
 
 	/*
@@ -6091,7 +6427,7 @@
 	cp->phys.header.lastp = cpu_to_scr(lastp);
 	cp->phys.header.goalp = cpu_to_scr(goalp);
 
-	if ((direction & (XFER_IN|XFER_OUT)) == (XFER_IN|XFER_OUT))
+	if (direction == SCSI_DATA_UNKNOWN)
 		cp->phys.header.savep = 
 			cpu_to_scr(NCB_SCRIPTH_PHYS (np, data_io));
 	else
@@ -6152,7 +6488,8 @@
 	/*
 	**	command
 	*/
-	cp->phys.cmd.addr	= cpu_to_scr(vtobus (&cmd->cmnd[0]));
+	memcpy(cp->cdb_buf, cmd->cmnd, cmd->cmd_len);
+	cp->phys.cmd.addr	= cpu_to_scr(CCB_PHYS (cp, cdb_buf[0]));
 	cp->phys.cmd.size	= cpu_to_scr(cmd->cmd_len);
 
 	/*
@@ -6719,6 +7056,7 @@
 		*/
 		if (cmd->cmnd[0] == 0x12 && !(cmd->cmnd[1] & 0x3) &&
 		    cmd->cmnd[4] >= 7 && !cmd->use_sg) {
+			sync_scsi_data(np, cmd);	/* SYNC the data */
 			ncr_setup_lcb (np, cp->target, cp->lun,
 				       (char *) cmd->request_buffer);
 		}
@@ -6941,7 +7279,7 @@
 	/*
 	**	Clear Start Queue
 	*/
-	phys = vtobus(np->squeue);
+	phys = np->p_squeue;
 	np->queuedepth = MAX_START - 1;	/* 1 entry needed as end marker */
 	for (i = 0; i < MAX_START*2; i += 2) {
 		np->squeue[i]   = cpu_to_scr(np->p_idletask);
@@ -7131,7 +7469,7 @@
 
 	np->istat_sem = 0;
 
-	OUTL (nc_dsa, vtobus(np));
+	OUTL (nc_dsa, np->p_ncb);
 	OUTL (nc_dsp, phys);
 }
 
@@ -8733,7 +9071,7 @@
 	**	them back in the LUN CCB wait queue.
 	*/
 	busyccbs = lp->queuedccbs;
-	i = (INL (nc_scratcha) - vtobus(np->squeue)) / 4;
+	i = (INL (nc_scratcha) - np->p_squeue) / 4;
 	j = i;
 	while (i != np->squeueput) {
 		cp2 = ncr_ccb_from_dsa(np, scr_to_cpu(np->squeue[i]));
@@ -8888,11 +9226,9 @@
 		/*
 		**	sense data
 		*/
-		bzero(cmd->sense_buffer, sizeof(cmd->sense_buffer));
-		cp->phys.sense.addr	=
-				cpu_to_scr(vtobus (&cmd->sense_buffer[0]));
-		cp->phys.sense.size	=
-				cpu_to_scr(sizeof(cmd->sense_buffer));
+		bzero(cp->sense_buf, sizeof(cp->sense_buf));
+		cp->phys.sense.addr	= cpu_to_scr(CCB_PHYS(cp,sense_buf[0]));
+		cp->phys.sense.size	= cpu_to_scr(sizeof(cp->sense_buf));
 
 		/*
 		**	requeue the command.
@@ -9073,7 +9409,7 @@
 			np->abrt_sel.sel_id	= target;
 			np->abrt_sel.sel_scntl3 = tp->wval;
 			np->abrt_sel.sel_sxfer  = tp->sval;
-			OUTL(nc_dsa, vtobus(np));
+			OUTL(nc_dsa, np->p_ncb);
 			OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, sel_for_abort));
 			return;
 		}
@@ -9114,7 +9450,7 @@
 			**	Compute index of next position in the start 
 			**	queue the SCRIPTS will schedule.
 			*/
-			i = (INL (nc_scratcha) - vtobus(np->squeue)) / 4;
+			i = (INL (nc_scratcha) - np->p_squeue) / 4;
 
 			/*
 			**	Remove the job from the start queue.
@@ -9315,11 +9651,17 @@
 	*/
 	case SIR_AUTO_SENSE_DONE:
 		cp = ncr_ccb_from_dsa(np, INL (nc_dsa));
+		if (!cp)
+			break;
+		memcpy(cp->cmd->sense_buffer, cp->sense_buf,
+		       sizeof(cp->cmd->sense_buffer));
 		p  = &cp->cmd->sense_buffer[0];
 
 		if (p[0] != 0x70 || p[2] != 0x6 || p[12] != 0x29)
 			break;
+#if 0
 		(void) ncr_clear_tasks(np, HS_RESET, cp->target, cp->lun, -1);
+#endif
 		break;
 	}
 
@@ -10036,6 +10378,7 @@
 	case SIR_SCRIPT_STOPPED:
 	case SIR_TARGET_SELECTED:
 	case SIR_ABORT_SENT:
+	case SIR_AUTO_SENSE_DONE:
 		ncr_sir_task_recovery(np, num);
 		return;
 	/*
@@ -10397,7 +10740,7 @@
 	/*
 	**	Allocate memory for this CCB.
 	*/
-	cp = m_calloc(sizeof(struct ccb), "CCB", MEMO_WARN);
+	cp = m_calloc_dma(sizeof(struct ccb), "CCB");
 	if (!cp)
 		return 0;
 
@@ -10427,7 +10770,7 @@
 	/*
 	**	Initilialyze some other fields.
 	*/
-	cp->phys.smsg_ext.addr = cpu_to_scr(vtobus(&np->msgin[2]));
+	cp->phys.smsg_ext.addr = cpu_to_scr(NCB_PHYS(np, msgin[2]));
 
 	/*
 	**	Chain into wakeup list and free ccb queue.
@@ -10519,11 +10862,11 @@
 	if (ln && !tp->luntbl) {
 		int i;
 
-		tp->luntbl = m_calloc(256, "LUNTBL", MEMO_WARN);
+		tp->luntbl = m_calloc_dma(256, "LUNTBL");
 		if (!tp->luntbl)
 			goto fail;
 		for (i = 0 ; i < 64 ; i++)
-			tp->luntbl[i] = cpu_to_scr(vtobus(&np->resel_badlun));
+			tp->luntbl[i] = cpu_to_scr(NCB_PHYS(np, resel_badlun));
 		tp->b_luntbl = cpu_to_scr(vtobus(tp->luntbl));
 	}
 
@@ -10531,7 +10874,7 @@
 	**	Allocate the table of pointers for LUN(s) > 0, if needed.
 	*/
 	if (ln && !tp->lmp) {
-		tp->lmp = m_calloc(MAX_LUN * sizeof(lcb_p), "LMP", MEMO_WARN);
+		tp->lmp = m_calloc(MAX_LUN * sizeof(lcb_p), "LMP");
 		if (!tp->lmp)
 			goto fail;
 	}
@@ -10540,7 +10883,7 @@
 	**	Allocate the lcb.
 	**	Make it available to the chip.
 	*/
-	lp = m_calloc(sizeof(struct lcb), "LCB", MEMO_WARN);
+	lp = m_calloc_dma(sizeof(struct lcb), "LCB");
 	if (!lp)
 		goto fail;
 	if (ln) {
@@ -10652,7 +10995,7 @@
 	**	initialyze the task table if not yet.
 	*/
 	if ((inq_byte7 & INQ7_QUEUE) && lp->tasktbl == &lp->tasktbl_0) {
-		lp->tasktbl = m_calloc(MAX_TASKS*4, "TASKTBL", MEMO_WARN);
+		lp->tasktbl = m_calloc_dma(MAX_TASKS*4, "TASKTBL");
 		if (!lp->tasktbl) {
 			lp->tasktbl = &lp->tasktbl_0;
 			goto fail;
@@ -10661,7 +11004,7 @@
 		for (i = 0 ; i < MAX_TASKS ; i++)
 			lp->tasktbl[i] = cpu_to_scr(np->p_notask);
 
-		lp->cb_tags = m_calloc(MAX_TAGS, "CB_TAGS", MEMO_WARN);
+		lp->cb_tags = m_calloc(MAX_TAGS, "CB_TAGS");
 		if (!lp->cb_tags)
 			goto fail;
 		for (i = 0 ; i < MAX_TAGS ; i++)
@@ -10741,7 +11084,7 @@
 
 #define CROSS_16MB(p, n) (((((u_long) p) + n - 1) ^ ((u_long) p)) & ~0xffffff)
 
-static	int ncr_scatter_no_sglist(ccb_p cp, Scsi_Cmnd *cmd)
+static	int ncr_scatter_no_sglist(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd)
 {
 	struct scr_tblmove *data = &cp->phys.data[MAX_SCATTER-1];
 	int segment;
@@ -10749,7 +11092,8 @@
 	cp->data_len = cmd->request_bufflen;
 
 	if (cmd->request_bufflen) {
-		u_long baddr = vtobus(cmd->request_buffer);
+		u_long baddr = map_scsi_single_data(np, cmd);
+
 		SCATTER_ONE(data, baddr, cmd->request_bufflen);
 		if (CROSS_16MB(baddr, cmd->request_bufflen)) {
 			cp->host_flags |= HF_PM_TO_C;
@@ -10780,7 +11124,7 @@
 **	nicely power-of-two sized and aligned. But, since this may change 
 **	at any time, a work-around was required.
 */
-static int ncr_scatter_896R1(ccb_p cp, Scsi_Cmnd *cmd)
+static int ncr_scatter_896R1(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd)
 {
 	int segn;
 	int use_sg = (int) cmd->use_sg;
@@ -10788,18 +11132,23 @@
 	cp->data_len = 0;
 
 	if (!use_sg)
-		segn = ncr_scatter_no_sglist(cp, cmd);
+		segn = ncr_scatter_no_sglist(np, cp, cmd);
 	else if (use_sg > MAX_SCATTER)
 		segn = -1;
 	else {
 		struct scatterlist *scatter = (struct scatterlist *)cmd->buffer;
-		struct scr_tblmove *data = &cp->phys.data[MAX_SCATTER - use_sg];
+		struct scr_tblmove *data;
+
+		use_sg = map_scsi_sg_data(np, cmd);
+		data = &cp->phys.data[MAX_SCATTER - use_sg];
 
 		for (segn = 0; segn < use_sg; segn++) {
-			u_long baddr = vtobus(scatter[segn].address);
+			u_long baddr = scsi_sg_dma_address(&scatter[segn]);
+			unsigned int len = scsi_sg_dma_len(&scatter[segn]);
+
 			SCATTER_ONE(&data[segn],
 				    baddr,
-				    scatter[segn].length);
+				    len);
 			if (CROSS_16MB(baddr, scatter[segn].length)) {
 				cp->host_flags |= HF_PM_TO_C;
 #ifdef DEBUG_896R1
@@ -10807,14 +11156,14 @@
 	baddr, scatter[segn].length);
 #endif
 			}
-			cp->data_len += scatter[segn].length;
+			cp->data_len += len;
 		}
 	}
 
 	return segn;
 }
 
-static int ncr_scatter(ccb_p cp, Scsi_Cmnd *cmd)
+static int ncr_scatter(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd)
 {
 	int segment;
 	int use_sg = (int) cmd->use_sg;
@@ -10822,19 +11171,24 @@
 	cp->data_len = 0;
 
 	if (!use_sg)
-		segment = ncr_scatter_no_sglist(cp, cmd);
+		segment = ncr_scatter_no_sglist(np, cp, cmd);
 	else if (use_sg > MAX_SCATTER)
 		segment = -1;
 	else {
 		struct scatterlist *scatter = (struct scatterlist *)cmd->buffer;
-		struct scr_tblmove *data = &cp->phys.data[MAX_SCATTER - use_sg];
+		struct scr_tblmove *data;
+
+		use_sg = map_scsi_sg_data(np, cmd);
+		data = &cp->phys.data[MAX_SCATTER - use_sg];
 
 		for (segment = 0; segment < use_sg; segment++) {
-			u_long baddr = vtobus(scatter[segment].address);
+			u_long baddr = scsi_sg_dma_address(&scatter[segment]);
+			unsigned int len = scsi_sg_dma_len(&scatter[segment]);
+
 			SCATTER_ONE(&data[segment],
 				    baddr,
-				    scatter[segment].length);
-			cp->data_len += scatter[segment].length;
+				    len);
+			cp->data_len += len;
 		}
 	}
 
@@ -10901,7 +11255,7 @@
 	/*
 	**	Start script (exchange values)
 	*/
-	OUTL (nc_dsa, vtobus(np));
+	OUTL (nc_dsa, np->p_ncb);
 	OUTL (nc_dsp, pc);
 	/*
 	**	Wait 'til done (with timeout)
@@ -11580,7 +11934,7 @@
 	**	overflow the kernel stack.
 	**	1 x 4K PAGE is enough for more than 40 devices for i386.
 	*/
-	devtbl = m_calloc(PAGE_SIZE, "devtbl", MEMO_WARN);
+	devtbl = m_calloc(PAGE_SIZE, "devtbl");
 	if (!devtbl)
 		return 0;
 
@@ -11745,6 +12099,15 @@
 		PciBusNumber(pdev),
 		(int) (PciDeviceFn(pdev) & 0xf8) >> 3,
 		(int) (PciDeviceFn(pdev) & 7));
+
+#ifdef SCSI_NCR_DYNAMIC_DMA_MAPPING
+	if (!pci_dma_supported(pdev, (dma_addr_t) (0xffffffffUL))) {
+		printk(KERN_WARNING NAME53C8XX
+		       "32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
+		return -1;
+	}
+#endif
+
 	/*
 	**    Read info from the PCI config space.
 	**    pci_read_config_xxx() functions are assumed to be used for 
@@ -12032,6 +12395,7 @@
  	/*
 	**    Initialise ncr_device structure with items required by ncr_attach.
 	*/
+	device->pdev		= pdev;
 	device->slot.bus	= PciBusNumber(pdev);
 	device->slot.device_fn	= PciDeviceFn(pdev);
 	device->slot.base	= base;
@@ -12232,6 +12596,10 @@
      cmd->host_scribble = NULL;
      cmd->SCp.ptr       = NULL;
      cmd->SCp.buffer    = NULL;
+#ifdef SCSI_NCR_DYNAMIC_DMA_MAPPING
+     cmd->__data_mapped = 0;
+     cmd->__data_mapping = 0;
+#endif
 
      NCR_LOCK_NCB(np, flags);
 
@@ -12267,6 +12635,7 @@
      unsigned long flags;
      ncb_p np = (ncb_p) dev_id;
      Scsi_Cmnd *done_list;
+     pcidev_t pdev;
 
 #ifdef DEBUG_SYM53C8XX
      printk("sym53c8xx : interrupt received\n");
@@ -12276,6 +12645,7 @@
 
      NCR_LOCK_NCB(np, flags);
      ncr_exception(np);
+     pdev = np->pdev;
      done_list     = np->done_list;
      np->done_list = 0;
      NCR_UNLOCK_NCB(np, flags);
@@ -12284,7 +12654,7 @@
 
      if (done_list) {
           NCR_LOCK_SCSI_DONE(np, flags);
-          ncr_flush_done_cmds(done_list);
+          ncr_flush_done_cmds(pdev, done_list);
           NCR_UNLOCK_SCSI_DONE(np, flags);
      }
 }
@@ -12297,17 +12667,19 @@
 {
      ncb_p np = (ncb_p) npref;
      unsigned long flags;
+     pcidev_t pdev;
      Scsi_Cmnd *done_list;
 
      NCR_LOCK_NCB(np, flags);
      ncr_timeout((ncb_p) np);
+     pdev = np->pdev;
      done_list     = np->done_list;
      np->done_list = 0;
      NCR_UNLOCK_NCB(np, flags);
 
      if (done_list) {
           NCR_LOCK_SCSI_DONE(np, flags);
-          ncr_flush_done_cmds(done_list);
+          ncr_flush_done_cmds(pdev, done_list);
           NCR_UNLOCK_SCSI_DONE(np, flags);
      }
 }
@@ -12325,6 +12697,7 @@
 	ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
 	int sts;
 	unsigned long flags;
+	pcidev_t pdev;
 	Scsi_Cmnd *done_list;
 
 #if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
@@ -12369,11 +12742,12 @@
 #endif
 
 out:
+	pdev = np->pdev;
 	done_list     = np->done_list;
 	np->done_list = 0;
 	NCR_UNLOCK_NCB(np, flags);
 
-	ncr_flush_done_cmds(done_list);
+	ncr_flush_done_cmds(pdev, done_list);
 
 	return sts;
 }
@@ -12387,6 +12761,7 @@
 	ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
 	int sts;
 	unsigned long flags;
+	pcidev_t pdev;
 	Scsi_Cmnd *done_list;
 
 #if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
@@ -12410,11 +12785,12 @@
 
 	sts = ncr_abort_command(np, cmd);
 out:
+	pdev = np->pdev;
 	done_list     = np->done_list;
 	np->done_list = 0;
 	NCR_UNLOCK_NCB(np, flags);
 
-	ncr_flush_done_cmds(done_list);
+	ncr_flush_done_cmds(pdev, done_list);
 
 	return sts;
 }
diff -u --recursive --new-file v2.3.47/linux/drivers/scsi/wd33c93.h linux/drivers/scsi/wd33c93.h
--- v2.3.47/linux/drivers/scsi/wd33c93.h	Tue Nov 23 22:42:21 1999
+++ linux/drivers/scsi/wd33c93.h	Thu Feb 24 22:51:47 2000
@@ -191,7 +191,7 @@
 typedef struct {
    volatile unsigned char   SASR;
    char                     pad;
-#ifdef CONFIG_SGI
+#ifdef CONFIG_SGI_IP22
    char                     pad2,pad3;
 #endif
    volatile unsigned char   SCMD;
diff -u --recursive --new-file v2.3.47/linux/drivers/sgi/Config.in linux/drivers/sgi/Config.in
--- v2.3.47/linux/drivers/sgi/Config.in	Fri Oct 15 15:25:14 1999
+++ linux/drivers/sgi/Config.in	Thu Feb 24 22:51:08 2000
@@ -5,14 +5,10 @@
 comment 'SGI devices'
 
 bool 'SGI Zilog85C30 serial support' CONFIG_SGI_SERIAL
-if [ "$CONFIG_SGI_SERIAL" != "n" ]; then
-   define_bool CONFIG_SERIAL y
-fi
-
 bool 'SGI DS1286  RTC support' CONFIG_SGI_DS1286
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then  
-   tristate 'SGI Newport Graphics support (EXPERIMENTAL)' CONFIG_SGI_NEWPORT_GFX
+   tristate 'SGI Newport Graphics support' CONFIG_SGI_NEWPORT_GFX
 fi
 
 endmenu
diff -u --recursive --new-file v2.3.47/linux/drivers/sgi/char/ds1286.c linux/drivers/sgi/char/ds1286.c
--- v2.3.47/linux/drivers/sgi/char/ds1286.c	Thu Feb 10 17:11:13 2000
+++ linux/drivers/sgi/char/ds1286.c	Thu Feb 24 22:51:08 2000
@@ -1,4 +1,4 @@
-/* $Id: ds1286.c,v 1.4 1999/06/17 13:29:03 ralf Exp $
+/* $Id: ds1286.c,v 1.7 2000/02/23 00:41:21 ralf Exp $
  *
  *	Real Time Clock interface for Linux	
  *
@@ -73,9 +73,7 @@
 
 static inline unsigned char ds1286_is_updating(void);
 
-#ifdef __SMP__
 static spinlock_t ds1286_lock = SPIN_LOCK_UNLOCKED;
-#endif
 
 /*
  *	Bits in rtc_status. (7 bits of room for future expansion)
diff -u --recursive --new-file v2.3.47/linux/drivers/sgi/char/graphics.c linux/drivers/sgi/char/graphics.c
--- v2.3.47/linux/drivers/sgi/char/graphics.c	Thu Feb 10 17:11:13 2000
+++ linux/drivers/sgi/char/graphics.c	Thu Feb 24 22:51:08 2000
@@ -1,4 +1,4 @@
-/* $Id: graphics.c,v 1.16 1999/04/01 23:45:00 ulfc Exp $
+/* $Id: graphics.c,v 1.23 2000/02/23 00:41:21 ralf Exp $
  *
  * gfx.c: support for SGI's /dev/graphics, /dev/opengl
  *
@@ -41,7 +41,7 @@
 #include <asm/rrm.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <asm/newport.h>
+#include <video/newport.h>
 
 #define DEBUG
 
diff -u --recursive --new-file v2.3.47/linux/drivers/sgi/char/graphics_syms.c linux/drivers/sgi/char/graphics_syms.c
--- v2.3.47/linux/drivers/sgi/char/graphics_syms.c	Wed Jun 30 11:24:54 1999
+++ linux/drivers/sgi/char/graphics_syms.c	Thu Feb 24 22:51:08 2000
@@ -8,6 +8,7 @@
  */
 
 #define __NO_VERSION__
+#include <linux/config.h>
 #include <linux/module.h>
 
 /* extern int rrm_command (unsigned int cmd, void *arg);
@@ -32,5 +33,4 @@
 EXPORT_SYMBOL(enable_gconsole);
 EXPORT_SYMBOL(remove_mapping);
 
-
-
+EXPORT_SYMBOL(npregs);
diff -u --recursive --new-file v2.3.47/linux/drivers/sgi/char/newport.c linux/drivers/sgi/char/newport.c
--- v2.3.47/linux/drivers/sgi/char/newport.c	Wed Jun 30 11:24:55 1999
+++ linux/drivers/sgi/char/newport.c	Thu Feb 24 22:51:08 2000
@@ -11,13 +11,12 @@
 #include <asm/gfx.h>
 #include <asm/ng1.h>
 #include <asm/uaccess.h>
-#include <asm/newport.h>
+#include <video/newport.h>
+#include <linux/config.h>
 #include <linux/module.h>
 
 struct newport_regs *npregs;
 
-EXPORT_SYMBOL(npregs);
-
 /* Kernel routines for supporting graphics context switching */
 
 void newport_save (void *y)
@@ -26,7 +25,7 @@
 	newport_wait ();
 
 #define LOAD(val) x->val = npregs->set.val;
-#define LOADI(val) x->val = npregs->set.val.i;
+#define LOADI(val) x->val = npregs->set.val.word;
 #define LOADC(val) x->val = npregs->cset.val;
 	
 	LOAD(drawmode1);
@@ -89,7 +88,7 @@
 	newport_bfwait ();
 	LOAD (dcbmode);
 	newport_bfwait ();
-	x->dcbdata0 = npregs->set.dcbdata0.all;
+	x->dcbdata0 = npregs->set.dcbdata0.byword;
 	newport_bfwait ();
 	LOAD(dcbdata1);
 }
@@ -109,7 +108,7 @@
 {
 	newport_ctx *x = y;
 #define STORE(val) npregs->set.val = x->val
-#define STOREI(val) npregs->set.val.i = x->val
+#define STOREI(val) npregs->set.val.word = x->val
 #define STOREC(val) npregs->cset.val = x->val
 	newport_wait ();
 	
diff -u --recursive --new-file v2.3.47/linux/drivers/sgi/char/sgiserial.c linux/drivers/sgi/char/sgiserial.c
--- v2.3.47/linux/drivers/sgi/char/sgiserial.c	Fri Oct 22 13:21:50 1999
+++ linux/drivers/sgi/char/sgiserial.c	Thu Feb 24 22:51:08 2000
@@ -1,7 +1,18 @@
 /* sgiserial.c: Serial port driver for SGI machines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
+ */
+
+/*
+ * Note: This driver seems to have been derived from some
+ * version of the sbus/char/zs.c driver.  A lot of clean-up
+ * and bug fixes seem to have happened to the Sun driver in
+ * the intervening time.  As of 21.09.1999, I have merged in
+ * ONLY the changes necessary to fix observed functional
+ * problems on the Indy.  Someone really ought to do a
+ * thorough pass to merge in the rest of the updates.
+ * Better still, someone really ought to make it a common
+ * code module for both platforms.   kevink@mips.com
  */
 
 #include <linux/config.h> /* for CONFIG_REMOTE_DEBUG */
@@ -26,8 +37,8 @@
 #include <asm/sgialib.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
-#include <asm/sgihpc.h>
-#include <asm/sgint23.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
 #include <asm/uaccess.h>
 
 #include "sgiserial.h"
@@ -44,7 +55,7 @@
 
 struct sgi_serial zs_soft[NUM_CHANNELS];
 struct sgi_serial *zs_chain;  /* IRQ servicing chain */
-static int zilog_irq = 21;
+static int zilog_irq = SGI_SERIAL_IRQ;
 
 /* Console hooks... */
 static int zs_cons_chanout = 0;
@@ -452,7 +463,7 @@
 	volatile unsigned char junk;
 
 	/* P3: In theory we have to test readiness here because a
-	 * serial console can clog the chip through rs_put_char().
+	 * serial console can clog the chip through zs_cons_put_char().
 	 * David did not do this. I think he relies on 3-chars FIFO in 8530.
 	 * Let's watch for lost _output_ characters. XXX
 	 */
@@ -891,7 +902,7 @@
 }
 
 /* This is for console output over ttya/ttyb */
-static void rs_put_char(char ch)
+static void zs_cons_put_char(char ch)
 {
 	struct sgi_zschannel *chan = zs_conschan;
 	volatile unsigned char junk;
@@ -909,6 +920,31 @@
 	restore_flags(flags);
 }
 
+/* 
+ * This is the more generic put_char function for the driver.
+ * In earlier versions of this driver, "rs_put_char" was the
+ * name of the console-specific fucntion, now called zs_cons_put_char
+ */
+
+static void rs_put_char(struct tty_struct *tty, char ch)
+{
+	struct sgi_zschannel *chan = 
+		((struct sgi_serial *)tty->driver_data)->zs_channel;
+	volatile unsigned char junk;
+	int flags, loops = 0;
+
+	save_flags(flags); cli();
+	while(((junk = chan->control) & Tx_BUF_EMP)==0 && loops < 10000) {
+		loops++;
+		udelay(2);
+	}
+
+	udelay(2);
+	chan->data = ch;
+	junk = ioc_icontrol->istat0;
+	restore_flags(flags);
+}
+
 /* These are for receiving and sending characters under the kgdb
  * source level kernel debugger.
  */
@@ -966,7 +1002,7 @@
 		info->xmit_cnt--;
 		restore_flags(flags);
 
-		rs_put_char(c);
+		zs_cons_put_char(c);
 
 		save_flags(flags);  cli();
 		left = MIN(info->xmit_cnt, left-1);
@@ -1019,8 +1055,18 @@
 		count -= c;
 		total += c;
 	}
-	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
-	    !(info->curregs[5] & TxENAB)) {
+
+	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+	/*
+	 * The above test used to include the condition
+ 	 * "&& !(info->curregs[5] & TxENAB)", but there
+	 * is reason to suspect that it is never statisfied
+	 * when the port is running.  The problem may in fact
+	 * have been masked by the fact that, if O_POST is set,
+	 * there is always a rs_flush_xx operation following the
+	 * rs_write, and the flush ignores that condition when
+	 * it kicks off the transmit.
+	 */
 		/* Enable transmitter */
 		info->curregs[1] |= TxINT_ENAB|EXT_INT_ENAB;
 		info->pendregs[1] |= TxINT_ENAB|EXT_INT_ENAB;
@@ -1028,7 +1074,21 @@
 		info->curregs[5] |= TxENAB;
 		info->pendregs[5] |= TxENAB;
 		write_zsreg(info->zs_channel, 5, info->curregs[5]);
+
+	/*
+	 * The following code is imported from the 2.3.6 Sun sbus zs.c
+	 * driver, of which an earlier version served as the basis
+	 * for sgiserial.c.  Perhaps due to changes over time in
+	 * the line discipline code, ns_write()s with from_user
+	 * set would not otherwise actually kick-off output in
+	 * Linux 2.2.x or later.  Maybe it never really worked.
+	 */
+
+		rs_put_char(tty, info->xmit_buf[info->xmit_tail++]);
+                info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+                info->xmit_cnt--;
 	}
+
 	restore_flags(flags);
 	return total;
 }
@@ -2021,13 +2081,14 @@
 	ZS_CLEARFIFO(zs_kgdbchan);
 }
 
-static void zs_console_write(struct console *co, const char *str, unsigned int count)
+static void zs_console_write(struct console *co, const char *str,
+                             unsigned int count)
 {
 
 	while(count--) {
 		if(*str == '\n')
-			rs_put_char('\r');
-		rs_put_char(*str++);
+			zs_cons_put_char('\r');
+		zs_cons_put_char(*str++);
 	}
 
 	/* Comment this if you want to have a strict interrupt-driven output */
@@ -2186,10 +2247,7 @@
 /*
  *	Register console.
  */
-long __init serial_console_init(long kmem_start, long kmem_end)
+void __init serial_console_init(void)
 {
 	register_console(&sgi_console_driver);
-	return kmem_start;
 }
-
-
diff -u --recursive --new-file v2.3.47/linux/drivers/sgi/char/shmiq.c linux/drivers/sgi/char/shmiq.c
--- v2.3.47/linux/drivers/sgi/char/shmiq.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/sgi/char/shmiq.c	Thu Feb 24 22:51:08 2000
@@ -1,4 +1,4 @@
-/* $Id: shmiq.c,v 1.12 1999/06/17 13:29:04 ralf Exp $
+/* $Id: shmiq.c,v 1.20 2000/02/24 00:13:10 ralf Exp $
  *
  * shmiq.c: shared memory input queue driver
  * written 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -311,7 +311,7 @@
 	if (minor-- == 0)
 		return -EINVAL;
 
-	if (vma->vm_pgoff)
+	if (vma->vm_pgoff != 0)
 		return -EINVAL;
 
 	size  = vma->vm_end - vma->vm_start;
diff -u --recursive --new-file v2.3.47/linux/drivers/sgi/char/streamable.c linux/drivers/sgi/char/streamable.c
--- v2.3.47/linux/drivers/sgi/char/streamable.c	Thu Feb 10 17:11:14 2000
+++ linux/drivers/sgi/char/streamable.c	Thu Feb 24 22:51:08 2000
@@ -1,4 +1,4 @@
-/* $Id: streamable.c,v 1.9 1998/09/19 19:17:50 ralf Exp $
+/* $Id: streamable.c,v 1.11 2000/02/23 00:41:21 ralf Exp $
  *
  * streamable.c: streamable devices. /dev/gfx
  * (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/Makefile linux/drivers/sound/Makefile
--- v2.3.47/linux/drivers/sound/Makefile	Thu Feb 10 17:11:14 2000
+++ linux/drivers/sound/Makefile	Thu Feb 24 22:44:47 2000
@@ -66,7 +66,7 @@
 obj-$(CONFIG_SOUND_SB)		+= sb.o uart401.o
 obj-$(CONFIG_SOUND_SOFTOSS)	+= softoss2.o
 obj-$(CONFIG_SOUND_SGALAXY)	+= sgalaxy.o ad1848.o
-obj-$(CONFIG_SOUND_AD1816)      += ad1816.o
+obj-$(CONFIG_SOUND_AD1816)	+= ad1816.o
 obj-$(CONFIG_SOUND_SSCAPE)	+= sscape.o ad1848.o mpu401.o
 obj-$(CONFIG_SOUND_TRIX)	+= trix.o ad1848.o sb.o uart401.o
 obj-$(CONFIG_SOUND_UART6850)	+= uart6850.o
@@ -104,7 +104,7 @@
 sb-objs		:= sb_audio.o sb_card.o sb_common.o sb_midi.o sb_mixer.o	\
 			   sb_ess.o
 softoss2-objs	:= softoss.o softoss_rs.o
-vidc_mod-objs	:= vidc.o vidc_audio.o vidc_fill.o vidc_mixer.o vidc_synth.o
+vidc_mod-objs	:= vidc.o vidc_fill.o
 wavefront-objs  := wavfront.o wf_midi.o yss225.o
 nm256-objs	:= nm256_audio.o ac97.o
 
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/README.CONFIG linux/drivers/sound/README.CONFIG
--- v2.3.47/linux/drivers/sound/README.CONFIG	Thu May 14 10:33:17 1998
+++ linux/drivers/sound/README.CONFIG	Wed Dec 31 16:00:00 1969
@@ -1,75 +0,0 @@
-Sound Driver Configuration Notes
-Michael Chastain, <mailto:mec@shout.net>
-18 Apr 1998
-
-The Linux sound driver is derived from OSS/Free, a multi-platform
-Unix sound driver by Hannu Savolainen.  You can find out
-more about OSS/Free and the commercial version, OSS/Linux, at
-<http://www.opensound.com/ossfree>.
-
-OSS/Free comes with the configuration program 'configure.c'.  We have
-discarded that program in favor of a standard Linux configuration file
-Config.in.
-
-Config.in defines a set of symbols with the form CONFIG_SOUND_*.
-These are the -native symbols-.  Here is a description:
-
-    CONFIG_SOUND
-
-	This is the master symbol.  It controls whether the basic
-	sound-driver code is resident, modular, or not present at all.
-
-	If the basic driver is resident, each primary and secondary
-	driver can be resident, modular, or not present.
-
-	If the basic driver is modular, each primary and secondary driver
-	can be modular or not present.
-
-	And if the basic driver is not present, all other drivers are
-	not present, too.
-
-    Primary drivers
-
-	These are symbols such as CONFIG_SOUND_SB, CONFIG_SOUND_SB_MODULE,
-	CONFIG_SOUND_TRIX, or CONFIG_SOUND_TRIX_MODULE.  Each driver
-	that the user can directly select is a primary driver and has
-	the usual pair of symbols: one resident and one modular.
-
-	Each primary driver can be either resident or modular.
-
-    Secondary drivers
-
-	Primary drivers require the support of secondary drivers, such
-	as ad1848.o and uart401.o.
-
-	In Makefile, each primary driver has a list of required secondary
-	drivers.  The secondary driver requirements are merged and a
-	single definition is emitted at the end.
-
-	For each secondary driver: if any resident primary driver
-	requires it, that secondary driver will be resident.  If no
-	resident primary driver requires it but some modular primary
-	driver requires it, then that secondary driver will be modular.
-	Otherwise that secondary driver will be not present.
-
-	OSS/Free also contains tests for secondary drivers.  The Makefile
-	defines symbols for these drivers in EXTRA_CFLAGS.
-
-    CONFIG_AUDIO, CONFIG_MIDI, CONFIG_SEQUENCER
-
-	These three drivers are like secondary drivers, but not quite.
-	They can not yet be separated into modules.  They are always
-	linked into the basic sound driver, whether they are needed
-	or not.  (This is in case a primary driver is added to the
-	system later, as a module, and needs these facilities.	If it
-	were possible to modularise them, then they would get built as
-	additional modules at that time).
-
-The OSS/Free code does not use the native symbols directly, primarily
-because it does not know about modules.  I could edit the code, but that
-would make it harder to upgrade to new versions of OSS/Free.  Instead,
-the OSS/Free code continues to use -legacy symbols-.
-
-legacy.h defines all the legacy symbols to 1.  This is because, whenever
-OSS/Free tests a symbol, the Makefile has already arranged for that
-driver to be included.
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/ac97_codec.c linux/drivers/sound/ac97_codec.c
--- v2.3.47/linux/drivers/sound/ac97_codec.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/sound/ac97_codec.c	Sat Feb 26 20:22:08 2000
@@ -28,8 +28,7 @@
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>
-
-#include "ac97_codec.h"
+#include <linux/ac97_codec.h>
 
 static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel);
 static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel, 
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/ac97_codec.h linux/drivers/sound/ac97_codec.h
--- v2.3.47/linux/drivers/sound/ac97_codec.h	Sun Feb 20 21:12:39 2000
+++ linux/drivers/sound/ac97_codec.h	Wed Dec 31 16:00:00 1969
@@ -1,161 +0,0 @@
-#ifndef _AC97_CODEC_H_
-#define _AC97_CODEC_H_
-
-#include "sound_config.h"
-#include "sound_calls.h"
-
-/* AC97 1.0 */
-#define  AC97_RESET               0x0000      //
-#define  AC97_MASTER_VOL_STEREO   0x0002      // Line Out
-#define  AC97_HEADPHONE_VOL       0x0004      // 
-#define  AC97_MASTER_VOL_MONO     0x0006      // TAD Output
-#define  AC97_MASTER_TONE         0x0008      //
-#define  AC97_PCBEEP_VOL          0x000a      // none
-#define  AC97_PHONE_VOL           0x000c      // TAD Input (mono)
-#define  AC97_MIC_VOL             0x000e      // MIC Input (mono)
-#define  AC97_LINEIN_VOL          0x0010      // Line Input (stereo)
-#define  AC97_CD_VOL              0x0012      // CD Input (stereo)
-#define  AC97_VIDEO_VOL           0x0014      // none
-#define  AC97_AUX_VOL             0x0016      // Aux Input (stereo)
-#define  AC97_PCMOUT_VOL          0x0018      // Wave Output (stereo)
-#define  AC97_RECORD_SELECT       0x001a      //
-#define  AC97_RECORD_GAIN         0x001c
-#define  AC97_RECORD_GAIN_MIC     0x001e
-#define  AC97_GENERAL_PURPOSE     0x0020
-#define  AC97_3D_CONTROL          0x0022
-#define  AC97_MODEM_RATE          0x0024
-#define  AC97_POWER_CONTROL       0x0026
-
-/* AC'97 2.0 */
-#define AC97_EXTENDED_ID          0x0028       /* Extended Audio ID */
-#define AC97_EXTENDED_STATUS      0x002A       /* Extended Audio Status */
-#define AC97_PCM_FRONT_DAC_RATE   0x002C       /* PCM Front DAC Rate */
-#define AC97_PCM_SURR_DAC_RATE    0x002E       /* PCM Surround DAC Rate */
-#define AC97_PCM_LFE_DAC_RATE     0x0030       /* PCM LFE DAC Rate */
-#define AC97_PCM_LR_DAC_RATE      0x0032       /* PCM LR DAC Rate */
-#define AC97_PCM_MIC_ADC_RATE     0x0034       /* PCM MIC ADC Rate */
-#define AC97_CENTER_LFE_MASTER    0x0036       /* Center + LFE Master Volume */
-#define AC97_SURROUND_MASTER      0x0038       /* Surround (Rear) Master Volume */
-#define AC97_RESERVED_3A          0x003A       /* Reserved */
-
-/* range 0x3c-0x58 - MODEM */
-
-/* registers 0x005a - 0x007a are vendor reserved */
-
-#define AC97_VENDOR_ID1           0x007c
-#define AC97_VENDOR_ID2           0x007e
-
-/* volume control bit defines */
-#define AC97_MUTE                 0x8000
-#define AC97_MICBOOST             0x0040
-#define AC97_LEFTVOL              0x3f00
-#define AC97_RIGHTVOL             0x003f
-
-/* record mux defines */
-#define AC97_RECMUX_MIC           0x0000
-#define AC97_RECMUX_CD            0x0101
-#define AC97_RECMUX_VIDEO         0x0202       /* not used */
-#define AC97_RECMUX_AUX           0x0303      
-#define AC97_RECMUX_LINE          0x0404      
-#define AC97_RECMUX_STEREO_MIX    0x0505
-#define AC97_RECMUX_MONO_MIX      0x0606
-#define AC97_RECMUX_PHONE         0x0707
-
-
-/* general purpose register bit defines */
-#define AC97_GP_LPBK              0x0080       /* Loopback mode */
-#define AC97_GP_MS                0x0100       /* Mic Select 0=Mic1, 1=Mic2 */
-#define AC97_GP_MIX               0x0200       /* Mono output select 0=Mix, 1=Mic */
-#define AC97_GP_RLBK              0x0400       /* Remote Loopback - Modem line codec */
-#define AC97_GP_LLBK              0x0800       /* Local Loopback - Modem Line codec */
-#define AC97_GP_LD                0x1000       /* Loudness 1=on */
-#define AC97_GP_3D                0x2000       /* 3D Enhancement 1=on */
-#define AC97_GP_ST                0x4000       /* Stereo Enhancement 1=on */
-#define AC97_GP_POP               0x8000       /* Pcm Out Path, 0=pre 3D, 1=post 3D */
-
-
-/* powerdown control and status bit defines */
-
-/* status */
-#define AC97_PWR_MDM              0x0010       /* Modem section ready */
-#define AC97_PWR_REF              0x0008       /* Vref nominal */
-#define AC97_PWR_ANL              0x0004       /* Analog section ready */
-#define AC97_PWR_DAC              0x0002       /* DAC section ready */
-#define AC97_PWR_ADC              0x0001       /* ADC section ready */
-
-/* control */
-#define AC97_PWR_PR0              0x0100       /* ADC and Mux powerdown */
-#define AC97_PWR_PR1              0x0200       /* DAC powerdown */
-#define AC97_PWR_PR2              0x0400       /* Output mixer powerdown (Vref on) */
-#define AC97_PWR_PR3              0x0800       /* Output mixer powerdown (Vref off) */
-#define AC97_PWR_PR4              0x1000       /* AC-link powerdown */
-#define AC97_PWR_PR5              0x2000       /* Internal Clk disable */
-#define AC97_PWR_PR6              0x4000       /* HP amp powerdown */
-#define AC97_PWR_PR7              0x8000       /* Modem off - if supported */
-
-/* useful power states */
-#define AC97_PWR_D0               0x0000      /* everything on */
-#define AC97_PWR_D1              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4
-#define AC97_PWR_D2              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4
-#define AC97_PWR_D3              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4
-#define AC97_PWR_ANLOFF          AC97_PWR_PR2|AC97_PWR_PR3  /* analog section off */
-
-/* Total number of defined registers.  */
-#define AC97_REG_CNT 64
-
-
-/* OSS interface to the ac97s.. */
-#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|SOUND_MASK_PCM|\
-	SOUND_MASK_LINE|SOUND_MASK_CD|\
-	SOUND_MASK_ALTPCM|SOUND_MASK_IGAIN|\
-	SOUND_MASK_LINE1|SOUND_MASK_VIDEO)
-
-#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \
-	SOUND_MASK_BASS|SOUND_MASK_TREBLE|\
-	SOUND_MASK_SPEAKER|SOUND_MASK_MIC|\
-	SOUND_MASK_PHONEIN|SOUND_MASK_PHONEOUT)
-
-#define AC97_RECORD_MASK (SOUND_MASK_MIC|\
-	SOUND_MASK_CD|SOUND_MASK_VIDEO|\
-	SOUND_MASK_LINE1| SOUND_MASK_LINE|\
-	SOUND_MASK_PHONEIN)
-
-#define supported_mixer(CODEC,FOO) ( CODEC->supported_mixers & (1<<FOO) )
-
-struct ac97_codec {
-	/* AC97 controller connected with */
-	void *private_data;
-
-	char *name;
-	int id;
-	int dev_mixer; 
-
-	/* codec specific init/reset routines, used mainly for 4 or 6 channel support */
-	int  (*codec_init)  (struct ac97_codec *codec);
-
-	/* controller specific lower leverl ac97 accessing routines */
-	u16  (*codec_read)  (struct ac97_codec *codec, u8 reg);
-	void (*codec_write) (struct ac97_codec *codec, u8 reg, u16 val);
-
-	/* OSS mixer masks */
-	int modcnt;
-	int supported_mixers;
-	int stereo_mixers;
-	int record_sources;
-	
-	/* OSS mixer interface */
-	int  (*read_mixer) (struct ac97_codec *codec, int oss_channel);
-	void (*write_mixer)(struct ac97_codec *codec, int oss_channel,
-			    unsigned int left, unsigned int right);
-	int  (*recmask_io) (struct ac97_codec *codec, int rw, int mask);
-	int  (*mixer_ioctl)(struct ac97_codec *codec, unsigned int cmd, unsigned long arg);
-
-	/* saved OSS mixer states */
-	unsigned int mixer_state[SOUND_MIXER_NRDEVICES];
-};
-
-extern int ac97_read_proc (char *page_out, char **start, off_t off,
-			   int count, int *eof, void *data);
-extern int ac97_probe_codec(struct ac97_codec *);
-
-#endif /* _AC97_CODEC_H_ */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/ad1816.c linux/drivers/sound/ad1816.c
--- v2.3.47/linux/drivers/sound/ad1816.c	Mon May 10 13:01:21 1999
+++ linux/drivers/sound/ad1816.c	Thu Feb 24 22:12:57 2000
@@ -59,8 +59,6 @@
 #include "soundmodule.h"
 #include "sound_config.h"
 
-#ifdef CONFIG_AD1816
-
 #define DEBUGNOISE(x)
 #define DEBUGINFO(x) 
 #define DEBUGLOG(x) x
@@ -1429,5 +1427,3 @@
 }
 
 #endif /* MODULE */
-
-#endif /* CONFIG_AD1816 */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- v2.3.47/linux/drivers/sound/ad1848.c	Fri Jan 28 15:09:08 2000
+++ linux/drivers/sound/ad1848.c	Thu Feb 24 22:12:57 2000
@@ -40,9 +40,6 @@
 #define DEB(x)
 #define DEB1(x)
 #include "sound_config.h"
-
-#ifdef CONFIG_AD1848
-
 #include "ad1848_mixer.h"
 
 typedef struct
@@ -113,7 +110,7 @@
 	-1, -1, -1, -1, -1, -1, -1, -1, -1
 };
 
-#if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS) || defined(MODULE)
+#ifdef MODULE
 
 static int timer_installed = -1;
 
@@ -167,7 +164,7 @@
 static void     ad1848_halt_output(int dev);
 static void     ad1848_trigger(int dev, int bits);
 
-#if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)
+#ifndef EXCLUDE_TIMERS
 static int ad1848_tmr_install(int dev);
 static void ad1848_tmr_reprogram(int dev);
 
@@ -1131,7 +1128,7 @@
 	restore_flags(flags);
 	devc->xfer_count = 0;
 
-#if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)
+#ifndef EXCLUDE_TIMERS
 	if (dev == timer_installed && devc->timer_running)
 		if ((fs & 0x01) != (old_fs & 0x01))
 		{
@@ -1245,7 +1242,7 @@
 	restore_flags(flags);
 	devc->xfer_count = 0;
 
-#if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)
+#ifndef EXCLUDE_TIMERS
 	if (dev == timer_installed && devc->timer_running)
 	{
 		if ((fs & 0x01) != (old_fs & 0x01))
@@ -1931,7 +1928,7 @@
 		}
 		if (capabilities[devc->model].flags & CAP_F_TIMER)
 		{
-#ifndef __SMP__
+#ifndef CONFIG_SMP
 			int x;
 			unsigned char tmp = ad_read(devc, 16);
 #endif			
@@ -1940,7 +1937,7 @@
 
 			ad_write(devc, 21, 0x00);	/* Timer MSB */
 			ad_write(devc, 20, 0x10);	/* Timer LSB */
-#ifndef __SMP__
+#ifndef CONFIG_SMP
 			ad_write(devc, 16, tmp | 0x40);	/* Enable timer */
 			for (x = 0; x < 100000 && devc->timer_ticks == 0; x++);
 			ad_write(devc, 16, tmp & ~0x40);	/* Disable timer */
@@ -1961,7 +1958,7 @@
 	} else if (irq < 0)
 		irq2dev[-irq] = devc->dev_no = my_dev;
 
-#if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)
+#ifndef EXCLUDE_TIMERS
 	if ((capabilities[devc->model].flags & CAP_F_TIMER) &&
 	    devc->irq_ok)
 		ad1848_tmr_install(my_dev);
@@ -2146,7 +2143,7 @@
 		if (devc->model != MD_1848 && (alt_stat & 0x40))	/* Timer interrupt */
 		{
 			devc->timer_ticks++;
-#if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)
+#ifndef EXCLUDE_TIMERS
 			if (timer_installed == dev && devc->timer_running)
 				sound_timer_interrupt();
 #endif
@@ -2583,7 +2580,7 @@
 	release_region(hw_config->io_base, 4);
 }
 
-#if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)
+#ifndef EXCLUDE_TIMERS
 
 /*
  * Timer stuff (for /dev/music).
@@ -2693,7 +2690,7 @@
 
 	return 1;
 }
-#endif
+#endif /* EXCLUDE_TIMERS */
 
 
 EXPORT_SYMBOL(ad1848_detect);
@@ -2757,5 +2754,4 @@
 		unload_ms_sound(&hw_config);
 }
 
-#endif
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/adlib_card.c linux/drivers/sound/adlib_card.c
--- v2.3.47/linux/drivers/sound/adlib_card.c	Thu Nov 18 20:25:37 1999
+++ linux/drivers/sound/adlib_card.c	Thu Feb 24 22:12:57 2000
@@ -65,4 +65,4 @@
 	SOUND_LOCK_END;
 }
 
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/audio.c linux/drivers/sound/audio.c
--- v2.3.47/linux/drivers/sound/audio.c	Fri Jan 28 15:09:08 2000
+++ linux/drivers/sound/audio.c	Thu Feb 24 22:12:57 2000
@@ -29,8 +29,6 @@
 #include <linux/kmod.h>
 
 #include "sound_config.h"
-
-#ifdef CONFIG_AUDIO
 #include "ulaw.h"
 #include "coproc.h"
 
@@ -516,8 +514,6 @@
 	 * NOTE! This routine could be called several times during boot.
 	 */
 }
-
-#endif
 
 void reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording)
 {
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/cs4232.c linux/drivers/sound/cs4232.c
--- v2.3.47/linux/drivers/sound/cs4232.c	Sun Dec 27 10:53:45 1998
+++ linux/drivers/sound/cs4232.c	Thu Feb 24 22:12:57 2000
@@ -176,7 +176,6 @@
 		 * Initialize logical device 3 (MPU)
 		 */
 
-#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
 		if (mpu_base != 0 && mpu_irq != 0)
 		{
 			CS_OUT2(0x15, 0x03);	/* Select logical device 3 (MPU) */
@@ -184,7 +183,6 @@
 			CS_OUT2(0x22, mpu_irq);	/* MPU IRQ */
 			CS_OUT2(0x33, 0x01);	/* Activate logical dev 3 */
 		}
-#endif
 
 		if(synth_base != 0)
 		{
@@ -238,7 +236,6 @@
 		AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
 		AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_SYNTH);		/* FM synth */
 	}
-#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
 	if (mpu_base != 0 && mpu_irq != 0)
 	{
 		static struct address_info hw_config2 = {
@@ -266,7 +263,6 @@
 		}
 		hw_config->slots[1] = hw_config2.slots[1];
 	}
-#endif
 }
 
 void unload_cs4232(struct address_info *hw_config)
@@ -284,7 +280,6 @@
 		      0);
 
 	sound_unload_audiodev(hw_config->slots[0]);
-#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
 	if (mpu_base != 0 && mpu_irq != 0 && mpu_detected)
 	{
 		static struct address_info hw_config2 =
@@ -305,7 +300,6 @@
 
 		unload_uart401(&hw_config2);
 	}
-#endif
 }
 
 void unload_cs4232_mpu(struct address_info *hw_config)
@@ -397,4 +391,4 @@
 	SOUND_LOCK_END;
 }
 
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/dev_table.c linux/drivers/sound/dev_table.c
--- v2.3.47/linux/drivers/sound/dev_table.c	Thu Feb 10 17:11:14 2000
+++ linux/drivers/sound/dev_table.c	Thu Feb 24 22:12:57 2000
@@ -43,7 +43,6 @@
 		return;		/* No cards detected */
 #endif
 
-#ifdef CONFIG_AUDIO
 	if (num_audiodevs)	/* Audio devices present */
 	{
 		int             dev;
@@ -52,7 +51,6 @@
 		}
 		audio_init_devices();
 	  }
-#endif
 
 	return;
 }
@@ -410,7 +408,6 @@
 			int driver_size, int flags, unsigned int format_mask,
 			void *devc, int dma1, int dma2)
 {
-#ifdef CONFIG_AUDIO
 	struct audio_driver *d;
 	struct audio_operations *op;
 	int l, num;
@@ -470,9 +467,6 @@
 
 	audio_init_devices();
 	return num;
-#else
-	return -EINVAL;
-#endif
 }
 
 int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
@@ -544,7 +538,6 @@
 
 int sound_alloc_mididev(void)
 {
-#ifdef CONFIG_MIDI
 	int i = register_sound_midi(&oss_sound_fops, -1);
 	if(i==-1)
 		return i;
@@ -552,9 +545,6 @@
 	if(i>=num_midis)
 		num_midis = i + 1;
 	return i;
-#else
-	return (-1);
-#endif
 }
 
 int sound_alloc_synthdev(void)
@@ -611,13 +601,11 @@
 
 void sound_unload_mididev(int dev)
 {
-#ifdef CONFIG_MIDI
 	if (dev != -1)
 	{
 		midi_devs[dev] = NULL;
 		unregister_sound_midi((dev<<4)+2);
 	}
-#endif
 }
 
 void sound_unload_synthdev(int dev)
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/dev_table.h linux/drivers/sound/dev_table.h
--- v2.3.47/linux/drivers/sound/dev_table.h	Thu Feb 10 17:11:14 2000
+++ linux/drivers/sound/dev_table.h	Thu Feb 24 22:12:57 2000
@@ -357,7 +357,7 @@
 struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV] = {NULL}; int num_synths = 0;
 struct midi_operations *midi_devs[MAX_MIDI_DEV] = {NULL}; int num_midis = 0;
 
-#if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS) && !defined(VMIDI)
+#ifndef EXCLUDE_TIMERS
 extern struct sound_timer_operations default_sound_timer;
 struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = {
 	&default_sound_timer, NULL
@@ -386,11 +386,9 @@
 #ifdef CONFIG_GUS16
 	{"GUS16", 0, SNDCARD_GUS16,	"Ultrasound 16-bit opt.",	attach_gus_db16, probe_gus_db16, unload_gus_db16},
 #endif
-#ifdef CONFIG_GUS
 	{"GUS", 0, SNDCARD_GUS,	"Gravis Ultrasound",	attach_gus_card, probe_gus, unload_gus},
 	{"GUSPNP", 1, SNDCARD_GUSPNP,	"GUS PnP",	attach_gus_card, probe_gus, unload_gus},
 #endif
-#endif
 
 #ifdef CONFIG_SOUND_MSS
 	{"MSS", 0, SNDCARD_MSS,	"MS Sound System",	attach_ms_sound, probe_ms_sound, unload_ms_sound},
@@ -433,11 +431,11 @@
 	{"PAS16", 0, SNDCARD_PAS,	"ProAudioSpectrum",	attach_pas_card, probe_pas, unload_pas},
 #endif
 
-#if (defined(CONFIG_SOUND_MPU401) || defined(CONFIG_SOUND_MPU_EMU)) && defined(CONFIG_MIDI)
+#if (defined(CONFIG_SOUND_MPU401) || defined(CONFIG_SOUND_MPU_EMU))
 	{"MPU401", 0, SNDCARD_MPU401,"Roland MPU-401",	attach_mpu401, probe_mpu401, unload_mpu401},
 #endif
 
-#if defined(CONFIG_SOUND_UART401) && defined(CONFIG_MIDI)
+#if defined(CONFIG_SOUND_UART401)
 	{"UART401", 0, SNDCARD_UART401,"MPU-401 (UART)", 
 		attach_uart401, probe_uart401, unload_uart401},
 #endif
@@ -450,7 +448,7 @@
 	{"MAUI", 0, SNDCARD_MAUI,"TB Maui",	attach_maui, probe_maui, unload_maui},
 #endif
 
-#if defined(CONFIG_SOUND_UART6850) && defined(CONFIG_MIDI)
+#if defined(CONFIG_SOUND_UART6850)
 	{"MIDI6850", 0, SNDCARD_UART6850,"6860 UART Midi",	attach_uart6850, probe_uart6850, unload_uart6850},
 #endif
 
@@ -461,10 +459,8 @@
 	{"SBLAST", 0, SNDCARD_SB,	"Sound Blaster",		attach_sb_card, probe_sb, unload_sb},
 	{"SBPNP", 6, SNDCARD_SBPNP,	"Sound Blaster PnP",		attach_sb_card, probe_sb, unload_sb},
 
-#ifdef CONFIG_MIDI
 	{"SBMPU", 0, SNDCARD_SB16MIDI,"SB MPU-401",	attach_sbmpu, probe_sbmpu, unload_sbmpu},
 #endif
-#endif
 
 #ifdef CONFIG_SOUND_SSCAPE
 	{"SSCAPE", 0, SNDCARD_SSCAPE, "Ensoniq SoundScape",	attach_sscape, probe_sscape, unload_sscape},
@@ -488,7 +484,7 @@
 		attach_softsyn_card, probe_softsyn, unload_softsyn},
 #endif
 
-#if defined(CONFIG_SOUND_VMIDI) && defined(CONFIG_MIDI)
+#ifdef CONFIG_SOUND_VMIDI
 	{"VMIDI", 0, SNDCARD_VMIDI,"Loopback MIDI Device",      attach_v_midi, probe_v_midi, unload_v_midi},
 #endif
 #ifdef CONFIG_SOUND_VIDC
@@ -503,8 +499,6 @@
 int num_sound_drivers = sizeof(sound_drivers) / sizeof (struct driver_info);
 
 
-#ifndef FULL_SOUND
-
 /*
  *	List of devices actually configured in the system.
  *
@@ -632,7 +626,7 @@
 	{SNDCARD_MAUI, {CONFIG_MAUI_BASE, CONFIG_MAUI_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
 #endif
 
-#if defined(CONFIG_SOUND_MPU401) && defined(CONFIG_MIDI)
+#ifdef CONFIG_SOUND_MPU401
 	{SNDCARD_MPU401, {CONFIG_MPU_BASE, CONFIG_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
 #ifdef MPU2_BASE
 	{SNDCARD_MPU401, {MPU2_BASE, MPU2_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
@@ -642,12 +636,12 @@
 #endif
 #endif
 
-#if defined(CONFIG_SOUND_UART6850) && defined(CONFIG_MIDI)
+#ifdef CONFIG_SOUND_UART6850
 	{SNDCARD_UART6850, {CONFIG_U6850_BASE, CONFIG_U6850_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
 #endif
 
 #ifdef CONFIG_SOUND_SB
-#if defined(CONFIG_MIDI) && defined(CONFIG_SB_MPU_BASE)
+#ifdef CONFIG_SB_MPU_BASE
 	{SNDCARD_SB16MIDI,{CONFIG_SB_MPU_BASE, CONFIG_SB_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
 #endif
 #endif
@@ -666,7 +660,7 @@
 	{SNDCARD_ADLIB, {FM_MONO, 0, 0, -1}, SND_DEFAULT_ENABLE},
 #endif
 
-#if defined(CONFIG_SOUND_VMIDI) && defined(CONFIG_MIDI)
+#ifdef CONFIG_SOUND_VMIDI
 	{SNDCARD_VMIDI, {0, 0, 0, -1}, SND_DEFAULT_ENABLE},
 #endif
 
@@ -683,13 +677,7 @@
 int num_sound_cards = sizeof(snd_installed_cards) / sizeof (struct card_info);
 static int max_sound_cards =  sizeof(snd_installed_cards) / sizeof (struct card_info);
 
-#else
-int num_sound_cards = 0;
-struct card_info snd_installed_cards[20] = {{0}};
-static int max_sound_cards = 20;
-#endif
-
-#if defined(MODULE) || (!defined(linux) && !defined(_AIX))
+#if defined(MODULE)
 int trace_init = 0;
 #else
 int trace_init = 1;
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/dmabuf.c linux/drivers/sound/dmabuf.c
--- v2.3.47/linux/drivers/sound/dmabuf.c	Mon Oct  4 15:49:30 1999
+++ linux/drivers/sound/dmabuf.c	Thu Feb 24 22:12:57 2000
@@ -29,8 +29,6 @@
 
 #include "sound_config.h"
 
-#if defined(CONFIG_AUDIO) || defined(CONFIG_GUS)
-
 #define DMAP_FREE_ON_CLOSE      0
 #define DMAP_KEEP_ON_CLOSE      1
 extern int sound_dmap_flag;
@@ -1286,5 +1284,3 @@
 			sound_free_dmap(adev->dmap_in);
 	}
 }
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c
--- v2.3.47/linux/drivers/sound/es1371.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/sound/es1371.c	Sat Feb 26 20:22:08 2000
@@ -119,11 +119,11 @@
 #include <linux/bitops.h>
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
+#include <linux/ac97_codec.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
-#include "ac97_codec.h"
 
 /* --------------------------------------------------------------------- */
 
@@ -376,6 +376,9 @@
 
 #define SND_DEV_DSP16   5 
 
+#define ES1371_MODULE_NAME "es1371"
+#define PFX ES1371_MODULE_NAME ": "
+
 /* --------------------------------------------------------------------- */
 
 struct es1371_state {
@@ -496,7 +499,7 @@
 			return r;
 		udelay(1);
 	}
-	printk(KERN_DEBUG "es1371: sample rate converter timeout r = 0x%08x\n", r);
+	printk(KERN_DEBUG PFX "sample rate converter timeout r = 0x%08x\n", r);
 	return r;
 }
 
@@ -1113,7 +1116,7 @@
 
 /* --------------------------------------------------------------------- */
 
-static const char invalid_magic[] = KERN_CRIT "es1371: invalid magic value\n";
+static const char invalid_magic[] = KERN_CRIT PFX "invalid magic value\n";
 
 #define VALIDATE_STATE(s)                         \
 ({                                                \
@@ -1216,7 +1219,7 @@
 		tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 / s->dac1rate;
 		tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
 		if (!schedule_timeout(tmo + 1))
-			DBG(printk(KERN_DEBUG "es1371: dac1 dma timed out??\n");)
+			DBG(printk(KERN_DEBUG PFX "dac1 dma timed out??\n");)
         }
         remove_wait_queue(&s->dma_dac1.wait, &wait);
         set_current_state(TASK_RUNNING);
@@ -1251,7 +1254,7 @@
 		tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 / s->dac2rate;
 		tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
 		if (!schedule_timeout(tmo + 1))
-			DBG(printk(KERN_DEBUG "es1371: dac2 dma timed out??\n");)
+			DBG(printk(KERN_DEBUG PFX "dac2 dma timed out??\n");)
         }
         remove_wait_queue(&s->dma_dac2.wait, &wait);
         set_current_state(TASK_RUNNING);
@@ -2502,7 +2505,7 @@
 			}
 			tmo = (count * HZ) / 3100;
 			if (!schedule_timeout(tmo ? : 1) && tmo)
-				printk(KERN_DEBUG "es1371: midi timed out??\n");
+				printk(KERN_DEBUG PFX "midi timed out??\n");
 		}
 		remove_wait_queue(&s->midi.owait, &wait);
 		set_current_state(TASK_RUNNING);
@@ -2629,7 +2632,7 @@
 		return -1;
 	}
 	if (!(s = kmalloc(sizeof(struct es1371_state), GFP_KERNEL))) {
-		printk(KERN_WARNING "es1371: out of memory\n");
+		printk(KERN_WARNING PFX "out of memory\n");
 		return -1;
 	}
 	memset(s, 0, sizeof(struct es1371_state));
@@ -2652,19 +2655,19 @@
 	s->codec.id = 0;
 	s->codec.codec_read = rdcodec;
 	s->codec.codec_write = wrcodec;
-	printk(KERN_INFO "es1371: found chip, vendor id 0x%04x device id 0x%04x revision 0x%02x\n",
+	printk(KERN_INFO PFX "found chip, vendor id 0x%04x device id 0x%04x revision 0x%02x\n",
 	       s->vendor, s->device, s->rev);
 	if (!request_region(s->io, ES1371_EXTENT, "es1371")) {
-		printk(KERN_ERR "es1371: io ports %#lx-%#lx in use\n", s->io, s->io+ES1371_EXTENT-1);
+		printk(KERN_ERR PFX "io ports %#lx-%#lx in use\n", s->io, s->io+ES1371_EXTENT-1);
 		goto err_region;
 	}
 	if (request_irq(s->irq, es1371_interrupt, SA_SHIRQ, "es1371", s)) {
-		printk(KERN_ERR "es1371: irq %u in use\n", s->irq);
+		printk(KERN_ERR PFX "irq %u in use\n", s->irq);
 		goto err_irq;
 	}
 	pci_enable_device(pcidev);
-	printk(KERN_INFO "es1371: found es1371 rev %d at io %#lx irq %u\n"
-	       KERN_INFO "es1371: features: joystick 0x%x\n", s->rev, s->io, s->irq, joystick[devindex]);
+	printk(KERN_INFO PFX "found es1371 rev %d at io %#lx irq %u\n"
+	       KERN_INFO PFX "features: joystick 0x%x\n", s->rev, s->io, s->irq, joystick[devindex]);
 	/* register devices */
 	if ((s->dev_audio = register_sound_dsp(&es1371_audio_fops, -1)) < 0)
 		goto err_dev1;
@@ -2683,7 +2686,7 @@
 	s->ctrl = 0;
 	if ((joystick[devindex] & ~0x18) == 0x200) {
 		if (check_region(joystick[devindex], JOY_EXTENT))
-			printk(KERN_ERR "es1371: joystick address 0x%x already in use\n", joystick[devindex]);
+			printk(KERN_ERR PFX "joystick address 0x%x already in use\n", joystick[devindex]);
 		else {
 			s->ctrl |= CTRL_JYSTK_EN | (((joystick[devindex] >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT);
 		}
@@ -2693,11 +2696,11 @@
 	/* check to see if s/pdif mode is being requested */
 	if (spdif[devindex]) {
 		if (s->rev >= 4) {
-			printk(KERN_INFO "es1371: enabling S/PDIF output\n");
+			printk(KERN_INFO PFX "enabling S/PDIF output\n");
 			cssr |= STAT_EN_SPDIF;
 			s->ctrl |= CTRL_SPDIFEN_B;
 		} else {
-			printk(KERN_ERR "es1371: revision %d does not support S/PDIF\n", s->rev);
+			printk(KERN_ERR PFX "revision %d does not support S/PDIF\n", s->rev);
 		}
 	}
 	/* initialize the chips */
@@ -2731,6 +2734,7 @@
 	if (!ac97_probe_codec(&s->codec))
 		goto err_dev4;
 	/* set default values */
+
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 	val = SOUND_MASK_LINE;
@@ -2759,7 +2763,7 @@
  err_dev2:
 	unregister_sound_dsp(s->dev_audio);
  err_dev1:
-	printk(KERN_ERR "es1371: cannot register misc device\n");
+	printk(KERN_ERR PFX "cannot register misc device\n");
 	free_irq(s->irq, s);
  err_irq:
 	release_region(s->io, ES1371_EXTENT);
@@ -2822,7 +2826,7 @@
 
 static void __exit cleanup_es1371(void)
 {
-	printk(KERN_INFO "es1371: unloading\n");
+	printk(KERN_INFO PFX "unloading\n");
 	pci_unregister_driver(&es1371_driver);
 }
 
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/finetune.h linux/drivers/sound/finetune.h
--- v2.3.47/linux/drivers/sound/finetune.h	Tue Sep 30 08:46:44 1997
+++ linux/drivers/sound/finetune.h	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-#ifdef SEQUENCER_C
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-
-  unsigned short finetune_table[128] =
-	{
-/*   0 */  9439,  9447,  9456,  9464,  9473,  9481,  9490,  9499, 
-/*   8 */  9507,  9516,  9524,  9533,  9542,  9550,  9559,  9567, 
-/*  16 */  9576,  9585,  9593,  9602,  9611,  9619,  9628,  9637, 
-/*  24 */  9645,  9654,  9663,  9672,  9680,  9689,  9698,  9707, 
-/*  32 */  9715,  9724,  9733,  9742,  9750,  9759,  9768,  9777, 
-/*  40 */  9786,  9795,  9803,  9812,  9821,  9830,  9839,  9848, 
-/*  48 */  9857,  9866,  9874,  9883,  9892,  9901,  9910,  9919, 
-/*  56 */  9928,  9937,  9946,  9955,  9964,  9973,  9982,  9991, 
-/*  64 */ 10000, 10009, 10018, 10027, 10036, 10045, 10054, 10063, 
-/*  72 */ 10072, 10082, 10091, 10100, 10109, 10118, 10127, 10136, 
-/*  80 */ 10145, 10155, 10164, 10173, 10182, 10191, 10201, 10210, 
-/*  88 */ 10219, 10228, 10237, 10247, 10256, 10265, 10274, 10284, 
-/*  96 */ 10293, 10302, 10312, 10321, 10330, 10340, 10349, 10358, 
-/* 104 */ 10368, 10377, 10386, 10396, 10405, 10415, 10424, 10433, 
-/* 112 */ 10443, 10452, 10462, 10471, 10481, 10490, 10499, 10509, 
-/* 120 */ 10518, 10528, 10537, 10547, 10556, 10566, 10576, 10585
-	};
-#else
-  extern unsigned short finetune_table[128];
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/gus_card.c linux/drivers/sound/gus_card.c
--- v2.3.47/linux/drivers/sound/gus_card.c	Wed Mar 10 17:03:52 1999
+++ linux/drivers/sound/gus_card.c	Thu Feb 24 22:12:57 2000
@@ -26,8 +26,6 @@
 #include "sound_config.h"
 #include "soundmodule.h"
 
-#ifdef CONFIG_GUS
-
 #include "gus_hw.h"
 
 void            gusintr(int irq, void *dev_id, struct pt_regs *dummy);
@@ -55,9 +53,7 @@
 	if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
 		if (sound_alloc_dma(hw_config->dma2, "GUS(2)"))
 			printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma2);
-#ifdef CONFIG_MIDI
 	gus_midi_init(hw_config);
-#endif
 	if(request_irq(hw_config->irq, gusintr, 0,  "Gravis Ultrasound", hw_config)<0)
 		printk(KERN_ERR "gus_card.c: Unable to allocate IRQ %d\n", hw_config->irq);
 
@@ -156,28 +152,20 @@
 		}
 		if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
 		{
-#ifdef CONFIG_MIDI
 			gus_midi_interrupt(0);
-#endif
 		}
 		if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
 		{
-#ifdef CONFIG_SEQUENCER
 			if (gus_timer_enabled)
 				sound_timer_interrupt();
 			gus_write8(0x45, 0);	/* Ack IRQ */
 			gus_timer_command(4, 0x80);		/* Reset IRQ flags */
-#else
-			gus_write8(0x45, 0);	/* Stop timers */
-#endif
 		}
 		if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
 			gus_voice_irq();
 	}
 }
 
-#endif
-
 /*
  *	Some extra code for the 16 bit sampling option
  */
@@ -191,10 +179,8 @@
 
 void attach_gus_db16(struct address_info *hw_config)
 {
-#ifdef CONFIG_GUS
 	gus_pcm_volume = 100;
 	gus_wave_volume = 90;
-#endif
 
 	hw_config->slots[3] = ad1848_init("GUS 16 bit sampling", hw_config->io_base,
 					  hw_config->irq,
@@ -292,4 +278,4 @@
 	SOUND_LOCK_END;
 }
 
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/gus_midi.c linux/drivers/sound/gus_midi.c
--- v2.3.47/linux/drivers/sound/gus_midi.c	Thu May 14 10:33:17 1998
+++ linux/drivers/sound/gus_midi.c	Thu Feb 24 22:12:57 2000
@@ -12,14 +12,9 @@
  */
 #include <linux/config.h>
 
-
 #include "sound_config.h"
-
 #include "gus_hw.h"
 
-#ifdef CONFIG_GUS
-#ifdef CONFIG_MIDI
-
 static int      midi_busy = 0, input_opened = 0;
 static int      my_dev;
 static int      output_used = 0;
@@ -265,6 +260,3 @@
 	}
 	restore_flags(flags);
 }
-
-#endif
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/gus_vol.c linux/drivers/sound/gus_vol.c
--- v2.3.47/linux/drivers/sound/gus_vol.c	Thu May 14 10:33:17 1998
+++ linux/drivers/sound/gus_vol.c	Thu Feb 24 22:12:57 2000
@@ -12,7 +12,6 @@
 #include <linux/config.h>
 
 #include "sound_config.h"
-#ifdef CONFIG_GUS
 #include "gus_linearvol.h"
 
 #define GUS_VOLUME	gus_wave_volume
@@ -152,5 +151,3 @@
 #endif
 	return gus_linearvol[(((vol * mainvol) / 127) * mixer_mainvol) / 100];
 }
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/gus_wave.c linux/drivers/sound/gus_wave.c
--- v2.3.47/linux/drivers/sound/gus_wave.c	Tue May 11 23:40:50 1999
+++ linux/drivers/sound/gus_wave.c	Thu Feb 24 22:12:57 2000
@@ -25,8 +25,6 @@
 #include <linux/ultrasound.h>
 #include "gus_hw.h"
 
-#ifdef CONFIG_GUS
-
 #define GUS_BANK_SIZE (((iw_mode) ? 256*1024*1024 : 256*1024))
 
 #define MAX_SAMPLE	150
@@ -3111,9 +3109,7 @@
 		hw_config->slots[0] = sdev;
 		synth_devs[sdev] = &guswave_operations;
 		sequencer_init();
-#ifdef CONFIG_SEQUENCER
 		gus_tmr_install(gus_base + 8);
-#endif
 	}
 
 	reset_sample_memory();
@@ -3433,8 +3429,6 @@
 	}
 }
 
-#ifdef CONFIG_SEQUENCER
-
 /*
  * Timer stuff
  */
@@ -3535,6 +3529,3 @@
 	sound_timer_init(&gus_tmr, "GUS");
 #endif
 }
-#endif
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/ics2101.c linux/drivers/sound/ics2101.c
--- v2.3.47/linux/drivers/sound/ics2101.c	Thu May 14 10:33:17 1998
+++ linux/drivers/sound/ics2101.c	Thu Feb 24 22:12:57 2000
@@ -17,7 +17,6 @@
 
 
 #include "sound_config.h"
-#ifdef CONFIG_GUS
 
 #include <linux/ultrasound.h>
 #include "gus_hw.h"
@@ -244,5 +243,3 @@
 	}
 	return n;
 }
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/legacy.h linux/drivers/sound/legacy.h
--- v2.3.47/linux/drivers/sound/legacy.h	Wed Dec 16 12:52:01 1998
+++ linux/drivers/sound/legacy.h	Wed Dec 31 16:00:00 1969
@@ -1,50 +0,0 @@
-#ifndef _SOUND_LEGACY_H_
-#define _SOUND_LEGACY_H_
-
-/*
- *	Force on additional support
- */
-
-#define __SGNXPRO__
-#define DESKPROXL
-/* #define SM_GAMES */
-#define SM_WAVE
-
-/*
- * Define legacy options.
- */
-
-#define SELECTED_SOUND_OPTIONS		0x0
-
-#define HAVE_MAUI_BOOT
-#define PSS_HAVE_LD
-#define INCLUDE_TRIX_BOOT
-
-#define CONFIG_CS4232
-#define CONFIG_GUS
-#define CONFIG_MAD16
-#define CONFIG_MAUI
-#define CONFIG_MPU401
-#define CONFIG_MSS
-#define CONFIG_OPL3SA1
-#define CONFIG_OPL3SA2
-#define CONFIG_PAS
-#define CONFIG_PSS
-#define CONFIG_SB
-#define CONFIG_SOFTOSS
-#define CONFIG_SSCAPE
-#define CONFIG_AD1816
-#define CONFIG_TRIX
-#define CONFIG_VMIDI
-#define CONFIG_YM3812
-
-#define CONFIG_AUDIO
-#define CONFIG_MIDI
-#define CONFIG_SEQUENCER
-
-#define CONFIG_AD1848
-#define CONFIG_MPU_EMU
-#define CONFIG_SBDSP
-#define CONFIG_UART401
-
-#endif	/* _SOUND_LEGACY_H */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/lowlevel/Config.in linux/drivers/sound/lowlevel/Config.in
--- v2.3.47/linux/drivers/sound/lowlevel/Config.in	Mon Oct  4 15:49:30 1999
+++ linux/drivers/sound/lowlevel/Config.in	Sat Feb 26 20:32:15 2000
@@ -2,6 +2,15 @@
 
 dep_tristate '  AWE32 synth' CONFIG_AWE32_SYNTH $CONFIG_SOUND_OSS
 
+if [ "$CONFIG_AWE32_SYNTH" = "y" -o "$CONFIG_AWE32_SYNTH" = "m" ]; then
+   comment 'AWE32 PnP-ISA Cards are not always setup correctly'
+   bool 'Configure AWE32 synth Base Address and Default Memory Size' CONFIG_AWE32_SYNTH_DEFAULTS
+   if [ "$CONFIG_AWE32_SYNTH_DEFAULTS" = "y" ]; then
+      hex 'AWE32 synth Base Address 620' AWE_DEFAULT_BASE_ADDR 620
+      int 'AWE32 synth Default Memory Size 512 1024 or 4096' AWE_DEFAULT_MEM_SIZE 512
+   fi
+fi
+
 if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND" = "m" ]; then
    dep_tristate '  Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_AEDSP16 $CONFIG_SOUND_OSS
    if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/mad16.c linux/drivers/sound/mad16.c
--- v2.3.47/linux/drivers/sound/mad16.c	Tue Dec 14 01:27:24 1999
+++ linux/drivers/sound/mad16.c	Thu Feb 24 22:12:57 2000
@@ -86,8 +86,6 @@
 
 #endif
 
-#ifdef CONFIG_MAD16
-
 #include "sb.h"
 
 static int      already_initialized = 0;
@@ -724,7 +722,7 @@
 
 void attach_mad16_mpu(struct address_info *hw_config)
 {
-#if defined(CONFIG_MIDI) && defined(CONFIG_MAD16_OLDCARD)
+#ifdef CONFIG_MAD16_OLDCARD
 
 	if (mad_read(MC1_PORT) & 0x20)
 		hw_config->io_base = 0x240;
@@ -746,7 +744,6 @@
 
 int probe_mad16_mpu(struct address_info *hw_config)
 {
-#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
 	static int mpu_attached = 0;
 	static int valid_ports[] = {
 		0x330, 0x320, 0x310, 0x300
@@ -766,7 +763,7 @@
 	if (board_type < C929)	/* Early chip. No MPU support. Just SB MIDI */
 	{
 
-#if defined(CONFIG_MIDI) && defined(CONFIG_MAD16_OLDCARD)
+#ifdef CONFIG_MAD16_OLDCARD
 		unsigned char   tmp;
 
 		tmp = mad_read(MC3_PORT);
@@ -899,9 +896,6 @@
 	mad_write(MC6_PORT, tmp);	/* Write MPU401 config */
 
 	return probe_uart401(hw_config);
-#else
-	return 0;
-#endif
 }
 
 void unload_mad16(struct address_info *hw_config)
@@ -917,7 +911,7 @@
 void
 unload_mad16_mpu(struct address_info *hw_config)
 {
-#if defined(CONFIG_MIDI) && defined(CONFIG_MAD16_OLDCARD)
+#ifdef CONFIG_MAD16_OLDCARD
 	if (board_type < C929)	/* Early chip. No MPU support. Just SB MIDI */
 	{
 		sb_dsp_unload(hw_config, 0);
@@ -925,9 +919,7 @@
 	}
 #endif
 
-#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
 	unload_uart401(hw_config);
-#endif
 }
 
 #ifdef MODULE
@@ -1126,9 +1118,4 @@
 	SOUND_LOCK_END;
 }
 
-#endif
-
-
-
-/* That's all folks */
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/maui.c linux/drivers/sound/maui.c
--- v2.3.47/linux/drivers/sound/maui.c	Wed Aug  4 16:36:41 1999
+++ linux/drivers/sound/maui.c	Thu Feb 24 22:12:57 2000
@@ -32,8 +32,6 @@
 #include "soundmodule.h"
 #include "sound_firmware.h"
 
-#ifdef CONFIG_MAUI
-
 static int      maui_base = 0x330;
 
 static volatile int irq_ok = 0;
@@ -53,12 +51,7 @@
 static int      (*orig_load_patch) (int dev, int format, const char *addr,
 			      int offs, int count, int pmgr_flag) = NULL;
 
-#ifdef HAVE_MAUI_BOOT
 #include "maui_boot.h"
-#else
-static unsigned char *maui_os = NULL;
-static int maui_osLen = 0;
-#endif
 
 static int maui_wait(int mask)
 {
@@ -190,7 +183,7 @@
 
 static int maui_init(int irq)
 {
-#ifdef __SMP__
+#ifdef CONFIG_SMP
 	int i;
 #endif	
 	unsigned char bits;
@@ -221,7 +214,7 @@
 	outb((0x80), HOST_CTRL_PORT);	/* Leave reset */
 	outb((0xD0), HOST_CTRL_PORT);	/* Cause interrupt */
 
-#ifdef __SMP__
+#ifdef CONFIG_SMP
 	for (i = 0; i < 1000000 && !irq_ok; i++);
 
 	if (!irq_ok)
@@ -500,5 +493,4 @@
 	unload_maui(&cfg);
 	SOUND_LOCK_END;
 }
-#endif
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/midi_synth.c linux/drivers/sound/midi_synth.c
--- v2.3.47/linux/drivers/sound/midi_synth.c	Sun Mar 21 07:11:37 1999
+++ linux/drivers/sound/midi_synth.c	Thu Feb 24 22:12:57 2000
@@ -21,8 +21,6 @@
 
 #include "sound_config.h"
 
-#ifdef CONFIG_MIDI
-
 #define _MIDI_SYNTH_C_
 
 #include "midi_synth.h"
@@ -32,9 +30,6 @@
 {0};
 static unsigned char prev_out_status[MAX_MIDI_DEV];
 
-#ifndef CONFIG_SEQUENCER
-#define STORE(cmd)
-#else
 #define STORE(cmd) \
 { \
   int len; \
@@ -42,7 +37,6 @@
   cmd; \
   seq_input_event(obuf, len); \
 }
-#endif
 
 #define _seqbuf obuf
 #define _seqbufptr 0
@@ -709,6 +703,3 @@
 
 	return 0;
 }
-
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/midibuf.c linux/drivers/sound/midibuf.c
--- v2.3.47/linux/drivers/sound/midibuf.c	Tue May 11 23:40:50 1999
+++ linux/drivers/sound/midibuf.c	Thu Feb 24 22:12:57 2000
@@ -21,7 +21,6 @@
 
 #include "sound_config.h"
 
-#ifdef CONFIG_MIDI
 
 /*
  * Don't make MAX_QUEUE_SIZE larger than 4000
@@ -431,6 +430,3 @@
 		return DATA_AVAIL (midi_in_buf[dev]);
 	return 0;
 }
-
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/mpu401.c linux/drivers/sound/mpu401.c
--- v2.3.47/linux/drivers/sound/mpu401.c	Thu Aug 26 13:05:39 1999
+++ linux/drivers/sound/mpu401.c	Thu Feb 24 22:12:57 2000
@@ -24,15 +24,11 @@
 #include "sound_config.h"
 #include "soundmodule.h"
 
-#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 #include "coproc.h"
 
 
-#ifdef CONFIG_SEQUENCER
 static int      timer_mode = TMR_INTERNAL, timer_caps = TMR_INTERNAL;
 
-#endif
-
 struct mpu_config
 {
 	int             base;	/*
@@ -159,9 +155,6 @@
 	0			/* Fx */
 };
 
-#ifndef CONFIG_SEQUENCER
-#define STORE(cmd)
-#else
 #define STORE(cmd) \
 { \
 	int len; \
@@ -169,7 +162,6 @@
 	cmd; \
 	seq_input_event(obuf, len); \
 }
-#endif
 
 #define _seqbuf obuf
 #define _seqbufptr 0
@@ -1225,8 +1217,6 @@
  *      Timer stuff
  ****************************************************/
 
-#if defined(CONFIG_SEQUENCER)
-
 static volatile int timer_initialized = 0, timer_open = 0, tmr_running = 0;
 static volatile int curr_tempo, curr_timebase, hw_timebase;
 static int      max_timebase = 8;	/* 8*24=192 ppqn */
@@ -1718,9 +1708,6 @@
 
 }
 
-#endif
-
-
 EXPORT_SYMBOL(probe_mpu401);
 EXPORT_SYMBOL(attach_mpu401);
 EXPORT_SYMBOL(unload_mpu401);
@@ -1762,5 +1749,4 @@
 	SOUND_LOCK_END;
 }
 
-#endif
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/opl3.c linux/drivers/sound/opl3.c
--- v2.3.47/linux/drivers/sound/opl3.c	Thu Nov 18 20:25:37 1999
+++ linux/drivers/sound/opl3.c	Thu Feb 24 22:12:57 2000
@@ -1204,7 +1204,7 @@
 
 void cleanup_module(void)
 {
-	if (devc)
+	if (devc && io != -1)
 	{
 		if(devc->base)
 			release_region(devc->base,4);
@@ -1217,7 +1217,7 @@
 
 MODULE_PARM(io, "i");
 
-#endif
+#endif /* MODULE */
 
 EXPORT_SYMBOL(opl3_init);
 EXPORT_SYMBOL(opl3_detect);
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/opl3sa.c linux/drivers/sound/opl3sa.c
--- v2.3.47/linux/drivers/sound/opl3sa.c	Mon Oct  4 15:49:30 1999
+++ linux/drivers/sound/opl3sa.c	Thu Feb 24 22:12:57 2000
@@ -31,8 +31,6 @@
 
 #endif
 
-#ifdef CONFIG_OPL3SA1
-
 static int kilroy_was_here = 0;	/* Don't detect twice */
 static int mpu_initialized = 0;
 
@@ -177,15 +175,12 @@
 
 void attach_opl3sa_mpu(struct address_info *hw_config)
 {
-#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
 	hw_config->name = "OPL3-SA (MPU401)";
 	attach_uart401(hw_config);
-#endif
 }
 
 int probe_opl3sa_mpu(struct address_info *hw_config)
 {
-#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
 	unsigned char conf;
 	static signed char irq_bits[] = {
 		-1, -1, -1, -1, -1, 1, -1, 2, -1, 3, 4
@@ -240,9 +235,6 @@
 	mpu_initialized = 1;
 
 	return probe_uart401(hw_config);
-#else
-	return 0;
-#endif
 }
 
 void unload_opl3sa_wss(struct address_info *hw_config)
@@ -265,17 +257,13 @@
 
 void unload_opl3sa_mpu(struct address_info *hw_config)
 {
-#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
 	unload_uart401(hw_config);
-#endif
 }
 
 #ifdef SB_OK
 void unload_opl3sa_sb(struct address_info *hw_config)
 {
-#ifdef CONFIG_SBDSP
 	sb_dsp_unload(hw_config);
-#endif
 }
 #endif
 
@@ -334,6 +322,4 @@
 	SOUND_LOCK_END;
 }
 
-#endif
-
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c
--- v2.3.47/linux/drivers/sound/opl3sa2.c	Mon Jul  5 19:58:24 1999
+++ linux/drivers/sound/opl3sa2.c	Thu Feb 24 22:12:57 2000
@@ -67,8 +67,6 @@
 #define CHIPSET_OPL3SAX  4
 
 
-#ifdef CONFIG_OPL3SA2
-
 /* What's my version? */
 static int chipset = CHIPSET_UNKNOWN;
 
@@ -443,27 +441,19 @@
 
 int probe_opl3sa2_mpu(struct address_info *hw_config)
 {
-#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 	return probe_mpu401(hw_config);
-#else
-	return 0;
-#endif
 }
 
 
 void attach_opl3sa2_mpu(struct address_info *hw_config)
 {
-#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 	attach_mpu401(hw_config);
-#endif
 }
 
 
 void unload_opl3sa2_mpu(struct address_info *hw_config)
 {
-#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 	unload_mpu401(hw_config);
-#endif
 }
 
 
@@ -706,7 +696,6 @@
 	attach_opl3sa2(&cfg);
 	attach_opl3sa2_mss(&mss_cfg);
 
-#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 	if(mpu_io != -1)
 	{
             /* MPU config: */
@@ -720,7 +709,6 @@
 		    attach_opl3sa2_mpu(&mpu_cfg);
 	    }
 	}
-#endif
 	SOUND_LOCK;
 	return 0;
 }
@@ -728,16 +716,13 @@
 
 void cleanup_module(void)
 {
-#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
         if(mpu_cfg.slots[1] != -1)
 	{
 		unload_opl3sa2_mpu(&mpu_cfg);
 	}
-#endif
 	unload_opl3sa2_mss(&mss_cfg);
 	unload_opl3sa2(&cfg);
 	SOUND_LOCK_END;
 }
 
 #endif /* MODULE */
-#endif /* CONFIG_OPL3SA2 */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/pas2_card.c linux/drivers/sound/pas2_card.c
--- v2.3.47/linux/drivers/sound/pas2_card.c	Thu Jan 14 22:59:47 1999
+++ linux/drivers/sound/pas2_card.c	Thu Feb 24 22:12:57 2000
@@ -9,8 +9,6 @@
 #include "sound_config.h"
 #include "soundmodule.h"
 
-#ifdef CONFIG_PAS
-
 static unsigned char dma_bits[] = {
 	4, 1, 2, 3, 0, 5, 6, 7
 };
@@ -92,16 +90,12 @@
 
 	if (status & 0x08)
 	{
-#ifdef CONFIG_AUDIO
 		  pas_pcm_interrupt(status, 1);
-#endif
 		  status &= ~0x08;
 	}
 	if (status & 0x10)
 	{
-#ifdef CONFIG_MIDI
 		  pas_midi_interrupt();
-#endif
 		  status &= ~0x10;
 	}
 }
@@ -239,7 +233,7 @@
 	mix_write(0x80 | 5, 0x078B);
 	mix_write(5, 0x078B);
 
-#if !defined(DISABLE_SB_EMULATION) && defined(CONFIG_SB)
+#if !defined(DISABLE_SB_EMULATION)
 
 	{
 		struct address_info *sb_config;
@@ -351,18 +345,14 @@
 		}
 		if (config_pas_hw(hw_config))
 		{
-#ifdef CONFIG_AUDIO
 			pas_pcm_init(hw_config);
-#endif
 
-#if !defined(MODULE) && !defined(DISABLE_SB_EMULATION) && defined(CONFIG_SB)
+#if !defined(MODULE) && !defined(DISABLE_SB_EMULATION)
 
 			sb_dsp_disable_midi(pas_sb_base);	/* No MIDI capability */
 #endif
 
-#ifdef CONFIG_MIDI
 			pas_midi_init();
-#endif
 			pas_init_mixer();
 		}
 	}
@@ -453,5 +443,4 @@
 }
 
 
-#endif
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/pas2_midi.c linux/drivers/sound/pas2_midi.c
--- v2.3.47/linux/drivers/sound/pas2_midi.c	Thu Jan 14 22:59:47 1999
+++ linux/drivers/sound/pas2_midi.c	Thu Feb 24 22:12:57 2000
@@ -12,12 +12,8 @@
  */
 #include <linux/config.h>
 
-
 #include "sound_config.h"
 
-#ifdef CONFIG_PAS
-#ifdef CONFIG_MIDI
-
 static int      midi_busy = 0, input_opened = 0;
 static int      my_dev;
 
@@ -264,6 +260,3 @@
 	}
 	pas_write(stat, 0x1B88);	/* Acknowledge interrupts */
 }
-
-#endif
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/pas2_mixer.c linux/drivers/sound/pas2_mixer.c
--- v2.3.47/linux/drivers/sound/pas2_mixer.c	Thu May 14 18:50:50 1998
+++ linux/drivers/sound/pas2_mixer.c	Thu Feb 24 22:12:57 2000
@@ -19,8 +19,6 @@
 
 #include "sound_config.h"
 
-#ifdef CONFIG_PAS
-
 #ifndef DEB
 #define DEB(what)		/* (what) */
 #endif
@@ -332,5 +330,3 @@
 	  }
 	return 1;
 }
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/pas2_pcm.c linux/drivers/sound/pas2_pcm.c
--- v2.3.47/linux/drivers/sound/pas2_pcm.c	Thu Jan 14 22:59:47 1999
+++ linux/drivers/sound/pas2_pcm.c	Thu Feb 24 22:12:57 2000
@@ -18,9 +18,6 @@
 
 #include "sound_config.h"
 
-#ifdef CONFIG_PAS
-#ifdef CONFIG_AUDIO
-
 #ifndef DEB
 #define DEB(WHAT)
 #endif
@@ -440,6 +437,3 @@
 		}
 	}
 }
-
-#endif
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/pss.c linux/drivers/sound/pss.c
--- v2.3.47/linux/drivers/sound/pss.c	Wed Dec 16 12:52:01 1998
+++ linux/drivers/sound/pss.c	Thu Feb 24 22:12:57 2000
@@ -34,9 +34,6 @@
 #include "sound_firmware.h"
 #include "soundmodule.h"
 
-#ifdef CONFIG_PSS
-#ifdef CONFIG_AUDIO
-
 /*
  * PSS registers.
  */
@@ -82,14 +79,7 @@
 #define NO_WSS_MIXER	-1
 
 #include "coproc.h"
-
-#ifdef PSS_HAVE_LD
 #include "pss_boot.h"
-#else
-static int pss_synthLen = 0;
-static unsigned char *pss_synth =
-NULL;
-#endif
 
 /* If compiled into kernel, it enable or disable pss mixer */
 #ifdef CONFIG_PSS_MIXER
@@ -675,11 +665,7 @@
 			break;	/* No more input */
 	}
 
-#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 	return probe_mpu401(hw_config);
-#else
-	return 0;
-#endif
 }
 
 static int pss_coproc_open(void *dev_info, int sub_device)
@@ -926,11 +912,9 @@
 
 void attach_pss_mpu(struct address_info *hw_config)
 {
-#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 	attach_mpu401(hw_config);	/* Slot 1 */
 	if (hw_config->slots[1] != -1)	/* The MPU driver installed itself */
 		midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
-#endif
 }
 
 int probe_pss_mss(struct address_info *hw_config)
@@ -1015,9 +999,7 @@
 
 void unload_pss_mpu(struct address_info *hw_config)
 {
-#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 	unload_mpu401(hw_config);
-#endif
 }
 
 void unload_pss_mss(struct address_info *hw_config)
@@ -1114,6 +1096,4 @@
 	unload_pss(&cfgpss);
 	SOUND_LOCK_END;
 }
-#endif
-#endif
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sb.h linux/drivers/sound/sb.h
--- v2.3.47/linux/drivers/sound/sb.h	Mon Apr 12 16:18:27 1999
+++ linux/drivers/sound/sb.h	Thu Feb 24 22:12:57 2000
@@ -1,7 +1,5 @@
 #include <linux/config.h>
-#include "legacy.h"
 
-#ifdef CONFIG_SBDSP
 #define DSP_RESET	(devc->base + 0x6)
 #define DSP_READ	(devc->base + 0xA)
 #define DSP_WRITE	(devc->base + 0xC)
@@ -168,4 +166,3 @@
 
 extern int acer;
 extern sb_devc *last_sb;
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sb_audio.c linux/drivers/sound/sb_audio.c
--- v2.3.47/linux/drivers/sound/sb_audio.c	Fri Jan  7 19:13:22 2000
+++ linux/drivers/sound/sb_audio.c	Thu Feb 24 22:12:57 2000
@@ -24,8 +24,6 @@
 #include <linux/config.h>
 #include "sound_config.h"
 
-#ifdef CONFIG_SBDSP
-
 #include "sb_mixer.h"
 #include "sb.h"
 
@@ -1126,5 +1124,3 @@
 	audio_devs[devc->dev]->mixer_dev = devc->my_mixerdev;
 	audio_devs[devc->dev]->min_fragment = 5;
 }
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c
--- v2.3.47/linux/drivers/sound/sb_card.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/sound/sb_card.c	Thu Feb 24 22:12:57 2000
@@ -37,8 +37,6 @@
 #include "sound_config.h"
 #include "soundmodule.h"
 
-#ifdef CONFIG_SBDSP
-
 #include "sb_mixer.h"
 #include "sb.h"
 
@@ -113,11 +111,11 @@
 	}
 #endif
 
-	/* This is useless since is done by sb_dsp_detect - azummo*/
+	/* This is useless since is done by sb_dsp_detect - azummo */
 	
 	if (check_region(hw_config->io_base, 16))
 	{
-		printk(KERN_ERR "sb_card: I/O port %x is already in use\n\n", hw_config->io_base);
+		printk(KERN_ERR "sb_card: I/O port 0x%x is already in use\n\n", hw_config->io_base);
 		return 0;
 	}
 	return sb_dsp_detect(hw_config, 0, 0);
@@ -138,11 +136,10 @@
 static struct address_info config_mpu;
 
 struct pci_dev 	*sb_dev 	= NULL, 
-				*wss_dev 	= NULL, 
-				*jp_dev 	= NULL,
-/*				*ide_dev	= NULL, */
-				*mpu_dev 	= NULL, 
-				*wt_dev 	= NULL;
+		*wss_dev	= NULL, 
+		*jp_dev		= NULL,
+		*mpu_dev	= NULL, 
+		*wt_dev		= NULL;
 /*
  *    Note DMA2 of -1 has the right meaning in the SB16 driver as well
  *    as here. It will cause either an error if it is needed or a fallback
@@ -153,49 +150,49 @@
 int io 		= -1;
 int irq 	= -1;
 int dma 	= -1;
-int dma16 	= -1;		/* Set this for modules that need it */
-int type 	= 0;		/* Can set this to a specific card type */
-int mad16 	= 0;		/* Set mad16=1 to load this as support for mad16 */
-int trix 	= 0;		/* Set trix=1 to load this as support for trix */
-int pas2 	= 0;		/* Set pas2=1 to load this as support for pas2 */
-int support 	= 0;		/* Set support to load this as a support module */
-int sm_games	= 0;		/* Mixer - see sb_mixer.c */
-int acer 	= 0;		/* Do acer notebook init */
-
-#if defined CONFIGISAPNP || defined CONFIG_ISAPNP_MODULE
-int isapnp 		= 1;
-int isapnpjump 		= 0;
-int nosbwave	= 0;		/* This option will be removed when the new awe_wave driver will be in the kernel tree */
+int dma16 	= -1;	/* Set this for modules that need it */
+int type 	= 0;	/* Can set this to a specific card type */
+int mad16 	= 0;	/* Set mad16=1 to load this as support for mad16 */
+int trix 	= 0;	/* Set trix=1 to load this as support for trix */
+int pas2 	= 0;	/* Set pas2=1 to load this as support for pas2 */
+int support	= 0;	/* Set support to load this as a support module */
+int sm_games	= 0;	/* Mixer - see sb_mixer.c */
+int acer	= 0;	/* Do acer notebook init */
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+int isapnp      = 1;
+int isapnpjump  = 0;
+int nosbwave    = 0;	/* This option will be removed when the new awe_wave driver will be in the kernel tree */
 #else
-int isapnp 		= 0;
+int isapnp 	= 0;
 #endif
 
 MODULE_DESCRIPTION("Soundblaster driver");
 
-MODULE_PARM(io, 	"i");
-MODULE_PARM(irq, 	"i");
-MODULE_PARM(dma, 	"i");
-MODULE_PARM(dma16, 	"i");
-MODULE_PARM(mpu_io, 	"i");
-MODULE_PARM(type, 	"i");
-MODULE_PARM(mad16, 	"i");
-MODULE_PARM(support, 	"i");
-MODULE_PARM(trix, 	"i");
-MODULE_PARM(pas2, 	"i");
-MODULE_PARM(sm_games, 	"i");
-MODULE_PARM(esstype, 	"i");
-MODULE_PARM(acer, 	"i");
+MODULE_PARM(io,		"i");
+MODULE_PARM(irq,	"i");
+MODULE_PARM(dma,	"i");
+MODULE_PARM(dma16,	"i");
+MODULE_PARM(mpu_io,	"i");
+MODULE_PARM(type,	"i");
+MODULE_PARM(mad16,	"i");
+MODULE_PARM(support,	"i");
+MODULE_PARM(trix,	"i");
+MODULE_PARM(pas2,	"i");
+MODULE_PARM(sm_games,	"i");
+MODULE_PARM(esstype,	"i");
+MODULE_PARM(acer,	"i");
 
 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
-MODULE_PARM(isapnp, 	"i");
-MODULE_PARM(isapnpjump, "i");
+MODULE_PARM(isapnp,	"i");
+MODULE_PARM(isapnpjump,	"i");
 MODULE_PARM(nosbwave,	"i");
 MODULE_PARM_DESC(isapnp,	"When set to 0, Plug & Play support will be disabled");
-MODULE_PARM_DESC(isapnpjump, 	"Jumps to a specific slot in the driver's PnP table. Use the source, Luke.");
-MODULE_PARM_DESC(nosbwave,		"Disable SB AWE 32/64 Wavetable initialization. Use this option with the new awe_wave driver.");
+MODULE_PARM_DESC(isapnpjump,	"Jumps to a specific slot in the driver's PnP table. Use the source, Luke.");
+MODULE_PARM_DESC(nosbwave,	"Disable SB AWE 32/64 Wavetable initialization. Use this option with the new awe_wave driver.");
 #endif
 
-MODULE_PARM_DESC(io, 		"Soundblaster i/o base address (0x220,0x240,0x260,0x280)");
+MODULE_PARM_DESC(io,		"Soundblaster i/o base address (0x220,0x240,0x260,0x280)");
 MODULE_PARM_DESC(irq,		"IRQ (5,7,9,10)");
 MODULE_PARM_DESC(dma,		"8-bit DMA channel (0,1,3)");
 MODULE_PARM_DESC(dma16,		"16-bit DMA channel (5,6,7)");
@@ -211,7 +208,7 @@
 
 void *smw_free = NULL;
 
-#if defined CONFIGISAPNP || defined CONFIG_ISAPNP_MODULE
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
 
 /* That's useful. */
 
@@ -253,7 +250,7 @@
 			hw_config->irq 		= sb_dev->irq_resource[0].start;
 			hw_config->dma 		= sb_dev->dma_resource[0].start;
 			hw_config->dma2 	= sb_dev->dma_resource[1].start;
-			mpu_config->io_base = sb_dev->resource[1].start;
+			mpu_config->io_base	= sb_dev->resource[1].start;
 		}
 	}
 	return(sb_dev);
@@ -270,8 +267,8 @@
 			hw_config->io_base 	= sb_dev->resource[0].start;
 			hw_config->irq 		= sb_dev->irq_resource[0].start;
 			hw_config->dma 		= sb_dev->dma_resource[0].start;
-			hw_config->dma2 	= sb_dev->dma_resource[1].start;
-			mpu_config->io_base = sb_dev->resource[2].start;
+			hw_config->dma2		= sb_dev->dma_resource[1].start;
+			mpu_config->io_base	= sb_dev->resource[2].start;
 		}
 	}
 	return(sb_dev);
@@ -291,7 +288,7 @@
 	 */
 
 	if((sb_dev = isapnp_find_dev(bus,
-				ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), NULL)))
+		ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), NULL)))
 	{
 #ifdef CMI8330_DMA0BAD
 		int dmahack = 0;
@@ -299,9 +296,9 @@
 		sb_dev->prepare(sb_dev);
 		
 		/*  This device doesn't work with DMA 0, so we must allocate
-		 *	it to prevent PnP routines to assign it to the card.
+		 *  it to prevent PnP routines to assign it to the card.
 		 *
-		 *	I know i could have inlined the following lines, but it's cleaner
+		 *  I know i could have inlined the following lines, but it's cleaner
 		 *  this way.
 		 */
 	
@@ -327,12 +324,9 @@
 		}
 
 #ifdef CMI8330_DMA0BAD
-		if(dmahack)
-			free_dma(0);
+		if(dmahack) free_dma(0);
 #endif
-
 		if(!sb_dev) return(NULL);
-
 	}
 	else
 		printk(KERN_ERR "sb: CMI8330 panic: sb base not found\n");
@@ -340,9 +334,8 @@
 	/*  @H@0001:mpu
 	 */
 
-#ifdef CONFIG_MIDI
 	if((mpu_dev = isapnp_find_dev(bus,
-				ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), NULL)))
+		ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), NULL)))
 	{
 		mpu_dev->prepare(mpu_dev);
 
@@ -359,17 +352,15 @@
 	}
 	else
 		printk(KERN_ERR "sb: CMI8330 panic: mpu not found\n");
-#endif
 
 
 	/*  @P@:Gameport
 	 */
 
 	if((jp_dev = isapnp_find_dev(bus,
-				ISAPNP_VENDOR('@','P','@'), ISAPNP_FUNCTION(0x0001), NULL)))
+		ISAPNP_VENDOR('@','P','@'), ISAPNP_FUNCTION(0x0001), NULL)))
 	{
 		jp_dev->prepare(jp_dev);
-		
 
 		if((jp_dev = activate_dev("CMI8330", "gameport", jp_dev)))
 			show_base("CMI8330", "gameport", &jp_dev->resource[0]);
@@ -382,7 +373,7 @@
 
 #if defined(CONFIG_SOUND_YM3812) || defined(CONFIG_SOUND_YM3812_MODULE)
 	if((wss_dev = isapnp_find_dev(bus,
-				ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), NULL)))
+		ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), NULL)))
 	{
 		wss_dev->prepare(wss_dev);
 
@@ -405,7 +396,7 @@
 
 /* Specific support for awe will be dropped when:
  * a) The new awe_wawe driver with PnP support will be introduced in the kernel
- * b) The joystick driver will support PnP
+ * b) The joystick driver will support PnP - a little patch is available from me....hint, hint :-)
  */
 
 static struct pci_dev *sb_init_awe(struct pci_bus *bus, struct pci_dev *card, struct address_info *hw_config, struct address_info *mpu_config)
@@ -430,7 +421,7 @@
 
 			mpu_config->io_base	= sb_dev->resource[1].start;
 
-			show_base("AWE", "sb", 		&sb_dev->resource[0]);
+			show_base("AWE", "sb",		&sb_dev->resource[0]);
 			show_base("AWE", "mpu", 	&sb_dev->resource[1]);
 			show_base("AWE", "opl3",	&sb_dev->resource[2]);
 		}
@@ -445,7 +436,7 @@
 	 *  CTL7001:Game SB32
 	 */
 
-	if( (jp_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x7002), NULL)) ||
+	if(	(jp_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x7002), NULL)) ||
 		(jp_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x7001), NULL)) )
 	{
 		jp_dev->prepare(jp_dev);
@@ -459,12 +450,13 @@
 
 	/*  CTL0022:WaveTable SB64
 	 *  CTL0021:WaveTable SB32
+	 *  CTL0023:WaveTable Sb64
 	 */
 
 	if( nosbwave == 0 &&
-	   	( (wt_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0023), NULL)) ||
-		  (wt_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0022), NULL)) ||
-		  (wt_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0021), NULL)) ))
+   	( ( wt_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0023), NULL)) ||
+	  ( wt_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0022), NULL)) ||
+	  ( wt_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0021), NULL)) ))
 	{
 		wt_dev->prepare(wt_dev);
 		
@@ -478,26 +470,6 @@
 	else
 		printk(KERN_ERR "sb: AWE panic: wavetable not found\n");
 
-
-	/*  CTL2011:IDE SB32/64
-	 */
-
-/* No reasons to enable this... or not? */
-/*
-	if( (ide_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x2011), NULL)) )
-	{
-		ide_dev->prepare(ide_dev);
-		
-		if((ide_dev = activate_dev("AWE", "IDE", ide_dev)))
-		{
-			show_base("AWE", "IDE 1", &ide_dev->resource[0]);
-			show_base("AWE", "IDE 2", &ide_dev->resource[1]);
-		}
-	}
-	else
-		printk(KERN_ERR "sb: AWE panic: IDE not found\n");
-*/
-
 	printk(KERN_INFO "sb: AWE mail reports to Alessandro Zummo <azummo@ita.flashnet.it>\n");
 
 	return(sb_dev);
@@ -508,31 +480,31 @@
 
 static struct { unsigned short vendor, function, flags; struct pci_dev * (*initfunc)(struct pci_bus *, struct pci_dev *, struct address_info *, struct address_info *); char *name; }
 isapnp_sb_list[] __initdata = {
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), SBF_DEV, &sb_init_generic,	"Sound Blaster 16" },
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), SBF_DEV, &sb_init_generic,	"Sound Blaster 16" },
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), SBF_DEV, &sb_init_generic,	"Sound Blaster 16" },
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042), SBF_DEV, &sb_init_generic,	"Sound Blaster 16" },
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0043), SBF_DEV, &sb_init_generic,	"Sound Blaster 16" },
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), SBF_DEV, &sb_init_generic,	"Sound Blaster 16" },
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044), 0,	   &sb_init_awe,		"Sound Blaster 32" },
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0039), 0,	   &sb_init_awe,		"Sound Blaster AWE 32" },
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x009D), 0,	   &sb_init_awe,		"Sound Blaster AWE 64" },
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x00C5), 0,	   &sb_init_awe,		"Sound Blaster AWE 64" },
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x00E4), 0,	   &sb_init_awe,		"Sound Blaster AWE 64" },
-	{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868), SBF_DEV, &sb_init_ess,		"ESS 1868" },
-	{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611), SBF_DEV, &sb_init_ess,		"ESS 1868" },
-	{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), SBF_DEV, &sb_init_ess,		"ESS 1869" },
-	{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878), SBF_DEV, &sb_init_ess,		"ESS 1878" },
-	{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879), SBF_DEV, &sb_init_ess,		"ESS 1879" },
-	{ISAPNP_VENDOR('C','M','I'), ISAPNP_FUNCTION(0x0001), 0,	   &sb_init_cmi,		"CMI 8330 SoundPRO" },
-    {0}
+	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), SBF_DEV,	&sb_init_generic,	"Sound Blaster 16" },
+	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), SBF_DEV,	&sb_init_generic,	"Sound Blaster 16" },
+	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), SBF_DEV,	&sb_init_generic,	"Sound Blaster 16" },
+	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042), SBF_DEV,	&sb_init_generic,	"Sound Blaster 16" },
+	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0043), SBF_DEV,	&sb_init_generic,	"Sound Blaster 16" },
+	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), SBF_DEV,	&sb_init_generic,	"Sound Blaster 16" },
+	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044), 0,	&sb_init_awe,		"Sound Blaster 32" },
+	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0039), 0,	&sb_init_awe,		"Sound Blaster AWE 32" },
+	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x009D), 0,	&sb_init_awe,		"Sound Blaster AWE 64" },
+	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x00C5), 0,	&sb_init_awe,		"Sound Blaster AWE 64" },
+	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x00E4), 0,	&sb_init_awe,		"Sound Blaster AWE 64" },
+	{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868), SBF_DEV,	&sb_init_ess,		"ESS 1868" },
+	{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611), SBF_DEV,	&sb_init_ess,		"ESS 1868" },
+	{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), SBF_DEV,	&sb_init_ess,		"ESS 1869" },
+	{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878), SBF_DEV,	&sb_init_ess,		"ESS 1878" },
+	{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879), SBF_DEV,	&sb_init_ess,		"ESS 1879" },
+	{ISAPNP_VENDOR('C','M','I'), ISAPNP_FUNCTION(0x0001), 0,	&sb_init_cmi,		"CMI 8330 SoundPRO" },
+	{0}
 };
 
 static int __init sb_init_isapnp(struct address_info *hw_config, struct address_info *mpu_config, struct pci_bus *bus, struct pci_dev *card, int slot)
 {
 	struct pci_dev *idev = NULL;
 
-    /* You missed the init func? That's bad. */
+	/* You missed the init func? That's bad. */
 	if(isapnp_sb_list[slot].initfunc)
 	{
 		char *busname = bus->name[0] ? bus->name : isapnp_sb_list[slot].name;
@@ -587,9 +559,9 @@
 			struct pci_bus *bus = NULL;
 				
 			while ((bus = isapnp_find_card(
-						       isapnp_sb_list[i].vendor,
-						       isapnp_sb_list[i].function,
-						       bus))) {
+					isapnp_sb_list[i].vendor,
+					isapnp_sb_list[i].function,
+					bus))) {
 	
 				if(sb_init_isapnp(hw_config, mpu_config, bus, NULL, i))
 					return 0;
@@ -608,9 +580,9 @@
 			struct pci_dev *card = NULL;
 
 			while ((card = isapnp_find_dev(NULL,
-						       isapnp_sb_list[i].vendor,
-						       isapnp_sb_list[i].function,
-						       card))) {
+					isapnp_sb_list[i].vendor,
+					isapnp_sb_list[i].function,
+					card))) {
 
 				if(sb_init_isapnp(hw_config, mpu_config, card->bus, card, i))
 					return 0;
@@ -632,7 +604,7 @@
 			able to disable PNP support for this single driver!
 		*/
 
-#if defined CONFIGISAPNP || defined CONFIG_ISAPNP_MODULE			
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE			
 		if(isapnp && (sb_probe_isapnp(&config, &config_mpu) < 0) )
 		{
 			printk(KERN_NOTICE "sb_card: No ISAPnP cards found, trying standard ones...\n");
@@ -647,10 +619,10 @@
 				return -EINVAL;
 			}
 
-			config.io_base 	= io;
-			config.irq 		= irq;
-			config.dma 		= dma;
-			config.dma2 	= dma16;
+			config.io_base	= io;
+			config.irq	= irq;
+			config.dma	= dma;
+			config.dma2	= dma16;
 		}
 
 		config.card_subtype = type;
@@ -686,7 +658,6 @@
 	if(sb_dev)	sb_dev->deactivate(sb_dev);
 	if(jp_dev)	jp_dev->deactivate(jp_dev);
 	if(wt_dev)	wt_dev->deactivate(wt_dev);
-/*	if(ide_dev)	wt_dev->deactivate(ide_dev); */
 	if(mpu_dev)	mpu_dev->deactivate(mpu_dev);
 	if(wss_dev)	wss_dev->deactivate(wss_dev);
 }
@@ -716,5 +687,3 @@
 EXPORT_SYMBOL(attach_sbmpu);
 EXPORT_SYMBOL(probe_sbmpu);
 EXPORT_SYMBOL(unload_sbmpu);
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c
--- v2.3.47/linux/drivers/sound/sb_common.c	Mon Oct  4 15:49:30 1999
+++ linux/drivers/sound/sb_common.c	Thu Feb 24 22:12:57 2000
@@ -23,12 +23,6 @@
 #include "sound_config.h"
 #include "sound_firmware.h"
 
-#ifdef CONFIG_SBDSP
-
-#ifndef CONFIG_AUDIO
-#error You will need to configure the sound driver with CONFIG_AUDIO option.
-#endif
-
 #include "sb_mixer.h"
 #include "sb.h"
 
@@ -114,11 +108,9 @@
 	{
 		src = sb_getmixer(devc, IRQ_STAT);	/* Interrupt source register */
 
-#if defined(CONFIG_MIDI)&& defined(CONFIG_UART401)
 		if (src & 4)						/* MPU401 interrupt */
 			if(devc->midi_irq_cookie)
 				uart401intr(devc->irq, devc->midi_irq_cookie, NULL);
-#endif
 
 		if (!(src & 3))
 			return;	/* Not a DSP interrupt */
@@ -139,9 +131,7 @@
 				break;
 
 			case IMODE_MIDI:
-#ifdef CONFIG_MIDI
 				sb_midi_interrupt(devc);
-#endif
 				break;
 
 			default:
@@ -284,7 +274,6 @@
 	return 1;
 }
 
-#if defined(CONFIG_MIDI) && defined(CONFIG_UART401)
 static void sb16_set_mpu_port(sb_devc * devc, struct address_info *hw_config)
 {
 	/*
@@ -307,7 +296,6 @@
 			printk(KERN_ERR "SB16: Invalid MIDI I/O port %x\n", hw_config->io_base);
 	}
 }
-#endif
 
 static int sb16_set_irq_hw(sb_devc * devc, int level)
 {
@@ -807,10 +795,8 @@
 		if (devc->major == 3 || devc->major == 4)
 			sb_mixer_init(devc);
 
-#ifdef CONFIG_MIDI
 	if (!(devc->caps & SB_NO_MIDI))
 		sb_dsp_midi_init(devc);
-#endif
 
 	if (hw_config->name == NULL)
 		hw_config->name = "Sound Blaster (8 BIT/MONO ONLY)";
@@ -971,8 +957,6 @@
 	sb_setmixer(devc, reg, value);
 }
 
-#ifdef CONFIG_MIDI
-
 /*
  *	MPU401 MIDI initialization.
  */
@@ -1200,10 +1184,8 @@
 #endif
 		return;
 	}
-#if defined(CONFIG_UART401)
 	attach_uart401(hw_config);
 	last_sb->midi_irq_cookie=midi_devs[hw_config->slots[4]]->devc;
-#endif
 }
 
 int probe_sbmpu(struct address_info *hw_config)
@@ -1244,7 +1226,6 @@
 	}
 #endif
 
-#if defined(CONFIG_UART401)
 	if (check_region(hw_config->io_base, 4))
 	{
 		printk(KERN_ERR "sbmpu: I/O port conflict (%x)\n", hw_config->io_base);
@@ -1279,9 +1260,6 @@
 			return 0;
 	}
 	return probe_uart401(hw_config);
-#else
-	return 0;
-#endif
 }
 
 void unload_sbmpu(struct address_info *hw_config)
@@ -1292,23 +1270,5 @@
 		return;
 	}
 #endif
-#if defined(CONFIG_UART401)
 	unload_uart401(hw_config);
-#endif
-}
-#else				/* !CONFIG_MIDI */
-
-void unload_sbmpu(struct address_info *hw_config)
-{
-}
-
-int probe_sbmpu(struct address_info *hw_config)
-{
-	return 0;
 }
-
-void attach_sbmpu(struct address_info *hw_config)
-{
-}
-#endif
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sb_midi.c linux/drivers/sound/sb_midi.c
--- v2.3.47/linux/drivers/sound/sb_midi.c	Thu Sep 10 16:37:26 1998
+++ linux/drivers/sound/sb_midi.c	Thu Feb 24 22:12:57 2000
@@ -14,9 +14,6 @@
 #include <linux/config.h>
 #include "sound_config.h"
 
-#ifdef CONFIG_SBDSP
-#ifdef CONFIG_MIDI
-
 #include "sb.h"
 #undef SB_TEST_IRQ
 
@@ -210,6 +207,3 @@
 	midi_devs[dev]->converter->id = "SBMIDI";
 	sequencer_init();
 }
-
-#endif
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sb_mixer.c linux/drivers/sound/sb_mixer.c
--- v2.3.47/linux/drivers/sound/sb_mixer.c	Mon Jul  5 19:58:25 1999
+++ linux/drivers/sound/sb_mixer.c	Thu Feb 24 22:12:57 2000
@@ -19,7 +19,6 @@
 #include <linux/config.h>
 #include "sound_config.h"
 
-#ifdef CONFIG_SBDSP
 #define __SB_MIXER_C__
 
 #include "sb.h"
@@ -78,27 +77,6 @@
 MIX_ENT(SOUND_MIXER_RECLEV,	0x00, 0, 0, 0x00, 0, 0)
 };
 
-#ifdef	__SGNXPRO__
-#if 0
-static mixer_tab sgnxpro_mix = { 	/* not used anywhere */
-MIX_ENT(SOUND_MIXER_VOLUME,	0x22, 7, 4, 0x22, 3, 4),
-MIX_ENT(SOUND_MIXER_BASS,	0x46, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE,	0x44, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH,	0x26, 7, 4, 0x26, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM,	0x04, 7, 4, 0x04, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER,	0x42, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE,	0x2e, 7, 4, 0x2e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC,	0x0a, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_CD,		0x28, 7, 4, 0x28, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX,	0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM,	0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV,	0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_IGAIN,	0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_OGAIN,	0x00, 0, 0, 0x00, 0, 0)
-};
-#endif
-#endif
-
 static mixer_tab sb16_mix = {
 MIX_ENT(SOUND_MIXER_VOLUME,	0x30, 7, 5, 0x31, 7, 5),
 MIX_ENT(SOUND_MIXER_BASS,	0x46, 7, 4, 0x47, 7, 4),
@@ -763,5 +741,3 @@
 	sb_mixer_reset(devc);
 	return 1;
 }
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sb_mixer.h linux/drivers/sound/sb_mixer.h
--- v2.3.47/linux/drivers/sound/sb_mixer.h	Mon Jul  5 19:58:25 1999
+++ linux/drivers/sound/sb_mixer.h	Thu Feb 24 22:12:57 2000
@@ -24,9 +24,6 @@
  *
  */
 #include <linux/config.h>
-#include "legacy.h"
-
-#ifdef CONFIG_SBDSP
 
 /*
  * Mixer registers
@@ -108,6 +105,3 @@
 #define ALS007_LINE	6
 #define ALS007_CD	2
 #define ALS007_SYNTH	7
-
-#endif
-
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sequencer.c linux/drivers/sound/sequencer.c
--- v2.3.47/linux/drivers/sound/sequencer.c	Tue May 11 23:40:50 1999
+++ linux/drivers/sound/sequencer.c	Thu Feb 24 22:12:57 2000
@@ -15,15 +15,12 @@
  * Alan Cox	   : reformatted and fixed a pair of null pointer bugs
  */
 #include <linux/config.h>
-
 #include <linux/kmod.h>
 
-
 #define SEQUENCER_C
 #include "sound_config.h"
-
-#ifdef CONFIG_SEQUENCER
 #include "softoss.h"
+
 int             (*softsynthp) (int cmd, int parm1, int parm2, unsigned long parm3) = NULL;
 
 #include "midi_ctrl.h"
@@ -719,9 +716,7 @@
 	switch (cmd)
 	{
 		case LOCL_STARTAUDIO:
-#ifdef CONFIG_AUDIO
 			DMAbuf_start_devices(parm);
-#endif
 			break;
 
 		default:
@@ -1692,9 +1687,7 @@
 
 	if (sequencer_ok)
 		return;
-#ifdef CONFIG_MIDI
 	MIDIbuf_init();
-#endif
 	queue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * EV_SZ);
 	if (queue == NULL)
 	{
@@ -1724,5 +1717,3 @@
 		iqueue=NULL;
 	}
 }
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sequencer_syms.c linux/drivers/sound/sequencer_syms.c
--- v2.3.47/linux/drivers/sound/sequencer_syms.c	Thu May 14 10:33:17 1998
+++ linux/drivers/sound/sequencer_syms.c	Thu Feb 24 22:12:57 2000
@@ -9,7 +9,6 @@
 char sequencer_syms_symbol;
 
 #include "sound_config.h"
-
 #include "sound_calls.h"
 
 EXPORT_SYMBOL(note_to_freq);
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sgalaxy.c linux/drivers/sound/sgalaxy.c
--- v2.3.47/linux/drivers/sound/sgalaxy.c	Mon Jul  5 19:58:25 1999
+++ linux/drivers/sound/sgalaxy.c	Thu Feb 24 22:12:57 2000
@@ -24,8 +24,6 @@
 #include "sound_config.h"
 #include "soundmodule.h"
 
-#if defined(CONFIG_SGALAXY) || defined (MODULE)
-
 static void sleep( unsigned howlong )
 {
 	current->state   = TASK_INTERRUPTIBLE;
@@ -182,5 +180,4 @@
 	SOUND_LOCK_END;
 }
 
-#endif
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/softoss.c linux/drivers/sound/softoss.c
--- v2.3.47/linux/drivers/sound/softoss.c	Fri Jul 10 14:03:36 1998
+++ linux/drivers/sound/softoss.c	Thu Feb 24 22:12:57 2000
@@ -30,8 +30,6 @@
 
 #include "sound_config.h"
 #include "soundmodule.h"
-
-#ifdef CONFIG_SOFTOSS
 #include "softoss.h"
 #include <linux/ultrasound.h>
 
@@ -1529,5 +1527,4 @@
 	sound_unload_timerdev(devc->timerdev);
 	SOUND_LOCK_END;
 }
-#endif
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/softoss_rs.c linux/drivers/sound/softoss_rs.c
--- v2.3.47/linux/drivers/sound/softoss_rs.c	Sun Dec 27 10:53:45 1998
+++ linux/drivers/sound/softoss_rs.c	Thu Feb 24 22:12:57 2000
@@ -17,8 +17,6 @@
 
 
 #include "sound_config.h"
-
-#ifdef CONFIG_SOFTOSS
 #include "softoss.h"
 
 void softsynth_resample_loop(short *buf, int loops)
@@ -130,4 +128,3 @@
 		}
 	}			/* Mix one sample */
 }
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sound_config.h linux/drivers/sound/sound_config.h
--- v2.3.47/linux/drivers/sound/sound_config.h	Thu Dec 31 12:03:48 1998
+++ linux/drivers/sound/sound_config.h	Thu Feb 24 22:12:57 2000
@@ -18,7 +18,6 @@
 #include <linux/fs.h>
 #include <linux/sound.h>
 
-#include "legacy.h"
 #include "os.h"
 #include "soundvers.h"
 
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sound_timer.c linux/drivers/sound/sound_timer.c
--- v2.3.47/linux/drivers/sound/sound_timer.c	Tue Jun  1 23:25:48 1999
+++ linux/drivers/sound/sound_timer.c	Thu Feb 24 22:12:57 2000
@@ -17,8 +17,6 @@
 
 #include "sound_config.h"
 
-#if defined(CONFIG_SEQUENCER)
-
 static volatile int initialized = 0, opened = 0, tmr_running = 0;
 static volatile time_t tmr_offs, tmr_ctr;
 static volatile unsigned long ticks_offs;
@@ -318,5 +316,3 @@
 	strcpy(sound_timer.info.name, name);
 	sound_timer_devs[n] = &sound_timer;
 }
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
--- v2.3.47/linux/drivers/sound/soundcard.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/sound/soundcard.c	Thu Feb 24 22:12:57 2000
@@ -45,8 +45,11 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/smp_lock.h>
-
 #include "soundmodule.h"
+
+/* From obsolete legacy.h */
+#define SELECTED_SOUND_OPTIONS 0x0
+
 struct notifier_block *sound_locker=(struct notifier_block *)0;
 static int lock_depth = 0;
 
@@ -219,9 +222,6 @@
 	}
 	if (!sound_started)
 		len += sprintf(buffer + len, "\n\n***** Sound driver not started *****\n\n");
-#ifndef CONFIG_AUDIO
-	len += sprintf(buffer + len, "\nAudio devices: NOT ENABLED IN CONFIG\n");
-#else
 	len += sprintf(buffer + len, "\nAudio devices:\n");
 	for (i = 0; (i < num_audiodevs) && (pos <= offset + length); i++) {
 		if (audio_devs[i] == NULL)
@@ -234,11 +234,7 @@
 			begin = pos;
 		}
 	}
-#endif
 
-#ifndef CONFIG_SEQUENCER
-	len += sprintf(buffer + len, "\nSynth devices: NOT ENABLED IN CONFIG\n");
-#else
 	len += sprintf(buffer + len, "\nSynth devices:\n");
 	for (i = 0; (i < num_synths) && (pos <= offset + length); i++) {
 		if (synth_devs[i] == NULL)
@@ -250,11 +246,7 @@
 			begin = pos;
 		}
 	}
-#endif
 
-#ifndef CONFIG_MIDI
-	len += sprintf(buffer + len, "\nMidi devices: NOT ENABLED IN CONFIG\n");
-#else
 	len += sprintf(buffer + len, "\nMidi devices:\n");
 	for (i = 0; (i < num_midis) && (pos <= offset + length); i++) {
 		if (midi_devs[i] == NULL)
@@ -266,9 +258,7 @@
 			begin = pos;
 		}
 	}
-#endif
 
-#ifdef CONFIG_SEQUENCER
 	len += sprintf(buffer + len, "\nTimers:\n");
 
 	for (i = 0; (i < num_sound_timers) && (pos <= offset + length); i++) {
@@ -281,7 +271,6 @@
 			begin = pos;
 		}
 	}
-#endif
 
 	len += sprintf(buffer + len, "\nMixers:\n");
 	for (i = 0; (i < num_mixers) && (pos <= offset + length); i++) {
@@ -388,25 +377,19 @@
 		ret = sndstat_file_read(file, buf, count, ppos);
 		break;
 
-#ifdef CONFIG_AUDIO
 	case SND_DEV_DSP:
 	case SND_DEV_DSP16:
 	case SND_DEV_AUDIO:
 		ret = audio_read(dev, file, buf, count);
 		break;
-#endif
 
-#ifdef CONFIG_SEQUENCER
 	case SND_DEV_SEQ:
 	case SND_DEV_SEQ2:
 		ret = sequencer_read(dev, file, buf, count);
 		break;
-#endif
 
-#ifdef CONFIG_MIDI
 	case SND_DEV_MIDIN:
 		ret = MIDIbuf_read(dev, file, buf, count);
-#endif
 	}
 	unlock_kernel();
 	return ret;
@@ -420,26 +403,20 @@
 	lock_kernel();
 	DEB(printk("sound_write(dev=%d, count=%d)\n", dev, count));
 	switch (dev & 0x0f) {
-#ifdef CONFIG_SEQUENCER
 	case SND_DEV_SEQ:
 	case SND_DEV_SEQ2:
 		ret =  sequencer_write(dev, file, buf, count);
 		break;
-#endif
 
-#ifdef CONFIG_AUDIO
 	case SND_DEV_DSP:
 	case SND_DEV_DSP16:
 	case SND_DEV_AUDIO:
 		ret = audio_write(dev, file, buf, count);
 		break;
-#endif
 
-#ifdef CONFIG_MIDI
 	case SND_DEV_MIDIN:
 		ret =  MIDIbuf_write(dev, file, buf, count);
 		break;
-#endif
 	}
 	unlock_kernel();
 	return ret;
@@ -483,29 +460,23 @@
 			return -ENXIO;
 		break;
 
-#ifdef CONFIG_SEQUENCER
 	case SND_DEV_SEQ:
 	case SND_DEV_SEQ2:
 		if ((retval = sequencer_open(dev, file)) < 0)
 			return retval;
 		break;
-#endif
 
-#ifdef CONFIG_MIDI
 	case SND_DEV_MIDIN:
 		if ((retval = MIDIbuf_open(dev, file)) < 0)
 			return retval;
 		break;
-#endif
 
-#ifdef CONFIG_AUDIO
 	case SND_DEV_DSP:
 	case SND_DEV_DSP16:
 	case SND_DEV_AUDIO:
 		if ((retval = audio_open(dev, file)) < 0)
 			return retval;
 		break;
-#endif
 
 	default:
 		printk(KERN_ERR "Invalid minor device %d\n", dev);
@@ -531,26 +502,20 @@
 	case SND_DEV_CTL:
 		break;
 		
-#ifdef CONFIG_SEQUENCER
 	case SND_DEV_SEQ:
 	case SND_DEV_SEQ2:
 		sequencer_release(dev, file);
 		break;
-#endif
 
-#ifdef CONFIG_MIDI
 	case SND_DEV_MIDIN:
 		MIDIbuf_release(dev, file);
 		break;
-#endif
 
-#ifdef CONFIG_AUDIO
 	case SND_DEV_DSP:
 	case SND_DEV_DSP16:
 	case SND_DEV_AUDIO:
 		audio_release(dev, file);
 		break;
-#endif
 
 	default:
 		printk(KERN_ERR "Sound error: Releasing unknown device 0x%02x\n", dev);
@@ -641,13 +606,11 @@
 	    (dev & 0x0f) != SND_DEV_CTL) {              
 		dtype = dev & 0x0f;
 		switch (dtype) {
-#ifdef CONFIG_AUDIO
 		case SND_DEV_DSP:
 		case SND_DEV_DSP16:
 		case SND_DEV_AUDIO:
 			return sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev,
 						 cmd, (caddr_t)arg);
-#endif
 			
 		default:
 			return sound_mixer_ioctl(dev >> 4, cmd, (caddr_t)arg);
@@ -661,25 +624,19 @@
 			return set_mixer_levels((caddr_t)arg);
 		return sound_mixer_ioctl(dev >> 4, cmd, (caddr_t)arg);
 
-#ifdef CONFIG_SEQUENCER
 	case SND_DEV_SEQ:
 	case SND_DEV_SEQ2:
 		return sequencer_ioctl(dev, file, cmd, (caddr_t)arg);
-#endif
 
-#ifdef CONFIG_AUDIO
 	case SND_DEV_DSP:
 	case SND_DEV_DSP16:
 	case SND_DEV_AUDIO:
 		return audio_ioctl(dev, file, cmd, (caddr_t)arg);
 		break;
-#endif
 
-#ifdef CONFIG_MIDI
 	case SND_DEV_MIDIN:
 		return MIDIbuf_ioctl(dev, file, cmd, (caddr_t)arg);
 		break;
-#endif
 
 	}
 	return -EINVAL;
@@ -692,23 +649,17 @@
 
 	DEB(printk("sound_poll(dev=%d)\n", dev));
 	switch (dev & 0x0f) {
-#ifdef CONFIG_SEQUENCER
 	case SND_DEV_SEQ:
 	case SND_DEV_SEQ2:
 		return sequencer_poll(dev, file, wait);
-#endif
 
-#ifdef CONFIG_MIDI
 	case SND_DEV_MIDIN:
 		return MIDIbuf_poll(dev, file, wait);
-#endif
 
-#ifdef CONFIG_AUDIO
 	case SND_DEV_DSP:
 	case SND_DEV_DSP16:
 	case SND_DEV_AUDIO:
 		return DMAbuf_poll(file, dev >> 4, wait);
-#endif
 	}
 	return 0;
 }
@@ -828,13 +779,11 @@
 	umode_t mode;
 	int *num;
 } dev_list[] = { /* list of minor devices */
-#ifdef CONFIG_AUDIO
 /* seems to be some confusion here -- this device is not in the device list */
 	{SND_DEV_DSP16,     "dspW",	 S_IWUGO | S_IRUSR | S_IRGRP,
 	 &num_audiodevs},
 	{SND_DEV_AUDIO,     "audio",	 S_IWUGO | S_IRUSR | S_IRGRP,
 	 &num_audiodevs},
-#endif /* CONFIG_AUDIO */
 };
 
 static char * 
@@ -903,12 +852,10 @@
 		return;		/* No cards detected */
 #endif
 
-#ifdef CONFIG_AUDIO
 	if (num_audiodevs || modular)	/* Audio devices present */
 	{
 		audio_init_devices();
 	}
-#endif
 #ifdef CONFIG_PROC_FS
 	if (!create_proc_info_entry("sound", 0, NULL, sound_proc_get_info))
 		printk(KERN_ERR "sound: registering /proc/sound failed\n");
@@ -1000,9 +947,7 @@
 	if (chrdev_registered)
 		destroy_special_devices();
 
-#ifdef CONFIG_SEQUENCER
 	sound_stop_timer();
-#endif
 
 #ifdef CONFIG_LOWLEVEL_SOUND
 	{
@@ -1093,8 +1038,6 @@
 	restore_flags(flags);
 }
 
-#ifdef CONFIG_SEQUENCER
-
 static void do_sequencer_timer(unsigned long dummy)
 {
 	sequencer_timer(0);
@@ -1129,7 +1072,6 @@
 {
 	del_timer(&seq_timer);;
 }
-#endif
 
 void conf_printf(char *name, struct address_info *hw_config)
 {
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sscape.c linux/drivers/sound/sscape.c
--- v2.3.47/linux/drivers/sound/sscape.c	Fri Jan 21 18:19:17 2000
+++ linux/drivers/sound/sscape.c	Thu Feb 24 22:12:57 2000
@@ -41,9 +41,6 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 
-
-#ifdef CONFIG_SSCAPE
-
 #include "coproc.h"
 
 /*
@@ -722,7 +719,6 @@
 	}
 #endif
 
-#if defined(CONFIG_MIDI) && defined(CONFIG_MPU_EMU)
 	if (probe_mpu401(hw_config))
 		hw_config->always_detect = 1;
 	hw_config->name = "SoundScape";
@@ -736,7 +732,6 @@
 		sscape_mididev = hw_config->slots[1];
 		midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
 	}
-#endif
 	sscape_write(devc, GA_INTENA_REG, 0x80);	/* Master IRQ enable */
 	devc->ok = 1;
 	devc->failed = 0;
@@ -1421,9 +1416,7 @@
 void unload_sscape(struct address_info *hw_config)
 {
 	release_region(devc->base + 2, 6);
-#if defined(CONFIG_MPU_EMU) && defined(CONFIG_MIDI)
 	unload_mpu401(hw_config);
-#endif
 }
 
 void unload_ss_ms_sound(struct address_info *hw_config)
@@ -1516,5 +1509,4 @@
 	unload_sscape(&mpu_config);
 }
 
-#endif
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/sys_timer.c linux/drivers/sound/sys_timer.c
--- v2.3.47/linux/drivers/sound/sys_timer.c	Mon Feb  1 14:04:42 1999
+++ linux/drivers/sound/sys_timer.c	Thu Feb 24 22:12:57 2000
@@ -20,8 +20,6 @@
 
 #include "sound_config.h"
 
-#ifdef CONFIG_SEQUENCER
-
 static volatile int opened = 0, tmr_running = 0;
 static volatile time_t tmr_offs, tmr_ctr;
 static volatile unsigned long ticks_offs;
@@ -289,5 +287,3 @@
 	def_tmr_ioctl,
 	def_tmr_arm
 };
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/trident.c linux/drivers/sound/trident.c
--- v2.3.47/linux/drivers/sound/trident.c	Thu Feb 10 17:11:14 2000
+++ linux/drivers/sound/trident.c	Sat Feb 26 20:22:08 2000
@@ -79,11 +79,11 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/spinlock.h>
+#include <linux/ac97_codec.h>
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
 
 #include "trident.h"
-#include "ac97_codec.h"
 
 #undef DEBUG
 
@@ -1131,7 +1131,7 @@
 		/* Midi - TODO */
 	}
 
-	/* manually clear interrupt status, bad hardware design, balme T^2 */
+	/* manually clear interrupt status, bad hardware design, blame T^2 */
 	outl((ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW),
 	     TRID_REG(card, T4D_MISCINT));
 	spin_unlock(&card->lock);
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/trix.c linux/drivers/sound/trix.c
--- v2.3.47/linux/drivers/sound/trix.c	Mon Jul  5 19:58:25 1999
+++ linux/drivers/sound/trix.c	Thu Feb 24 22:12:57 2000
@@ -23,15 +23,8 @@
 #include "sb.h"
 #include "sound_firmware.h"
 
-#ifdef CONFIG_TRIX
-
-#ifdef INCLUDE_TRIX_BOOT
 #include <linux/init.h>
 #include "trix_boot.h"
-#else
-static unsigned char *trix_boot = NULL;
-static int trix_boot_len = 0;
-#endif
 
 
 static int kilroy_was_here = 0;	/* Don't detect twice */
@@ -327,11 +320,7 @@
 	sb_initialized = 1;
 
 	hw_config->name = "AudioTrix SB";
-#ifdef CONFIG_SBDSP
 	return sb_dsp_detect(hw_config, 0, 0);
-#else
-	return 0;
-#endif
 }
 
 void attach_trix_sb(struct address_info *hw_config)
@@ -339,7 +328,6 @@
 	extern int sb_be_quiet;
 	int old_quiet;
 
-#ifdef CONFIG_SBDSP
 	hw_config->driver_use_1 = SB_NO_MIDI | SB_NO_MIXER | SB_NO_RECORDING;
 
 	/* Prevent false alarms */
@@ -349,20 +337,16 @@
 	sb_dsp_init(hw_config);
 
 	sb_be_quiet = old_quiet;
-#endif
 }
 
 void attach_trix_mpu(struct address_info *hw_config)
 {
-#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
 	hw_config->name = "AudioTrix Pro";
 	attach_uart401(hw_config);
-#endif
 }
 
 int probe_trix_mpu(struct address_info *hw_config)
 {
-#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
 	unsigned char conf;
 	static char irq_bits[] = {
 		-1, -1, -1, 1, 2, 3, -1, 4, -1, 5
@@ -420,9 +404,6 @@
 	trix_write(0x19, (trix_read(0x19) & 0x83) | conf);
 	mpu_initialized = 1;
 	return probe_uart401(hw_config);
-#else
-	return 0;
-#endif
 }
 
 void unload_trix_wss(struct address_info *hw_config)
@@ -445,16 +426,12 @@
 
 void unload_trix_mpu(struct address_info *hw_config)
 {
-#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
 	unload_uart401(hw_config);
-#endif
 }
 
 void unload_trix_sb(struct address_info *hw_config)
 {
-#ifdef CONFIG_SBDSP
 	sb_dsp_unload(hw_config, mpu);
-#endif
 }
 
 #ifdef MODULE
@@ -566,5 +543,4 @@
 	SOUND_LOCK_END;
 }
 
-#endif
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/uart401.c linux/drivers/sound/uart401.c
--- v2.3.47/linux/drivers/sound/uart401.c	Fri Jul 10 14:03:36 1998
+++ linux/drivers/sound/uart401.c	Thu Feb 24 22:12:57 2000
@@ -25,9 +25,6 @@
 #include "sound_config.h"
 #include "soundmodule.h"
 
-#ifdef CONFIG_UART401
-#ifdef CONFIG_MIDI
-
 typedef struct uart401_devc
 {
 	int             base;
@@ -482,12 +479,9 @@
 	SOUND_LOCK_END;
 }
 
-#endif
+#endif /* MODULE */
 
 EXPORT_SYMBOL(attach_uart401);
 EXPORT_SYMBOL(probe_uart401);
 EXPORT_SYMBOL(unload_uart401);
 EXPORT_SYMBOL(uart401intr);
-
-#endif
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/uart6850.c linux/drivers/sound/uart6850.c
--- v2.3.47/linux/drivers/sound/uart6850.c	Thu May 14 10:33:17 1998
+++ linux/drivers/sound/uart6850.c	Thu Feb 24 22:12:57 2000
@@ -24,9 +24,6 @@
  */
 
 #include "sound_config.h"
-
-#ifdef CONFIG_SOUND_UART6850
-#ifdef CONFIG_MIDI
 #include "soundmodule.h"
 
 static int uart6850_base = 0x330;
@@ -353,6 +350,4 @@
 	unload_uart6850(&cfg);
 	SOUND_LOCK_END;
 }
-#endif
-#endif
-#endif
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/v_midi.c linux/drivers/sound/v_midi.c
--- v2.3.47/linux/drivers/sound/v_midi.c	Sat Jun 13 10:23:52 1998
+++ linux/drivers/sound/v_midi.c	Thu Feb 24 22:12:57 2000
@@ -24,8 +24,6 @@
 #include "sound_config.h"
 #include "soundmodule.h"
 
-#ifdef CONFIG_VMIDI
-
 #include "v_midi.h"
 
 static vmidi_devc *v_devc[2] = { NULL, NULL};
@@ -52,7 +50,7 @@
 	SOUND_LOCK_END;
 }
 
-#endif
+#endif /* MODULE */
 
 /*
  * The DSP channel can be used either for input or output. Variable
@@ -297,5 +295,3 @@
 	sound_unload_mididev(midi2);
 	kfree(midi_mem);
 }
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/vidc.c linux/drivers/sound/vidc.c
--- v2.3.47/linux/drivers/sound/vidc.c	Thu Jun 17 01:11:35 1999
+++ linux/drivers/sound/vidc.c	Thu Feb 24 22:44:47 2000
@@ -1,128 +1,534 @@
 /*
- *	drivers/sound/vidc.c
+ * drivers/sound/vidc.c
  *
- *	Detection routine for the VIDC.
+ * VIDC20 audio driver.
  *
- *	Copyright (C) 1997 by Russell King <rmk@arm.uk.linux.org>
+ * Copyright (C) 1997-2000 by Russell King <rmk@arm.linux.org.uk>
+ *
+ * The VIDC20 sound hardware consists of the VIDC20 itself, a DAC and a DMA
+ * engine.  The DMA transfers fixed-format (16-bit little-endian linear)
+ * samples to the VIDC20, which then transfers this data serially to the
+ * DACs.  The samplerate is controlled by the VIDC.
+ *
+ * We currently support a mixer device, but it is currently non-functional.
  */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
 
-#include <asm/io.h>
+#include <asm/hardware.h>
 #include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/iomd.h>
+#include <asm/system.h>
+
 #include "sound_config.h"
 #include "soundmodule.h"
 #include "vidc.h"
 
-int vidc_busy;
+#ifndef _SIOC_TYPE
+#define _SIOC_TYPE(x)	_IOC_TYPE(x)
+#endif
+#ifndef _SIOC_NR
+#define _SIOC_NR(x)	_IOC_NR(x)
+#endif
+
+#define VIDC_SOUND_CLOCK	(250000)
+
+/*
+ * When using SERIAL SOUND mode (external DAC), the number of physical
+ * channels is fixed at 2.
+ */
+static int		vidc_busy;
+static int		vidc_adev;
+static int		vidc_audio_rate;
+static char		vidc_audio_format;
+static char		vidc_audio_channels;
+
+static unsigned char	vidc_level_l[SOUND_MIXER_NRDEVICES] = {
+	85,		/* master	*/
+	50,		/* bass		*/
+	50,		/* treble	*/
+	0,		/* synth	*/
+	75,		/* pcm		*/
+	0,		/* speaker	*/
+	100,		/* ext line	*/
+	0,		/* mic		*/
+	100,		/* CD		*/
+	0,
+};
+
+static unsigned char	vidc_level_r[SOUND_MIXER_NRDEVICES] = {
+	85,		/* master	*/
+	50,		/* bass		*/
+	50,		/* treble	*/
+	0,		/* synth	*/
+	75,		/* pcm		*/
+	0,		/* speaker	*/
+	100,		/* ext line	*/
+	0,		/* mic		*/
+	100,		/* CD		*/
+	0,
+};
+
+static unsigned int	vidc_audio_volume_l;	/* left PCM vol, 0 - 65536 */
+static unsigned int	vidc_audio_volume_r;	/* right PCM vol, 0 - 65536 */
+
+static void	(*old_mksound)(unsigned int hz, unsigned int ticks);
+extern void	(*kd_mksound)(unsigned int hz, unsigned int ticks);
+extern void	vidc_update_filler(int bits, int channels);
+extern int	softoss_dev;
 
-void vidc_update_filler(int format, int channels)
+static void
+vidc_mksound(unsigned int hz, unsigned int ticks)
 {
-	int fillertype;
+	printk("BEEP - %d %d!\n", hz, ticks);
+}
 
-#define TYPE(fmt,ch) (((fmt)<<2) | ((ch)&3))
+static void
+vidc_mixer_set(int mdev, unsigned int level)
+{
+	unsigned int lev_l = level & 0x007f;
+	unsigned int lev_r = (level & 0x7f00) >> 8;
+	unsigned int mlev_l, mlev_r;
+
+	if (lev_l > 100)
+		lev_l = 100;
+	if (lev_r > 100)
+		lev_r = 100;
+
+#define SCALE(lev,master)	((lev) * (master) * 65536 / 10000)
+
+	mlev_l = vidc_level_l[SOUND_MIXER_VOLUME];
+	mlev_r = vidc_level_r[SOUND_MIXER_VOLUME];
+
+	switch (mdev) {
+	case SOUND_MIXER_VOLUME:
+	case SOUND_MIXER_PCM:
+		vidc_level_l[mdev] = lev_l;
+		vidc_level_r[mdev] = lev_r;
+
+		vidc_audio_volume_l = SCALE(lev_l, mlev_l);
+		vidc_audio_volume_r = SCALE(lev_r, mlev_r);
+/*printk("VIDC: PCM vol %05X %05X\n", vidc_audio_volume_l, vidc_audio_volume_r);*/
+		break;
+	}
+#undef SCALE
+}
+
+static int vidc_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+{
+	unsigned int val;
+	unsigned int mdev;
+
+	if (_SIOC_TYPE(cmd) != 'M')
+		return -EINVAL;
+
+	mdev = _SIOC_NR(cmd);
+
+	if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
+		if (get_user(val, (unsigned int *)arg))
+			return -EFAULT;
+
+		if (mdev < SOUND_MIXER_NRDEVICES)
+			vidc_mixer_set(mdev, val);
+		else
+			return -EINVAL;
+	}
+
+	/*
+	 * Return parameters
+	 */
+	switch (mdev) {
+	case SOUND_MIXER_RECSRC:
+		val = 0;
+		break;
+
+	case SOUND_MIXER_DEVMASK:
+		val = SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_SYNTH;
+		break;
+
+	case SOUND_MIXER_STEREODEVS:
+		val = SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_SYNTH;
+		break;
+
+	case SOUND_MIXER_RECMASK:
+		val = 0;
+		break;
+
+	case SOUND_MIXER_CAPS:
+		val = 0;
+		break;
+
+	default:
+		if (mdev < SOUND_MIXER_NRDEVICES)
+			val = vidc_level_l[mdev] | vidc_level_r[mdev] << 8;
+		else
+			return -EINVAL;
+	}
+
+	return put_user(val, (unsigned int *)arg) ? -EFAULT : 0;
+}
+
+static unsigned int vidc_audio_set_format(int dev, unsigned int fmt)
+{
+	switch (fmt) {
+	default:
+		fmt = AFMT_S16_LE;
+	case AFMT_U8:
+	case AFMT_S8:
+	case AFMT_S16_LE:
+		vidc_audio_format = fmt;
+		vidc_update_filler(vidc_audio_format, vidc_audio_channels);
+	case AFMT_QUERY:
+		break;
+	}
+	return vidc_audio_format;
+}
+
+static int vidc_audio_set_speed(int dev, int rate)
+{
+	if (rate) {
+		unsigned int hwctrl, hwrate;
+		unsigned int newsize, new2size;
+
+		/*
+		 * If we have selected 44.1kHz, use the DAC clock.
+		 */
+		if (0 && rate == 44100) {
+			hwctrl = 0x00000002;
+			hwrate = 3;
+		} else {
+			hwctrl = 0x00000003;
+
+			hwrate = (((VIDC_SOUND_CLOCK * 2) / rate) + 1) >> 1;
+			if (hwrate < 3)
+				hwrate = 3;
+			if (hwrate > 255)
+				hwrate = 255;
+
+			rate = VIDC_SOUND_CLOCK / hwrate;
+		}
+
+		outl(0xb0000000 | (hwrate - 2), IO_VIDC_BASE);
+		outl(0xb1000000 | hwctrl, IO_VIDC_BASE);
+
+		newsize = (10000 / hwrate) & ~3;
+		if (newsize < 208)
+			newsize = 208;
+		if (newsize > 4096)
+			newsize = 4096;
+		for (new2size = 128; new2size < newsize; new2size <<= 1);
+			if (new2size - newsize > newsize - (new2size >> 1))
+				new2size >>= 1;
+		if (new2size > 4096) {
+			printk(KERN_ERR "VIDC: error: dma buffer (%d) %d > 4K\n",
+				newsize, new2size);
+			new2size = 4096;
+		}
+		dma_bufsize = new2size;
+		vidc_audio_rate = rate;
+	}
+	return vidc_audio_rate;
+}
+
+static short vidc_audio_set_channels(int dev, short channels)
+{
+	switch (channels) {
+	default:
+		channels = 2;
+	case 1:
+	case 2:
+		vidc_audio_channels = channels;
+		vidc_update_filler(vidc_audio_format, vidc_audio_channels);
+	case 0:
+		break;
+	}
+	return vidc_audio_channels;
+}
+
+/*
+ * Open the device
+ */
+static int vidc_audio_open(int dev, int mode)
+{
+	/* This audio device does not have recording capability */
+	if (mode == OPEN_READ)
+		return -EPERM;
+
+	if (vidc_busy)
+		return -EBUSY;
+
+	vidc_busy = 1;
+	return 0;
+}
+
+/*
+ * Close the device
+ */
+static void vidc_audio_close(int dev)
+{
+	vidc_busy = 0;
+}
+
+/*
+ * Output a block via DMA to sound device.
+ *
+ * We just set the DMA start and count; the DMA interrupt routine
+ * will take care of formatting the samples (via the appropriate
+ * vidc_filler routine), and flag via vidc_audio_dma_interrupt when
+ * more data is required.
+ */
+static void
+vidc_audio_output_block(int dev, unsigned long buf, int total_count, int one)
+{
+	struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
+	unsigned long flags;
+
+	save_flags_cli(flags);
+	dma_start = buf - (unsigned long)dmap->raw_buf_phys + (unsigned long)dmap->raw_buf;
+	dma_count = total_count;
+	restore_flags(flags);
+}
+
+static void
+vidc_audio_start_input(int dev, unsigned long buf, int count, int intrflag)
+{
+}
+
+static int vidc_audio_prepare_for_input(int dev, int bsize, int bcount)
+{
+	return -EINVAL;
+}
+
+static void vidc_audio_dma_interrupt(void)
+{
+	DMAbuf_outputintr(vidc_adev, 1);
+}
+
+/*
+ * Prepare for outputting samples.
+ *
+ * Each buffer that will be passed will be `bsize' bytes long,
+ * with a total of `bcount' buffers.
+ */
+static int vidc_audio_prepare_for_output(int dev, int bsize, int bcount)
+{
+	struct audio_operations *adev = audio_devs[dev];
+
+	dma_interrupt = NULL;
+	adev->dmap_out->flags |= DMA_NODMA;
+
+	return 0;
+}
+
+/*
+ * Stop our current operation.
+ */
+static void vidc_audio_reset(int dev)
+{
+	dma_interrupt = NULL;
+}
+
+static int vidc_audio_local_qlen(int dev)
+{
+	return /*dma_count !=*/ 0;
+}
+
+static void vidc_audio_trigger(int dev, int enable_bits)
+{
+	struct audio_operations *adev = audio_devs[dev];
+
+	if (enable_bits & PCM_ENABLE_OUTPUT) {
+		if (!(adev->flags & DMA_ACTIVE)) {
+			unsigned long flags;
+
+			save_flags_cli(flags);
 
-	fillertype = TYPE(format, channels);
+			/* prevent recusion */
+			adev->flags |= DMA_ACTIVE;
 
-	switch (fillertype)
-	{
-		default:
-		case TYPE(AFMT_U8, 1):
-			vidc_filler = vidc_fill_1x8_u;
-			break;
-
-		case TYPE(AFMT_U8, 2):
-			vidc_filler = vidc_fill_2x8_u;
-			break;
-
-		case TYPE(AFMT_S8, 1):
-			vidc_filler = vidc_fill_1x8_s;
-			break;
-
-		case TYPE(AFMT_S8, 2):
-			vidc_filler = vidc_fill_2x8_s;
-			break;
-
-		case TYPE(AFMT_S16_LE, 1):
-			vidc_filler = vidc_fill_1x16_s;
-			break;
-
-		case TYPE(AFMT_S16_LE, 2):
-			vidc_filler = vidc_fill_2x16_s;
-			break;
+			dma_interrupt = vidc_audio_dma_interrupt;
+			vidc_sound_dma_irq(0, NULL, NULL);
+			outb(DMA_CR_E | 0x10, IOMD_SD0CR);
+
+			restore_flags(flags);
+		}
+	}
+}
+
+static struct audio_driver vidc_audio_driver =
+{
+	open:			vidc_audio_open,
+	close:			vidc_audio_close,
+	output_block:		vidc_audio_output_block,
+	start_input:		vidc_audio_start_input,
+	prepare_for_input:	vidc_audio_prepare_for_input,
+	prepare_for_output:	vidc_audio_prepare_for_output,
+	halt_io:		vidc_audio_reset,
+	local_qlen:		vidc_audio_local_qlen,
+	trigger:		vidc_audio_trigger,
+	set_speed:		vidc_audio_set_speed,
+	set_bits:		vidc_audio_set_format,
+	set_channels:		vidc_audio_set_channels
+};
+
+static struct mixer_operations vidc_mixer_operations = {
+	id:		"VIDC",
+	name:		"VIDCsound",
+	ioctl:		vidc_mixer_ioctl
+};
+
+void vidc_update_filler(int format, int channels)
+{
+#define TYPE(fmt,ch) (((fmt)<<2) | ((ch)&3))
+
+	switch (TYPE(format, channels)) {
+	default:
+	case TYPE(AFMT_U8, 1):
+		vidc_filler = vidc_fill_1x8_u;
+		break;
+
+	case TYPE(AFMT_U8, 2):
+		vidc_filler = vidc_fill_2x8_u;
+		break;
+
+	case TYPE(AFMT_S8, 1):
+		vidc_filler = vidc_fill_1x8_s;
+		break;
+
+	case TYPE(AFMT_S8, 2):
+		vidc_filler = vidc_fill_2x8_s;
+		break;
+
+	case TYPE(AFMT_S16_LE, 1):
+		vidc_filler = vidc_fill_1x16_s;
+		break;
+
+	case TYPE(AFMT_S16_LE, 2):
+		vidc_filler = vidc_fill_2x16_s;
+		break;
 	}
 }
 
 void attach_vidc(struct address_info *hw_config)
 {
 	char name[32];
-	int i;
+	int i, adev;
 
 	sprintf(name, "VIDC %d-bit sound", hw_config->card_subtype);
 	conf_printf(name, hw_config);
 	memset(dma_buf, 0, sizeof(dma_buf));
 
-	for (i = 0; i < 2; i++)
-	{
+	adev = sound_install_audiodrv(AUDIO_DRIVER_VERSION, name,
+			&vidc_audio_driver, sizeof(vidc_audio_driver),
+			DMA_AUTOMODE, AFMT_U8 | AFMT_S8 | AFMT_S16_LE,
+			NULL, hw_config->dma, hw_config->dma2);
+
+	if (adev < 0)
+		goto audio_failed;
+
+	/*
+	 * 1024 bytes => 64 buffers
+	 */
+	audio_devs[adev]->min_fragment = 10;
+	audio_devs[adev]->mixer_dev = num_mixers;
+
+	audio_devs[adev]->mixer_dev =
+		sound_install_mixer(MIXER_DRIVER_VERSION,
+				name, &vidc_mixer_operations,
+				sizeof(vidc_mixer_operations), NULL);
+
+	if (audio_devs[adev]->mixer_dev < 0)
+		goto mixer_failed;
+
+	for (i = 0; i < 2; i++) {
 		dma_buf[i] = get_free_page(GFP_KERNEL);
-		if (!dma_buf[i])
-			goto nomem;
-		dma_pbuf[i] = virt_to_phys(dma_buf[i]);
+		if (!dma_buf[i]) {
+			printk(KERN_ERR "%s: can't allocate required buffers\n",
+				name);
+			goto mem_failed;
+		}
+		dma_pbuf[i] = virt_to_phys((void *)dma_buf[i]);
 	}
 
-	if (sound_alloc_dma(hw_config->dma, "VIDCsound"))
-	{
-		printk(KERN_ERR "VIDCsound: can't allocate virtual DMA channel\n");
-		return;
-	}
-	if (request_irq(hw_config->irq, vidc_sound_dma_irq, 0, "VIDCsound", &dma_start))
-	{
-		printk(KERN_ERR "VIDCsound: can't allocate DMA interrupt\n");
-		return;
+	if (sound_alloc_dma(hw_config->dma, hw_config->name)) {
+		printk(KERN_ERR "%s: DMA %d is in  use\n", name, hw_config->dma);
+		goto dma_failed;
 	}
 
-//	vidc_synth_init(hw_config);
-	vidc_audio_init(hw_config);
-	vidc_mixer_init(hw_config);
+	if (request_irq(hw_config->irq, vidc_sound_dma_irq, 0,
+			hw_config->name, &dma_start)) {
+		printk(KERN_ERR "%s: IRQ %d is in use\n", name, hw_config->irq);
+		goto irq_failed;
+	}
+	old_mksound = kd_mksound;
+	kd_mksound = vidc_mksound;
+	vidc_adev = adev;
+	vidc_mixer_set(SOUND_MIXER_VOLUME, (85 | 85 << 8));
+
+#if defined(CONFIG_SOUND_SOFTOSS) || defined(CONFIG_SOUND_SOFTOSS_MODULE)
+	softoss_dev = adev;
+#endif
 	return;
 
-nomem:
+irq_failed:
+	sound_free_dma(hw_config->dma);
+dma_failed:
+mem_failed:
 	for (i = 0; i < 2; i++)
 		free_page(dma_buf[i]);
-	printk(KERN_ERR "VIDCsound: can't allocate required buffers\n");
+	sound_unload_mixerdev(audio_devs[adev]->mixer_dev);
+mixer_failed:
+	sound_unload_audiodev(adev);
+audio_failed:
+	return;
 }
 
 int probe_vidc(struct address_info *hw_config)
 {
-	hw_config->irq = IRQ_DMAS0;
-	hw_config->dma = DMA_VIRTUAL_SOUND;
-	hw_config->dma2 = -1;
-	hw_config->card_subtype = 16;
+	hw_config->irq		= IRQ_DMAS0;
+	hw_config->dma		= DMA_VIRTUAL_SOUND;
+	hw_config->dma2		= -1;
+	hw_config->card_subtype	= 16;
+	hw_config->name		= "VIDC20";
 	return 1;
 }
 
 void unload_vidc(struct address_info *hw_config)
 {
-	int i;
+	int i, adev = vidc_adev;
+
+	vidc_adev = -1;
+
+	if (old_mksound)
+		kd_mksound = old_mksound;
 
-	free_irq(hw_config->irq, NULL);
+	free_irq(hw_config->irq, &dma_start);
 	sound_free_dma(hw_config->dma);
 
-	for (i = 0; i < 2; i++)
-		free_page(dma_buf[i]);
+	if (adev >= 0) {
+		sound_unload_mixerdev(audio_devs[adev]->mixer_dev);
+		sound_unload_audiodev(adev);
+		for (i = 0; i < 2; i++)
+			free_page(dma_buf[i]);
+	}
 }
 
 #ifdef MODULE
 static struct address_info config;
+/*
+ * Note! Module use count is handled by SOUNDLOCK/SOUND_LOCK_END
+ */
 
 int init_module(void)
 {
 	if (probe_vidc(&config) == 0)
 		return -ENODEV;
-	printk("VIDC 16-bit serial sound\n");
+
 	SOUND_LOCK;
 	attach_vidc(&config);
+
 	return 0;
 }
 
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/vidc.h linux/drivers/sound/vidc.h
--- v2.3.47/linux/drivers/sound/vidc.h	Wed Dec 16 12:52:01 1998
+++ linux/drivers/sound/vidc.h	Thu Feb 24 22:44:47 2000
@@ -55,18 +55,9 @@
 extern unsigned long dma_start, dma_count, dma_bufsize;
 extern unsigned long dma_buf[2], dma_pbuf[2];
 
-/* vidc_audio.c */
-
-extern void     vidc_audio_init(struct address_info *hw_config);
-extern int      vidc_audio_get_volume(void);
-extern int      vidc_audio_set_volume(int vol);
-
-/* vidc_mixer.c */
-
-extern void     vidc_mixer_init(struct address_info *hw_config);
-
 /* vidc_synth.c */
 
 extern void     vidc_synth_init(struct address_info *hw_config);
+extern void	vidc_synth_exit(struct address_info *hw_config);
 extern int      vidc_synth_get_volume(void);
 extern int      vidc_synth_set_volume(int vol);
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/vidc_audio.c linux/drivers/sound/vidc_audio.c
--- v2.3.47/linux/drivers/sound/vidc_audio.c	Thu Jun 17 01:11:35 1999
+++ linux/drivers/sound/vidc_audio.c	Wed Dec 31 16:00:00 1969
@@ -1,314 +0,0 @@
-/*
- * drivers/sound/vidc_audio.c
- *
- * Audio routines for the VIDC
- *
- * Copyright (C) 1997 Russell King <rmk@arm.uk.linux.org>
- */
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/iomd.h>
-
-#include "sound_config.h"
-#include "vidc.h"
-
-/*
- * VIDC sound
- *
- * When using SERIAL SOUND mode (external DAC), the number of physical
- * channels is fixed at 2.  Therefore, the sample rate = vidc sample rate.
- */
-
-static int      vidc_adev;
-
-static int      vidc_audio_volume;
-static int      vidc_audio_rate;
-static char     vidc_audio_format;
-static char     vidc_audio_channels;
-
-extern void     vidc_update_filler(int bits, int channels);
-
-int  vidc_audio_get_volume(void)
-{
-	return vidc_audio_volume;
-}
-
-int vidc_audio_set_volume(int newvol)
-{
-	vidc_audio_volume = newvol;
-	return vidc_audio_volume;
-}
-
-static int vidc_audio_set_bits(int fmt)
-{
-	switch (fmt)
-	{
-		case AFMT_QUERY:
-			break;
-		case AFMT_U8:
-		case AFMT_S8:
-		case AFMT_S16_LE:
-			vidc_audio_format = fmt;
-			vidc_update_filler(vidc_audio_format, vidc_audio_channels);
-			break;
-		default:
-			vidc_audio_format = AFMT_S16_LE;
-			vidc_update_filler(vidc_audio_format, vidc_audio_channels);
-			break;
-	}
-	return vidc_audio_format;
-}
-
-static int vidc_audio_set_rate(int rate)
-{
-	if (rate)
-	{
-		int newsize, new2size;
-
-		vidc_audio_rate = ((500000 / rate) + 1) >> 1;
-		if (vidc_audio_rate < 3)
-			vidc_audio_rate = 3;
-		if (vidc_audio_rate > 255)
-			vidc_audio_rate = 255;
-		outl((vidc_audio_rate - 2) | 0xb0000000, IO_VIDC_BASE);
-		outl(0xb1000003, IO_VIDC_BASE);
-		newsize = (10000 / vidc_audio_rate) & ~3;
-		if (newsize < 208)
-			newsize = 208;
-		if (newsize > 4096)
-			newsize = 4096;
-		for (new2size = 128; new2size < newsize; new2size <<= 1);
-			if (new2size - newsize > newsize - (new2size >> 1))
-				new2size >>= 1;
-		dma_bufsize = new2size;
-	}
-	return 250000 / vidc_audio_rate;
-}
-
-static int vidc_audio_set_channels(int channels)
-{
-	switch (channels)
-	{
-		case 0:
-			break;
-		case 1:
-		case 2:
-			vidc_audio_channels = channels;
-			vidc_update_filler(vidc_audio_format, vidc_audio_channels);
-			break;
-		default:
-			vidc_audio_channels = 2;
-			vidc_update_filler(vidc_audio_format, vidc_audio_channels);
-			break;
-	}
-	return vidc_audio_channels;
-}
-
-/*
- * Open the device
- *
- * dev  - device
- * mode - mode to open device (logical OR of OPEN_READ and OPEN_WRITE)
- *
- * Called when opening the DMAbuf               (dmabuf.c:259)
- */
-static int vidc_audio_open(int dev, int mode)
-{
-	if (vidc_busy)
-		return -EBUSY;
-
-	if ((mode & OPEN_READ) && (!mode & OPEN_WRITE))
-	{
-		/* This audio device doesn't have recording capability */
-		return -EIO;
-	}
-	vidc_busy = 1;
-	return 0;
-}
-
-/*
- * Close the device
- *
- * dev  - device
- *
- * Called when closing the DMAbuf               (dmabuf.c:477)
- *      after halt_xfer
- */
-static void vidc_audio_close(int dev)
-{
-	vidc_busy = 0;
-}
-
-static int vidc_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
-{
-	int ret;
-
-	switch (cmd)
-	{
-		case SOUND_PCM_WRITE_RATE:
-			if (get_user(ret, (int *) arg))
-				return -EFAULT;
-			ret = vidc_audio_set_rate(ret);
-			break;
-
-		case SOUND_PCM_READ_RATE:
-			ret = vidc_audio_set_rate(0);
-			break;
-
-		case SNDCTL_DSP_STEREO:
-			if (get_user(ret, (int *) arg))
-				return -EFAULT;
-			ret = vidc_audio_set_channels(ret + 1) - 1;
-			break;
-
-		case SOUND_PCM_WRITE_CHANNELS:
-			if (get_user(ret, (int *) arg))
-				return -EFAULT;
-			ret = vidc_audio_set_channels(ret);
-			break;
-
-		case SOUND_PCM_READ_CHANNELS:
-			ret = vidc_audio_set_channels(0);
-			break;
-
-		case SNDCTL_DSP_SETFMT:
-			if (get_user(ret, (int *) arg))
-				return -EFAULT;
-			ret = vidc_audio_set_bits(ret);
-			break;
-
-		case SOUND_PCM_READ_BITS:
-			ret = vidc_audio_set_bits(0);
-			break;
-
-		case SOUND_PCM_WRITE_FILTER:
-		case SOUND_PCM_READ_FILTER:
-			return -EINVAL;
-
-		default:
-			return -EINVAL;
-	}
-	return put_user(ret, (int *) arg);
-}
-
-/*
- * Output a block via DMA to sound device
- *
- * dev          - device number
- * buf          - physical address of buffer
- * total_count  - total byte count in buffer
- * intrflag     - set if this has been called from an interrupt (via DMAbuf_outputintr)
- * restart_dma  - set if DMA needs to be re-initialised
- *
- * Called when:
- *  1. Starting output                                  (dmabuf.c:1327)
- *  2.                                                  (dmabuf.c:1504)
- *  3. A new buffer needs to be sent to the device      (dmabuf.c:1579)
- */
-static void vidc_audio_output_block(int dev, unsigned long buf, int total_count,
-			int intrflag)
-{
-	struct audio_operations *adev = audio_devs[dev];
-	struct dma_buffparms *dmap = adev->dmap_out;
-
-	dma_start = buf - (unsigned long)dmap->raw_buf_phys + (unsigned long)dmap->raw_buf;
-	dma_count = total_count;
-
-	if (!(adev->flags & DMA_ACTIVE))
-	{
-		unsigned long flags;
-		save_flags_cli(flags);
-
-		vidc_sound_dma_irq(0, NULL, NULL);
-		outb(DMA_CR_E | 0x10, IOMD_SD0CR);
-
-		restore_flags(flags);
-	}
-}
-
-static void vidc_audio_start_input(int dev, unsigned long buf, int count,
-		       int intrflag)
-{
-}
-
-static int vidc_audio_prepare_for_input(int dev, int bsize, int bcount)
-{
-	return -EINVAL;
-}
-
-static void vidc_audio_dma_interrupt(void)
-{
-	DMAbuf_outputintr(vidc_adev, 1);
-}
-
-/*
- * Prepare for outputting samples to `dev'
- *
- * Each buffer that will be passed will be `bsize' bytes long,
- * with a total of `bcount' buffers.
- *
- * Called when:
- *  1. A trigger enables audio output                   (dmabuf.c:978)
- *  2. We get a write buffer without dma_mode setup     (dmabuf.c:1152)
- *  3. We restart a transfer                            (dmabuf.c:1324)
- */
-static int vidc_audio_prepare_for_output(int dev, int bsize, int bcount)
-{
-	audio_devs[dev]->dmap_out->flags |= DMA_NODMA;
-	dma_interrupt = vidc_audio_dma_interrupt;
-	return 0;
-}
-
-/*
- * Stop our current operation.
- */
-static void vidc_audio_reset(int dev)
-{
-	/* stop interrupts.  Our real interrupt routine
-	 * will close DMA down for us
-	 */
-	dma_interrupt = NULL;
-}
-
-static int vidc_audio_local_qlen(int dev)
-{
-	return /*dma_count !=*/ 0;
-}
-
-static struct audio_driver vidc_audio_driver =
-{
-	vidc_audio_open,		/* open                 */
-	vidc_audio_close,		/* close                */
-	vidc_audio_output_block,	/* output_block         */
-	vidc_audio_start_input,		/* start_input          */
-	vidc_audio_ioctl,		/* ioctl                */
-	vidc_audio_prepare_for_input,	/* prepare_for_input    */
-	vidc_audio_prepare_for_output,	/* prepare_for_output   */
-	vidc_audio_reset,		/* reset                */
-	vidc_audio_local_qlen,		/*+local_qlen           */
-	NULL,				/*+copy_from_user       */
-	NULL,				/*+halt_input           */
-	NULL,				/* halt_output          */
-	NULL,				/*+trigger              */
-	NULL,				/*+set_speed            */
-	NULL,				/*+set_bits             */
-	NULL,				/*+set_channels         */
-};
-
-void vidc_audio_init(struct address_info *hw_config)
-{
-	vidc_audio_volume = 100 | (100 << 8);
-
-	if ((vidc_adev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
-				"VIDCsound", &vidc_audio_driver,
-				sizeof(struct audio_driver),
-				DMA_AUTOMODE, AFMT_U8 | AFMT_S8 | AFMT_S16_LE,
-				NULL, hw_config->dma, hw_config->dma2)) >= 0)
-	{
-		audio_devs[vidc_adev]->min_fragment = 10;	/* 1024 bytes => 64 buffers */
-		audio_devs[vidc_adev]->mixer_dev = num_mixers;
-	}
-	else printk(KERN_ERR "VIDCsound: Too many PCM devices available\n");
-}
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/vidc_fill.S linux/drivers/sound/vidc_fill.S
--- v2.3.47/linux/drivers/sound/vidc_fill.S	Thu Jun 17 01:11:35 1999
+++ linux/drivers/sound/vidc_fill.S	Thu Feb 24 22:44:47 2000
@@ -191,24 +191,24 @@
 		.data
 		.globl	SYMBOL_NAME(dma_interrupt)
 SYMBOL_NAME(dma_interrupt):
-		.long	0
+		.long	0				@ r3
 		.globl	SYMBOL_NAME(dma_pbuf)
 SYMBOL_NAME(dma_pbuf):
-		.long	0
-		.long	0
+		.long	0				@ r4
+		.long	0				@ r5
 		.globl	SYMBOL_NAME(dma_start)
 SYMBOL_NAME(dma_start):
-		.long	0
+		.long	0				@ r0
 		.globl	SYMBOL_NAME(dma_count)
 SYMBOL_NAME(dma_count):
-		.long	0
+		.long	0				@ r1
 		.globl	SYMBOL_NAME(dma_buf)
 SYMBOL_NAME(dma_buf):
-		.long	0
-		.long	0
+		.long	0				@ r2
+		.long	0				@ r3
 		.globl	SYMBOL_NAME(vidc_filler)
 SYMBOL_NAME(vidc_filler):
-		.long	SYMBOL_NAME(vidc_fill_noaudio)
+		.long	SYMBOL_NAME(vidc_fill_noaudio)	@ r4
 		.globl	SYMBOL_NAME(dma_bufsize)
 SYMBOL_NAME(dma_bufsize):
-		.long	0x1000
+		.long	0x1000				@ r5
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/vidc_mixer.c linux/drivers/sound/vidc_mixer.c
--- v2.3.47/linux/drivers/sound/vidc_mixer.c	Wed Dec 16 12:52:01 1998
+++ linux/drivers/sound/vidc_mixer.c	Wed Dec 31 16:00:00 1969
@@ -1,151 +0,0 @@
-/*
- * drivers/sound/vidc_mixer.c
- *
- * Mixer routines for VIDC
- *
- * Copyright (C) 1997 Russell King <rmk@arm.uk.linux.org>
- */
-
-#include "sound_config.h"
-#include "vidc.h"
-
-int vidc_volume;
-
-static int vidc_get_volume(void)
-{
-	return vidc_volume;
-}
-
-static int vidc_set_volume(int newvol)
-{
-	vidc_volume = newvol;
-/*  printk ("vidc_set_volume: %X\n", newvol); */
-	return newvol;
-}
-
-static int vidc_default_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
-{
-	int ret;
-
-	switch (cmd)
-	{
-		case SOUND_MIXER_READ_VOLUME:
-			ret = vidc_get_volume();
-			break;
-
-		case SOUND_MIXER_WRITE_VOLUME:
-			if (get_user(ret, (int *) arg))
-				return -EINVAL;
-			ret = vidc_set_volume(ret);
-			break;
-
-		case SOUND_MIXER_READ_BASS:
-		case SOUND_MIXER_WRITE_BASS:
-		case SOUND_MIXER_READ_TREBLE:
-		case SOUND_MIXER_WRITE_TREBLE:
-			ret = 50;
-			break;
-
-		case SOUND_MIXER_READ_SYNTH:
-//			ret = vidc_synth_get_volume();
-			ret = 0;
-			break;
-
-		case SOUND_MIXER_WRITE_SYNTH:
-			if (get_user(ret, (int *) arg))
-				return -EINVAL;
-//			ret = vidc_synth_set_volume(ret);
-			ret = 0;
-			break;
-
-		case SOUND_MIXER_READ_PCM:
-			ret = vidc_audio_get_volume();
-			break;
-
-		case SOUND_MIXER_WRITE_PCM:
-			if (get_user(ret, (int *) arg))
-				return -EINVAL;
-			ret = vidc_audio_set_volume(ret);
-			break;
-
-		case SOUND_MIXER_READ_SPEAKER:
-			ret = 100;
-			break;
-
-		case SOUND_MIXER_WRITE_SPEAKER:
-			ret = 100;
-			break;
-
-		case SOUND_MIXER_READ_LINE:
-		case SOUND_MIXER_WRITE_LINE:
-		case SOUND_MIXER_READ_MIC:
-		case SOUND_MIXER_WRITE_MIC:
-			ret = 0;
-			break;
-
-		case SOUND_MIXER_READ_CD:
-		case SOUND_MIXER_WRITE_CD:
-			ret = 100 | (100 << 8);
-			break;
-
-		case SOUND_MIXER_READ_IMIX:
-		case SOUND_MIXER_WRITE_IMIX:
-		case SOUND_MIXER_READ_ALTPCM:
-		case SOUND_MIXER_WRITE_ALTPCM:
-		case SOUND_MIXER_READ_LINE1:
-		case SOUND_MIXER_WRITE_LINE1:
-		case SOUND_MIXER_READ_LINE2:
-		case SOUND_MIXER_WRITE_LINE2:
-		case SOUND_MIXER_READ_LINE3:
-		case SOUND_MIXER_WRITE_LINE3:
-			ret = 0;
-			break;
-
-		case SOUND_MIXER_READ_RECSRC:
-			ret = 0;
-			break;
-
-		case SOUND_MIXER_WRITE_RECSRC:
-			return -EINVAL;
-			break;
-
-		case SOUND_MIXER_READ_DEVMASK:
-			ret = SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_SYNTH;
-			break;
-
-		case SOUND_MIXER_READ_RECMASK:
-			ret = 0;
-			break;
-
-		case SOUND_MIXER_READ_STEREODEVS:
-			ret = SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_SYNTH;
-			break;
-
-		case SOUND_MIXER_READ_CAPS:
-			ret = 0;
-			break;
-
-		case SOUND_MIXER_READ_MUTE:
-			return -EINVAL;
-			break;
-
-		default:
-			return -EINVAL;
-			break;
-	}
-	return put_user(ret, (int *) arg);
-}
-
-static struct mixer_operations vidc_mixer_operations = {
-	"VIDC",
-	"VIDCsound",
-	vidc_default_mixer_ioctl	/* ioctl                */
-};
-
-void vidc_mixer_init(struct address_info *hw_config)
-{
-	int vidc_mixer = sound_alloc_mixerdev();
-	vidc_volume = 100 | (100 << 8);
-	if (num_mixers < MAX_MIXER_DEV)
-		mixer_devs[vidc_mixer] = &vidc_mixer_operations;
-}
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/vidc_synth.c linux/drivers/sound/vidc_synth.c
--- v2.3.47/linux/drivers/sound/vidc_synth.c	Wed Dec 16 12:52:01 1998
+++ linux/drivers/sound/vidc_synth.c	Wed Dec 31 16:00:00 1969
@@ -1,91 +0,0 @@
-/*
- * drivers/sound/vidc_synth.c
- *
- * Synthesizer routines for the VIDC
- *
- * Copyright (C) 1997 Russell King <rmk@arm.uk.linux.org>
- */
-
-#include "sound_config.h"
-#include "vidc.h"
-#if 0
-static struct synth_info vidc_info =
-{
-	"VIDCsound",		/* name                 */
-	0,			/* device               */
-	SYNTH_TYPE_SAMPLE,	/* synth_type           */
-	0,			/* synth_subtype        */
-	0,			/* perc_mode            */
-	16,			/* nr_voices            */
-	0,			/* nr_drums             */
-	0,			/* instr_bank_size      */
-	0,			/* capabilities         */
-};
-
-int             vidc_sdev;
-int             vidc_synth_volume;
-
-static int vidc_synth_open(int dev, int mode)
-{
-	if (vidc_busy)
-		return -EBUSY;
-
-	vidc_busy = 1;
-	return 0;
-}
-
-static void vidc_synth_close(int dev)
-{
-	vidc_busy = 0;
-}
-
-
-static struct synth_operations vidc_synth_operations =
-{
-	"VIDC Synth",		/* name			*/
-	&vidc_info,		/* info 		*/
-	0,			/* midi_dev		*/
-	SYNTH_TYPE_SAMPLE,	/* synth_type		*/
-	/*SAMPLE_TYPE_XXX */ 0, /* synth_subtype	*/
-	vidc_synth_open,	/* open 		*/
-	vidc_synth_close,	/* close		*/
-	NULL,			/* ioctl		*/
-	NULL,			/* kill_note		*/
-	NULL,			/* start_note		*/
-	NULL,			/* set_instr		*/
-	NULL,			/* reset		*/
-	NULL,			/* hw_control		*/
-	NULL,			/* load_patch		*/
-	NULL,			/* aftertouch		*/
-	NULL,			/* controller		*/
-	NULL,			/* panning		*/
-	NULL,			/* volume_method	*/
-	NULL,			/* bender		*/
-	NULL,			/* alloc_voice		*/
-	NULL,			/* setup_voice		*/
-	NULL,			/* send_sysex		*/
-				/* alloc		*/
-				/* chn_info[16] 	*/
-				/* syex_buf		*/
-				/* syex_ptr		*/
-};
-
-int  vidc_synth_get_volume(void)
-{
-	return vidc_synth_volume;
-}
-
-int vidc_synth_set_volume(int newvol)
-{
-	return vidc_synth_volume = newvol;
-}
-
-void vidc_synth_init(struct address_info *hw_config)
-{
-	vidc_synth_volume = 100 | (100 << 8);
-	if ((vidc_sdev=sound_alloc_synthdev())!=-1)
-		synth_devs[vidc_sdev] = &vidc_synth_operations;
-	else
-		printk(KERN_ERR "VIDCsound: Too many synthesizers\n");
-}
-#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/waveartist.c linux/drivers/sound/waveartist.c
--- v2.3.47/linux/drivers/sound/waveartist.c	Tue Dec 14 01:27:24 1999
+++ linux/drivers/sound/waveartist.c	Thu Feb 24 22:12:57 2000
@@ -838,7 +838,6 @@
 	else
 		printk(KERN_WARNING "waveartist: unexpected interrupt\n");
 
-#ifdef CONFIG_AUDIO
 	if (irqstatus & 0x01) {
 		int temp = 1;
 
@@ -855,7 +854,6 @@
 		if (temp)	//default:
 			printk(KERN_WARNING "waveartist: Unknown interrupt\n");
 	}
-#endif
 	if (irqstatus & 0x2)
 		// We do not use SB mode natively...
 		printk(KERN_WARNING "waveartist: Unexpected SB interrupt...\n");
diff -u --recursive --new-file v2.3.47/linux/drivers/sound/wavfront.c linux/drivers/sound/wavfront.c
--- v2.3.47/linux/drivers/sound/wavfront.c	Thu Feb 10 17:11:14 2000
+++ linux/drivers/sound/wavfront.c	Thu Feb 24 22:12:57 2000
@@ -86,7 +86,7 @@
  */
  
 #if defined(__alpha__)
-#ifdef __SMP__
+#ifdef CONFIG_SMP
 #define LOOPS_PER_SEC cpu_data[smp_processor_id()].loops_per_sec
 #else
 #define LOOPS_PER_SEC	loops_per_sec
@@ -1686,13 +1686,11 @@
 	   master otherwise.
 	*/
 
-#ifdef CONFIG_MIDI
 	if (dev.mididev > 0) {
 		midi_synth_controller (dev.mididev, guspatch.instr_no, 10,
 				       ((guspatch.panning << 4) > 127) ?
 				       127 : (guspatch.panning << 4));
 	}
-#endif CONFIG_MIDI
 
 	return(0);
 }
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/acm.c linux/drivers/usb/acm.c
--- v2.3.47/linux/drivers/usb/acm.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/usb/acm.c	Wed Feb 23 11:27:14 2000
@@ -643,16 +643,10 @@
 };
 
 /*
- * Init / cleanup.
+ * Init / exit.
  */
 
-static void __exit usb_acm_cleanup(void)
-{
-	usb_deregister(&acm_driver);
-	tty_unregister_driver(&acm_tty_driver);
-}
-
-static int __init usb_acm_init(void)
+static int __init acm_init(void)
 {
 	acm_tty_driver.init_termios =		tty_std_termios;
 	acm_tty_driver.init_termios.c_cflag =	B9600 | CS8 | CREAD | HUPCL | CLOCAL;
@@ -668,5 +662,11 @@
 	return 0;
 }
 
-module_init(usb_acm_init);
-module_exit(usb_acm_cleanup);
+static void __exit acm_exit(void)
+{
+	usb_deregister(&acm_driver);
+	tty_unregister_driver(&acm_tty_driver);
+}
+
+module_init(acm_init);
+module_exit(acm_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/devio.c linux/drivers/usb/devio.c
--- v2.3.47/linux/drivers/usb/devio.c	Thu Feb 10 17:11:14 2000
+++ linux/drivers/usb/devio.c	Sat Feb 26 20:33:03 2000
@@ -1002,15 +1002,11 @@
 	return mask;
 }
 
-static struct file_operations usbdevfs_device_file_operations = {
+struct file_operations usbdevfs_device_file_operations = {
 	llseek:		usbdev_lseek,
 	read:		usbdev_read,
 	poll:		usbdev_poll,
 	ioctl:		usbdev_ioctl,
 	open:		usbdev_open,
 	release:	usbdev_release,
-};
-
-struct inode_operations usbdevfs_device_inode_operations = {
-        &usbdevfs_device_file_operations,  /* file-ops */
 };
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/evdev.c linux/drivers/usb/evdev.c
--- v2.3.47/linux/drivers/usb/evdev.c	Tue Jan  4 13:57:17 2000
+++ linux/drivers/usb/evdev.c	Wed Feb 23 11:27:14 2000
@@ -256,20 +256,16 @@
 	disconnect:	evdev_disconnect,
 };
 
-#ifdef MODULE
-int init_module(void)
-#else
-int __init evdev_init(void)
-#endif
+static int __init evdev_init(void)
 {
 	input_register_handler(&evdev_handler);
-
 	return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void __exit evdev_exit(void)
 {
 	input_unregister_handler(&evdev_handler);
 }
-#endif
+
+module_init(evdev_init);
+module_exit(evdev_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/ftdi_sio.h linux/drivers/usb/ftdi_sio.h
--- v2.3.47/linux/drivers/usb/ftdi_sio.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/ftdi_sio.h	Thu Feb 24 22:50:41 2000
@@ -0,0 +1,380 @@
+/* Bill Ryder - bryder@sgi.com - wrote the FTDI_SIO implementation */
+/* The device is based on the FTDI FT8U100AX chip, DB25 on one side, USB on the other */
+/* Thanx to FTDI for so kindly providing details of the protocol required */
+/* http://www.ftdi.co.uk  */
+
+/* The implementation of the device I have is called a USC-1000 */
+/*  which is available from http://www.dse.co.nz - cat no XH4214 */
+/* It looks similar to this: http://www.dansdata.com/usbser.htm but I can't be sure */
+/* There are other USC-1000s which don't look like my device though so beware */
+
+/* Definitions for the FTDI USB Single Port Serial Converter */
+/* known as FTDI_SIO (Serial Input/Output application of the chipset) */
+
+#define FTDI_VID	0x0403	/* Vendor Id */
+#define FTDI_SIO_PID	0x8372	/* Product Id */
+
+/* Vendor Request Interface */
+#define FTDI_SIO_RESET 		0 /* Reset the port */
+#define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
+#define FTDI_SIO_SET_FLOW_CTRL	2 /* Set flow control register */
+#define FTDI_SIO_SET_BAUD_RATE	3 /* Set baud rate */
+#define FTDI_SIO_SET_DATA	4 /* Set the data characteristics of the port */
+#define FTDI_SIO_GET_MODEM_STATUS	5 /* Retrieve current value of modern status register */
+#define FTDI_SIO_SET_EVENT_CHAR	6 /* Set the event character */
+#define FTDI_SIO_SET_ERROR_CHAR	7 /* Set the error character */
+
+/* Port Identifier Table */
+#define PIT_DEFAULT 		0 /* SIOA */
+#define PIT_SIOA		1 /* SIOA */
+/* The device this is tested with one has one port */
+#define PIT_SIOB		2 /* SIOB */
+#define PIT_PARALLEL		3 /* Parallel */
+
+/* FTDI_SIO_RESET */
+#define FTDI_SIO_RESET_REQUEST FTDI_SIO_RESET
+#define FTDI_SIO_RESET_REQUEST_TYPE 0x40
+#define FTDI_SIO_RESET_SIO 0
+#define FTDI_SIO_RESET_PURGE_RX 1
+#define FTDI_SIO_RESET_PURGE_TX 2
+/* 
+   BmRequestType:  0100 0000B
+   bRequest:       FTDI_SIO_RESET
+   wValue:         Control Value 
+                         0 = Reset SIO
+                         1 = Purge RX buffer
+                         2 = Purge TX buffer
+   wIndex:         Port
+   wLength:        0
+   Data:           None
+
+   */
+
+/* FTDI_SIO_SET_BAUDRATE */
+#define FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE 0x40
+#define FTDI_SIO_SET_BAUDRATE_REQUEST 3
+
+/*
+  BmRequestType:  0100 0000B
+  bRequest:       FTDI_SIO_SET_BAUDRATE
+  wValue:         BaudRate value - see below
+  wIndex:         Port
+  wLength:        0
+  Data:           None
+*/
+
+typedef enum {
+ ftdi_sio_b300 = 0, 
+ ftdi_sio_b600 = 1, 
+ ftdi_sio_b1200 = 2,
+ ftdi_sio_b2400 = 3,
+ ftdi_sio_b4800 = 4,
+ ftdi_sio_b9600 = 5,
+ ftdi_sio_b19200 = 6,
+ ftdi_sio_b38400 = 7,
+ ftdi_sio_b57600 = 8,
+ ftdi_sio_b115200 = 9
+} FTDI_SIO_baudrate_t ;
+
+#define FTDI_SIO_SET_DATA_REQUEST FTDI_SIO_SET_DATA
+#define FTDI_SIO_SET_DATA_REQUEST_TYPE 0x40
+#define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8 )
+#define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8 )
+#define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8 )
+#define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8 )
+#define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8 )
+#define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11 )
+#define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11 )
+#define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11 )
+
+/* FTDI_SIO_SET_DATA */
+
+/*    BmRequestType:  0100 0000B */
+/*    bRequest:       FTDI_SIO_SET_DATA */
+/*    wValue:         Data characteristics (see below) */
+/*    wIndex:         Port */
+/*    wLength:        0 */
+/*    Data:           None */
+/* 
+  Data characteristics
+
+B0..7   Number of data bits
+B8..10  Parity
+           0 = None
+           1 = Odd
+           2 = Even
+           3 = Mark
+           4 = Space
+ B11..13 Stop Bits
+           0 = 1
+           1 = 1.5
+           2 = 2
+ B14..15 Reserved
+*/
+
+
+
+/* FTDI_SIO_MODEM_CTRL */
+#define FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE 0x40
+#define FTDI_SIO_SET_MODEM_CTRL_REQUEST FTDI_SIO_MODEM_CTRL
+
+/* 
+  BmRequestType:   0100 0000B
+  bRequest:        FTDI_SIO_MODEM_CTRL
+  wValue:          ControlValue (see below)
+  wIndex:          Port
+  wLength:         0
+  Data:            None
+
+  NOTE: If the device is in RTS/CTS flow control, the RTS set by this
+        command will be IGNORED without an error being returned
+*/
+
+#define FTDI_SIO_SET_DTR_MASK 0x1
+#define FTDI_SIO_SET_DTR_HIGH ( 1 | ( FTDI_SIO_SET_DTR_MASK  << 8))
+#define FTDI_SIO_SET_DTR_LOW  ( 0 | ( FTDI_SIO_SET_DTR_MASK  << 8))
+#define FTDI_SIO_SET_RTS_MASK 0x2
+#define FTDI_SIO_SET_RTS_HIGH ( 2 | ( FTDI_SIO_SET_RTS_MASK << 8 ))
+#define FTDI_SIO_SET_RTS_LOW ( 0 | ( FTDI_SIO_SET_RTS_MASK << 8 ))
+
+/* ControlValue
+   B0    DTR state
+           0 = reset
+           1 = set
+   B1    RTS state
+           0 = reset
+           1 = set
+   B2..7 Reserved
+   B8    DTR state enable
+           0 = ignore
+           1 = use DTR state
+   B9    RTS state enable
+           0 = ignore
+           1 = use RTS state
+   B10..15 Reserved
+*/
+
+/* FTDI_SIO_SET_FLOW_CTRL */
+#define FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE 0x40
+#define FTDI_SIO_SET_FLOW_CTRL_REQUEST FTDI_SIO_SET_FLOW_CTRL
+#define FTDI_SIO_DISABLE_FLOW_CTRL 0x0 
+#define FTDI_SIO_RTS_CTS_HS 0x1
+#define FTDI_SIO_DTR_DSR_HS 0x2
+#define FTDI_SIO_XON_XOFF_HS 0x4
+/* 
+   BmRequestType:  0100 0000b
+   bRequest:       FTDI_SIO_SET_FLOW_CTRL
+   wValue:         Xoff/Xon
+   wIndex:         Protocol/Port - hIndex is protocl / lIndex is port
+   wLength:        0 
+   Data:           None
+
+hIndex - protocol has
+ B0 Output handshaking using RTS/CTS
+      0 = disabled
+      1 = enabled
+ B1 Output handshaking using DTR/DSR
+      0 = disabled
+      1 = enabled
+ B2 Xon/Xoff handshaking
+      0 = disabled
+      1 = enabled
+
+A value of zero in the hIndex field selects no handshaking
+
+If Xon/Xoff handshaking is specified, the hValue field contains the Xoff character 
+and the lValue field contains the Xon character.
+
+*/  
+ 
+/* FTDI_SIO_SET_EVENT_CHAR */
+/* Set the special event character for the specified communications port */
+/* If the device sees this character it will immediately return the */
+/* data read so far - rather than wait 40ms or until 62 bytes is read */
+#define  FTDI_SIO_SET_EVENT_CHAR_REQUEST FTDI_SIO_SET_EVENT_CHAR
+#define  FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE 0x40
+
+
+/* 
+  BmRequestType:   0100 0000b
+  bRequest:        FTDI_SIO_SET_EVENT_CHAR
+  wValue:          EventChar
+  wIndex:          Port
+  wLength:         0
+  Data:            None
+
+wValue:
+   B0..7   Event Character
+   B8      Event Character Processing
+             0 = disabled
+             1 = enabled
+   B9..15  Reserved
+
+*/
+          
+/* FTDI_SIO_SET_ERROR_CHAR */
+/* Set the parity error replacement character for the specified communications port */
+
+/* 
+  BmRequestType:  0100 0000b
+  bRequest:       FTDI_SIO_SET_EVENT_CHAR
+  wValue:         Error Char
+  wIndex:         Port
+  wLength:        0
+  Data:           None
+
+Error Char
+  B0..7  Error Character
+  B8     Error Character Processing
+           0 = disabled
+           1 = enabled
+  B9..15 Reserved
+
+*/
+
+/* FTDI_SIO_GET_MODEM_STATUS */
+/* Retreive the current value of the modem status register */
+
+#define FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE 0xc0
+#define FTDI_SIO_GET_MODEM_STATUS_REQUEST FTDI_SIO_GET_MODEM_STATUS
+#define FTDI_SIO_CTS_MASK 0x10
+#define FTDI_SIO_DSR_MASK 0x20
+#define FTDI_SIO_RI_MASK  0x40
+#define FTDI_SIO_RLSD_MASK 0x80
+/* 
+  BmRequestType:   1100 0000b
+  bRequest:        FTDI_SIO_GET_MODEM_STATUS
+  wValue:          zero
+  wIndex:          Port
+  wLength:         1
+  Data:            Status
+
+One byte of data is returned 
+B0..3 0
+B4    CTS
+        0 = inactive
+        1 = active
+B5    DSR
+        0 = inactive
+        1 = active
+B6    Ring Indicator (RI)
+        0 = inactive
+        1 = active
+B7    Receive Line Signal Detect (RLSD)
+        0 = inactive
+        1 = active 
+*/
+
+
+
+/* Descriptors returned by the device 
+
+ Device Descriptor
+
+Offset	Field		Size	Value	Description
+0	bLength		1	0x12	Size of descriptor in bytes
+1	bDescriptorType	1	0x01	DEVICE Descriptor Type
+2	bcdUSB		2	0x0110	USB Spec Release Number
+4	bDeviceClass	1	0x00	Class Code
+5	bDeviceSubClass	1	0x00	SubClass Code
+6	bDeviceProtocol	1	0x00	Protocol Code
+7	bMaxPacketSize0 1	0x08	Maximum packet size for endpoint 0
+8	idVendor	2	0x0403	Vendor ID
+10	idProduct	2	0x8372	Product ID (FTDI_SIO_PID)
+12	bcdDevice	2	0x0001	Device release number
+14	iManufacturer	1	0x01	Index of man. string desc
+15	iProduct	1	0x02	Index of prod string desc
+16	iSerialNumber	1	0x02	Index of serial nmr string desc
+17	bNumConfigurations 1    0x01	Number of possible configurations
+
+Configuration Descriptor
+
+Offset	Field			Size	Value
+0	bLength			1	0x09	Size of descriptor in bytes
+1	bDescriptorType		1	0x02	CONFIGURATION Descriptor Type
+2	wTotalLength		2	0x0020	Total length of data
+4	bNumInterfaces		1	0x01	Number of interfaces supported
+5	bConfigurationValue	1	0x01	Argument for SetCOnfiguration() req
+6	iConfiguration		1	0x02	Index of config string descriptor
+7	bmAttributes		1	0x20	Config characteristics Remote Wakeup
+8	MaxPower		1	0x1E	Max power consumption
+
+Interface Descriptor
+
+Offset	Field			Size	Value
+0	bLength			1	0x09	Size of descriptor in bytes
+1	bDescriptorType		1	0x04	INTERFACE Descriptor Type
+2	bInterfaceNumber	1	0x00	Number of interface
+3	bAlternateSetting	1	0x00	Value used to select alternate
+4	bNumEndpoints		1	0x02	Number of endpoints
+5	bInterfaceClass		1	0xFF	Class Code
+6	bInterfaceSubClass	1	0xFF	Subclass Code
+7	bInterfaceProtocol	1	0xFF	Protocol Code
+8	iInterface		1	0x02	Index of interface string description
+
+IN Endpoint Descriptor
+
+Offset	Field			Size	Value
+0	bLength			1	0x07	Size of descriptor in bytes
+1	bDescriptorType		1	0x05	ENDPOINT descriptor type
+2	bEndpointAddress	1	0x82	Address of endpoint
+3	bmAttributes		1	0x02	Endpoint attributes - Bulk
+4	bNumEndpoints		2	0x0040	maximum packet size
+5	bInterval		1	0x00	Interval for polling endpoint
+
+OUT Endpoint Descriptor
+
+Offset	Field			Size	Value
+0	bLength			1	0x07	Size of descriptor in bytes
+1	bDescriptorType		1	0x05	ENDPOINT descriptor type
+2	bEndpointAddress	1	0x02	Address of endpoint
+3	bmAttributes		1	0x02	Endpoint attributes - Bulk
+4	bNumEndpoints		2	0x0040	maximum packet size
+5	bInterval		1	0x00	Interval for polling endpoint
+    
+DATA FORMAT
+
+IN Endpoint
+
+The device reserves the first two bytes of data on this endpoint to contain the current
+values of the modem and line status registers. In the absence of data, the device 
+generates a message consisting of these two status bytes every 40 ms
+
+Byte 0: Modem Status
+
+Offset	Description
+B0	Reserved - must be 1
+B1	Reserved - must be 0
+B2	Reserved - must be 0
+B3	Reserved - must be 0
+B4	Clear to Send (CTS)
+B5	Data Set Ready (DSR)
+B6	Ring Indicator (RI)
+B7	Receive Line Signal Detect (RLSD)
+
+Byte 1: Line Status
+
+Offset	Description
+B0	Data Ready (DR)
+B1	Overrun Error (OE)
+B2	Parity Error (PE)
+B3	Framing Error (FE)
+B4	Break Interrupt (BI)
+B5	Transmitter Holding Register (THRE)
+B6	Transmitter Empty (TEMT)
+B7	Error in RCVR FIFO
+
+OUT Endpoint
+
+This device reserves the first bytes of data on this endpoint contain the length
+and port identifier of the message. For the FTDI USB Serial converter the port 
+identifier is always 1.
+
+Byte 0: Line Status
+
+Offset	Description
+B0	Reserved - must be 1
+B1	Reserved - must be 0
+B2..7	Length of message - (not including Byte 0)
+
+*/
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/graphire.c linux/drivers/usb/graphire.c
--- v2.3.47/linux/drivers/usb/graphire.c	Fri Jan 28 15:09:08 2000
+++ linux/drivers/usb/graphire.c	Wed Feb 23 11:27:14 2000
@@ -37,6 +37,7 @@
 #include <linux/malloc.h>
 #include <linux/input.h>
 #include <linux/module.h>
+#include <linux/init.h>
 #include "usb.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
@@ -179,17 +180,16 @@
 	disconnect:	graphire_disconnect,
 };
 
-#ifdef MODULE
-void cleanup_module(void)
+static int __init graphire_init(void)
 {
-	usb_deregister(&graphire_driver);
+	usb_register(&graphire_driver);
+	return 0;
 }
 
-int init_module(void)
-#else
-int graphire_init(void)
-#endif
+static void __exit graphire_exit(void)
 {
-	usb_register(&graphire_driver);
-	return 0;
+	usb_deregister(&graphire_driver);
 }
+
+module_init(graphire_init);
+module_exit(graphire_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/hid.c linux/drivers/usb/hid.c
--- v2.3.47/linux/drivers/usb/hid.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/usb/hid.c	Thu Feb 24 10:14:29 2000
@@ -40,6 +40,8 @@
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 
+#include <asm/unaligned.h>
+
 #undef DEBUG
 #undef DEBUG_DATA
 
@@ -573,14 +575,14 @@
 
 				case 2: 
 					if ((end - start) >= 2) {
-						item->data.u16 = le16_to_cpu( *((__u16*)start)++);
+						item->data.u16 = le16_to_cpu( get_unaligned(((__u16*)start)++));
 						return start;
 					}
 
 				case 3: 
 					item->size++;
 					if ((end - start) >= 4) {
-						item->data.u32 = le32_to_cpu( *((__u32*)start)++);
+						item->data.u32 = le32_to_cpu( get_unaligned(((__u32*)start)++));
 						return start;
 					}
 			}
@@ -706,7 +708,7 @@
 static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
 {
 	report += (offset >> 5) << 2; offset &= 31;
-	return (le64_to_cpu(*(__u64*)report) >> offset) & ((1 << n) - 1);
+	return (le64_to_cpu(get_unaligned((__u64*)report)) >> offset) & ((1 << n) - 1);
 }
 
 static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
@@ -1408,19 +1410,16 @@
 	disconnect:	hid_disconnect
 };
 
-#ifdef MODULE
-void cleanup_module(void)
+static int __init hid_init(void)
 {
-	usb_deregister(&hid_driver);
+	usb_register(&hid_driver);
+	return 0;
 }
 
-int init_module(void)
-#else
-int hid_init(void)
-#endif
+static void __exit hid_exit(void)
 {
-	usb_register(&hid_driver);
-	return 0;
+	usb_deregister(&hid_driver);
 }
 
-__initcall(hid_init);
+module_init(hid_init);
+module_exit(hid_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/inode.c linux/drivers/usb/inode.c
--- v2.3.47/linux/drivers/usb/inode.c	Sat Feb 12 11:22:11 2000
+++ linux/drivers/usb/inode.c	Sat Feb 26 20:33:03 2000
@@ -46,24 +46,17 @@
 static LIST_HEAD(superlist);
 
 extern struct inode_operations usbdevfs_bus_inode_operations;
-
-static struct inode_operations devices_inode_operations = {
-        &usbdevfs_devices_fops
-};
-
-static struct inode_operations drivers_inode_operations = {
-        &usbdevfs_drivers_fops
-};
+extern struct file_operations usbdevfs_bus_file_operations;
 
 struct special {
 	const char *name;
-	struct inode_operations *iops;
+	struct file_operations *fops;
 	struct list_head inodes;
 };
 
 static struct special special[] = { 
-	{ "devices", &devices_inode_operations,  },
-	{ "drivers", &drivers_inode_operations,  }
+	{ "devices", &usbdevfs_devices_fops,  },
+	{ "drivers", &usbdevfs_drivers_fops,  }
 };
 
 #define NRSPECIAL (sizeof(special)/sizeof(special[0]))
@@ -110,7 +103,7 @@
 	inode->i_uid = sb->u.usbdevfs_sb.devuid;
 	inode->i_gid = sb->u.usbdevfs_sb.devgid;
 	inode->i_mode = sb->u.usbdevfs_sb.devmode | S_IFREG;
-	inode->i_op = &usbdevfs_device_inode_operations;
+	inode->i_fop = &usbdevfs_device_file_operations;
 	inode->i_size = sizeof(struct usb_device_descriptor);
 	inode->u.usbdev_i.p.dev = dev;
 	list_add_tail(&inode->u.usbdev_i.slist, &sb->u.usbdevfs_sb.ilist);
@@ -148,6 +141,7 @@
 	inode->i_gid = sb->u.usbdevfs_sb.busgid;
 	inode->i_mode = sb->u.usbdevfs_sb.busmode | S_IFDIR;
 	inode->i_op = &usbdevfs_bus_inode_operations;
+	inode->i_fop = &usbdevfs_bus_file_operations;
 	inode->u.usbdev_i.p.bus = bus;
 	list_add_tail(&inode->u.usbdev_i.slist, &sb->u.usbdevfs_sb.ilist);
 	list_add_tail(&inode->u.usbdev_i.dlist, &bus->inodes);
@@ -159,7 +153,6 @@
 	inode->u.usbdev_i.p.dev = NULL;
 	inode->i_mode &= ~S_IRWXUGO;
 	inode->i_uid = inode->i_gid = 0;
-	inode->i_op = NULL;
 	inode->i_size = 0;
 	list_del(&inode->u.usbdev_i.slist);
 	INIT_LIST_HEAD(&inode->u.usbdev_i.slist);
@@ -405,7 +398,6 @@
 };
 
 static struct inode_operations usbdevfs_root_inode_operations = {
-	default_file_ops: &usbdevfs_root_file_operations,
 	lookup: usbdevfs_root_lookup,
 };
 
@@ -414,7 +406,6 @@
 };
 
 static struct inode_operations usbdevfs_bus_inode_operations = {
-	default_file_ops: &usbdevfs_bus_file_operations,
 	lookup: usbdevfs_bus_lookup,
 };
 
@@ -433,13 +424,14 @@
 	case ISPECIAL:
 		if (inode->i_ino == IROOT) {
 			inode->i_op = &usbdevfs_root_inode_operations;
+			inode->i_fop = &usbdevfs_root_file_operations;
 			inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
 			return;
 		}
 		if (inode->i_ino <= IROOT || inode->i_ino > IROOT+NRSPECIAL)
 			return;
 		spec = &special[inode->i_ino-(IROOT+1)];
-		inode->i_op = spec->iops;
+		inode->i_fop = spec->fops;
 		return;
 
 	case IDEVICE:
@@ -453,10 +445,6 @@
         }
 }
 
-static void usbdevfs_put_inode(struct inode *inode)
-{
-}
-
 static void usbdevfs_put_super(struct super_block *sb)
 {
 	list_del(&sb->u.usbdevfs_sb.slist);
@@ -482,15 +470,9 @@
 }
 
 static struct super_operations usbdevfs_sops = { 
-        usbdevfs_read_inode,
-        NULL,
-        usbdevfs_put_inode,
-        NULL,
-        NULL,
-        usbdevfs_put_super,
-        NULL,
-        usbdevfs_statfs,
-        NULL
+	read_inode:	usbdevfs_read_inode,
+	put_super:	usbdevfs_put_super,
+	statfs:		usbdevfs_statfs,
 };
 
 struct super_block *usbdevfs_read_super(struct super_block *s, void *data, int silent)
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/input.c linux/drivers/usb/input.c
--- v2.3.47/linux/drivers/usb/input.c	Sat Feb 12 11:22:11 2000
+++ linux/drivers/usb/input.c	Thu Feb 24 10:11:24 2000
@@ -31,7 +31,6 @@
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/module.h>
-#include <linux/config.h>
 #include <linux/random.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
@@ -303,35 +302,3 @@
 		handleptr = &((*handleptr)->hnext);
 	*handleptr = (*handleptr)->hnext;
 }
-
-
-#ifdef MODULE
-int init_module(void)
-#else
-int __init input_init(void)
-#endif
-{
-#ifndef MODULE
-#ifdef CONFIG_INPUT_KEYBDEV
-	keybdev_init();
-#endif
-#ifdef CONFIG_INPUT_MOUSEDEV
-	mousedev_init();
-#endif
-#ifdef CONFIG_INPUT_JOYDEV
-	joydev_init();
-#endif
-#ifdef CONFIG_INPUT_EVDEV
-	evdev_init();
-#endif
-#endif
-	return 0;
-}
-
-#ifdef MODULE
-void cleanup_module(void)
-{
-}
-#endif
-
-__initcall(input_init);
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/joydev.c linux/drivers/usb/joydev.c
--- v2.3.47/linux/drivers/usb/joydev.c	Fri Jan 21 18:19:17 2000
+++ linux/drivers/usb/joydev.c	Wed Feb 23 11:27:14 2000
@@ -82,7 +82,7 @@
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_SUPPORTED_DEVICE("js");
 
-static int js_correct(int value, struct js_corr *corr)
+static int joydev_correct(int value, struct js_corr *corr)
 {
 	switch (corr->type) {
 		case JS_CORR_NONE:
@@ -102,7 +102,7 @@
 	return value;
 }
 
-static void js_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
 {
 	struct joydev *joydev = handle->private;
 	struct joydev_list *list = joydev->list;
@@ -120,7 +120,7 @@
 		case EV_ABS:
 			event.type = JS_EVENT_AXIS;
 			event.number = joydev->absmap[code];
-			event.value = js_correct(value, &joydev->corr[event.number]);
+			event.value = joydev_correct(value, &joydev->corr[event.number]);
 			break;
 
 		default:
@@ -226,8 +226,8 @@
 
 		data.buttons =  (joydev->nkey > 0 && test_bit(joydev->keypam[0], input->key)) ? 1 : 0 |
 				(joydev->nkey > 1 && test_bit(joydev->keypam[1], input->key)) ? 2 : 0;
-		data.x = ((js_correct(input->abs[ABS_X], &joydev->corr[0]) / 256) + 128) >> joydev->glue.JS_CORR.x;
-		data.y = ((js_correct(input->abs[ABS_Y], &joydev->corr[1]) / 256) + 128) >> joydev->glue.JS_CORR.y;
+		data.x = ((joydev_correct(input->abs[ABS_X], &joydev->corr[0]) / 256) + 128) >> joydev->glue.JS_CORR.x;
+		data.y = ((joydev_correct(input->abs[ABS_Y], &joydev->corr[1]) / 256) + 128) >> joydev->glue.JS_CORR.y;
 
 		if (copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE)))
 			return -EFAULT;
@@ -276,7 +276,7 @@
 			event.number = list->startup;
 		} else {
 			event.type = JS_EVENT_AXIS | JS_EVENT_INIT;
-			event.value = js_correct(input->abs[joydev->abspam[list->startup - joydev->nkey]],
+			event.value = joydev_correct(input->abs[joydev->abspam[list->startup - joydev->nkey]],
 							&joydev->corr[list->startup - joydev->nkey]);
 			event.number = list->startup - joydev->nkey;
 		}
@@ -459,29 +459,27 @@
 }
 
 static struct input_handler joydev_handler = {
-	event:		js_event,
+	event:		joydev_event,
 	connect:	joydev_connect,
 	disconnect:	joydev_disconnect,
 };
 
-#ifdef MODULE
-void cleanup_module(void)
-{
-	input_unregister_handler(&joydev_handler);
-	if (unregister_chrdev(JOYSTICK_MAJOR, "js"))
-		printk(KERN_ERR "js: can't unregister device\n");
-}
-
-int init_module(void)
-#else
-int __init joydev_init(void)
-#endif
+static int joydev_init(void)
 {
 	if (register_chrdev(JOYDEV_MAJOR, "js", &joydev_fops)) {
 		printk(KERN_ERR "joydev: unable to get major %d for joystick\n", JOYDEV_MAJOR);
 		return -EBUSY;
 	}
 	input_register_handler(&joydev_handler);
-
 	return 0;
 }
+
+static void joydev_exit(void)
+{
+	input_unregister_handler(&joydev_handler);
+	if (unregister_chrdev(JOYSTICK_MAJOR, "js"))
+		printk(KERN_ERR "js: can't unregister device\n");
+}
+
+module_init(joydev_init);
+module_exit(joydev_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/keybdev.c linux/drivers/usb/keybdev.c
--- v2.3.47/linux/drivers/usb/keybdev.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/usb/keybdev.c	Wed Feb 23 11:27:14 2000
@@ -158,18 +158,18 @@
 	disconnect:	keybdev_disconnect,
 };
 
-#ifdef MODULE
-void cleanup_module(void)
-{
-	kbd_ledfunc = NULL;
-	input_unregister_handler(&keybdev_handler);
-}
-int init_module(void)
-#else
-int __init keybdev_init(void)
-#endif
+static int __init keybdev_init(void)
 {
 	input_register_handler(&keybdev_handler);
 	kbd_ledfunc = keybdev_ledfunc;
 	return 0;
 }
+
+static void __exit keybdev_exit(void)
+{
+	kbd_ledfunc = NULL;
+	input_unregister_handler(&keybdev_handler);
+}
+
+module_init(keybdev_init);
+module_exit(keybdev_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/mousedev.c linux/drivers/usb/mousedev.c
--- v2.3.47/linux/drivers/usb/mousedev.c	Fri Jan 28 15:09:08 2000
+++ linux/drivers/usb/mousedev.c	Wed Feb 23 11:27:14 2000
@@ -447,12 +447,7 @@
 	disconnect:	mousedev_disconnect,
 };
 
-
-#ifdef MODULE
-int init_module(void)
-#else
-int __init mousedev_init(void)
-#endif
+static int __init mousedev_init(void)
 {
 	input_register_handler(&mousedev_handler);
 
@@ -472,13 +467,13 @@
 	return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void __exit mousedev_exit(void)
 {
 #ifdef CONFIG_INPUT_MOUSEDEV_MIX
 	misc_deregister(&mousedev_single.misc);
 #endif
-
 	input_unregister_handler(&mousedev_handler);
 }
-#endif
+
+module_init(mousedev_init);
+module_exit(mousedev_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/printer.c linux/drivers/usb/printer.c
--- v2.3.47/linux/drivers/usb/printer.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/usb/printer.c	Wed Feb 23 11:27:14 2000
@@ -432,18 +432,17 @@
 	minor:		USBLP_MINOR_BASE
 };
 
-static void __exit usb_printer_cleanup(void)
-{
-	usb_deregister(&usblp_driver);
-}
-
-static int __init usb_printer_init(void)
+static int __init usblp_init(void)
 {
 	if (usb_register(&usblp_driver))
 		return -1;
-
 	return 0;
 }
 
-module_init(usb_printer_init);
-module_exit(usb_printer_cleanup);
+static void __exit usblp_exit(void)
+{
+	usb_deregister(&usblp_driver);
+}
+
+module_init(usblp_init);
+module_exit(usblp_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/scanner.c linux/drivers/usb/scanner.c
--- v2.3.47/linux/drivers/usb/scanner.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/usb/scanner.c	Tue Feb 22 22:21:04 2000
@@ -817,15 +817,12 @@
        SCN_BASE_MNR
 };
 
-#ifdef MODULE
-void cleanup_module(void)
+void __exit usb_scanner_exit(void)
 {
 	usb_deregister(&scanner_driver);
 }
-int init_module(void)
-#else
-int usb_scanner_init(void)
-#endif
+
+int __init usb_scanner_init(void)
 {
         if (usb_register(&scanner_driver) < 0)
                 return -1;
@@ -834,4 +831,5 @@
 	return 0;
 }
 
-__initcall(usb_scanner_init);
+module_init(usb_scanner_init);
+module_exit(usb_scanner_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/usb-core.c linux/drivers/usb/usb-core.c
--- v2.3.47/linux/drivers/usb/usb-core.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/usb/usb-core.c	Wed Feb 23 11:27:14 2000
@@ -33,12 +33,8 @@
 int usb_cpia_init(void);
 int usb_ibmcam_init(void);
 int usb_ov511_init(void);
-int usb_stor_init(void);
 int dabusb_init(void);
 int plusb_init(void);
-int usb_mouse_init(void);
-int usb_kbd_init(void);
-int graphire_init(void);
 
 /*
  * HCI drivers
@@ -86,23 +82,11 @@
 #ifdef CONFIG_USB_OV511
 	usb_ov511_init();
 #endif
-#ifdef CONFIG_USB_STORAGE
-	usb_stor_init();
-#endif
 #ifdef CONFIG_USB_DABUSB
 	dabusb_init();
 #endif
 #ifdef CONFIG_USB_PLUSB
 	plusb_init();
-#endif
-#ifdef CONFIG_USB_MOUSE
-	usb_mouse_init();
-#endif
-#ifdef CONFIG_USB_KBD
-	usb_kbd_init();
-#endif
-#ifdef CONFIG_USB_GRAPHIRE
-	graphire_init();
 #endif
 #ifdef CONFIG_USB_UHCI
 	uhci_init();
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/usb-ohci.c linux/drivers/usb/usb-ohci.c
--- v2.3.47/linux/drivers/usb/usb-ohci.c	Thu Feb 10 17:11:15 2000
+++ linux/drivers/usb/usb-ohci.c	Thu Feb 24 10:14:29 2000
@@ -45,6 +45,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
+#include <asm/unaligned.h>
 
 #undef DEBUG
 #define OHCI_USE_NPS
@@ -62,7 +63,7 @@
 
 static DECLARE_WAIT_QUEUE_HEAD (op_wakeup); 
 static LIST_HEAD (ohci_hcd_list);
-spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
 
 /*-------------------------------------------------------------------------*
  * URB support functions 
@@ -319,6 +320,7 @@
 	if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
 		urb_rm_priv(urb);
 		usb_dec_dev_use (urb->dev);	
+		spin_unlock_irqrestore(&usb_ed_lock, flags);
 		return -EINVAL;
 	}
 	
@@ -1261,7 +1263,7 @@
 	int len = 0;
 	int status = TD_CC_NOERROR;
 	
-	__u8 datab[16];
+	__u32 datab[4];
 	__u8  * data_buf = datab;
 	
  	__u16 bmRType_bReq;
@@ -1371,7 +1373,8 @@
 		
 		case RH_GET_DESCRIPTOR | RH_CLASS:
 			*(__u8 *)  (data_buf+1) = 0x29;
-			*(__u32 *) (data_buf+2) = cpu_to_le32 (readl (&ohci->regs->roothub.a));  
+			put_unaligned(cpu_to_le32 (readl (&ohci->regs->roothub.a)),
+				      (__u32 *) (data_buf + 2));
 	 		*(__u8 *)  data_buf = (*(__u8 *) (data_buf + 2) / 8) * 2 + 9; /* length of descriptor */
 				 
 			len = min (leni, min(*(__u8 *) data_buf, wLength));
@@ -1380,7 +1383,8 @@
 				*(__u8 *) (data_buf+7) = readl (&ohci->regs->roothub.b) & 0xff; 
 				*(__u8 *) (data_buf+8) = (readl (&ohci->regs->roothub.b) & 0xff0000) >> 16; 
 			} else {
-				*(__u32 *) (data_buf+7) = cpu_to_le32 (readl(&ohci->regs->roothub.b)); 
+				put_unaligned(cpu_to_le32 (readl(&ohci->regs->roothub.b)),
+					      (__u32 *) (data_buf + 7));
 			}
 			OK (len); 
  
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/usb-serial.c linux/drivers/usb/usb-serial.c
--- v2.3.47/linux/drivers/usb/usb-serial.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/usb/usb-serial.c	Thu Feb 24 22:50:41 2000
@@ -14,6 +14,17 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (02/21/2000) gkh
+ *	Made it so that any serial devices only have to specify which functions
+ *	they want to overload from the generic function calls (great, 
+ *	inheritance in C, in a driver, just what I wanted...)
+ *	Added support for set_termios and ioctl function calls. No drivers take
+ *	advantage of this yet.
+ *	Removed the #ifdef MODULE, now there is no module specific code.
+ *	Cleaned up a few comments in usb-serial.h that were wrong (thanks again
+ *	to Miles Lott).
+ *	Small fix to get_free_serial.
+ *
  * (02/14/2000) gkh
  *	Removed the Belkin and Peracom functionality from the driver due to
  *	the lack of support from the vendor, and me not wanting people to 
@@ -169,6 +180,19 @@
 
 #include "usb-serial.h"
 
+/* parity check flag */
+#define RELEVANT_IFLAG(iflag)	(iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+/* local function prototypes */
+static int  serial_open (struct tty_struct *tty, struct file * filp);
+static void serial_close (struct tty_struct *tty, struct file * filp);
+static int  serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count);
+static int  serial_write_room (struct tty_struct *tty);
+static int  serial_chars_in_buffer (struct tty_struct *tty);
+static void serial_throttle (struct tty_struct * tty);
+static void serial_unthrottle (struct tty_struct * tty);
+static int  serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
+static void serial_set_termios (struct tty_struct *tty, struct termios * old);
 
 static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum);
 static void usb_serial_disconnect(struct usb_device *dev, void *ptr);
@@ -224,7 +248,7 @@
 			continue;
 
 		good_spot = 1;
-		for (j = 0; j < num_ports-1; ++j)
+		for (j = 1; j <= num_ports-1; ++j)
 			if (serial_table[i+j])
 				good_spot = 0;
 		if (good_spot == 0)
@@ -328,12 +352,12 @@
 	tty->driver_data = serial;
 	serial->tty = tty;
 	 
-	/* pass on to the driver specific version of this function */
+	/* pass on to the driver specific version of this function if it is available */
 	if (serial->type->open) {
 		return (serial->type->open(tty, filp));
+	} else {
+		return (generic_serial_open(tty, filp));
 	}
-		
-	return (0);
 }
 
 
@@ -363,9 +387,11 @@
 		return;
 	}
 
-	/* pass on to the driver specific version of this function */
+	/* pass on to the driver specific version of this function if it is available */
 	if (serial->type->close) {
 		serial->type->close(tty, filp);
+	} else {
+		generic_serial_close(tty, filp);
 	}
 }	
 
@@ -391,13 +417,12 @@
 		return (-EINVAL);
 	}
 	
-	/* pass on to the driver specific version of this function */
+	/* pass on to the driver specific version of this function if it is available */
 	if (serial->type->write) {
 		return (serial->type->write(tty, from_user, buf, count));
+	} else {
+		return (generic_serial_write(tty, from_user, buf, count));
 	}
-
-	/* no specific driver, so return that we didn't write anything */
-	return (0);
 }
 
 
@@ -422,12 +447,12 @@
 		return (-EINVAL);
 	}
 	
-	/* pass on to the driver specific version of this function */
+	/* pass on to the driver specific version of this function if it is available */
 	if (serial->type->write_room) {
 		return (serial->type->write_room(tty));
+	} else {
+		return (generic_write_room(tty));
 	}
-
-	return (0);
 }
 
 
@@ -452,12 +477,12 @@
 		return (-EINVAL);
 	}
 	
-	/* pass on to the driver specific version of this function */
+	/* pass on to the driver specific version of this function if it is available */
 	if (serial->type->chars_in_buffer) {
 		return (serial->type->chars_in_buffer(tty));
+	} else {
+		return (generic_chars_in_buffer(tty));
 	}
-
-	return (0);
 }
 
 
@@ -485,6 +510,8 @@
 	/* pass on to the driver specific version of this function */
 	if (serial->type->throttle) {
 		serial->type->throttle(tty);
+	} else {
+		generic_throttle(tty);
 	}
 
 	return;
@@ -515,12 +542,86 @@
 	/* pass on to the driver specific version of this function */
 	if (serial->type->unthrottle) {
 		serial->type->unthrottle(tty);
+	} else {
+		generic_unthrottle(tty);
 	}
 
 	return;
 }
 
 
+static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
+{
+	struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+	int port;	
+
+	dbg("serial_ioctl");
+
+	if (!serial) {
+		dbg("serial == NULL!");
+		return -ENODEV;
+	}
+
+	port = MINOR(tty->device) - serial->minor;
+
+	dbg("serial_ioctl port %d", port);
+	
+	/* do some sanity checking that we really have a device present */
+	if (!serial->type) {
+		dbg("serial->type == NULL!");
+		return -ENODEV;
+	}
+	if (!serial->active[port]) {
+		dbg ("device not open");
+		return -ENODEV;
+	}
+
+	/* pass on to the driver specific version of this function if it is available */
+	if (serial->type->ioctl) {
+		return (serial->type->ioctl(tty, file, cmd, arg));
+	} else {
+		return (generic_ioctl (tty, file, cmd, arg));
+	}
+}
+
+
+static void serial_set_termios (struct tty_struct *tty, struct termios * old)
+{
+	struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+	int port;	
+
+	dbg("serial_set_termios");
+
+	if (!serial) {
+		dbg("serial == NULL!");
+		return;
+	}
+
+	port = MINOR(tty->device) - serial->minor;
+
+	dbg("serial_set_termios port %d", port);
+	
+	/* do some sanity checking that we really have a device present */
+	if (!serial->type) {
+		dbg("serial->type == NULL!");
+		return;
+	}
+	if (!serial->active[port]) {
+		dbg ("device not open");
+		return;
+	}
+
+	/* pass on to the driver specific version of this function if it is available */
+	if (serial->type->set_termios) {
+		serial->type->set_termios(tty, old);
+	} else {
+		generic_set_termios (tty, old);
+	}
+	
+	return;
+}
+
+
 #ifdef CONFIG_USB_SERIAL_WHITEHEAT
 /*****************************************************************************
  * Connect Tech's White Heat specific driver functions
@@ -566,6 +667,29 @@
 }
 
 
+static void whiteheat_set_termios (struct tty_struct *tty, struct termios *old_termios)
+{
+	struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+	int port = MINOR(tty->device) - serial->minor;
+	unsigned int cflag = tty->termios->c_cflag;
+
+	dbg("whiteheat_set_termios port %d", port);
+
+	/* check that they really want us to change something */
+	if (old_termios) {
+		if ((cflag == old_termios->c_cflag) &&
+		    (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
+			dbg("nothing to change...");
+			return;
+		}
+	}
+
+	/* do the parsing of the cflag to see what to set the line to */
+	/* FIXME!! */
+
+	return;
+}
+
 static void whiteheat_throttle (struct tty_struct * tty)
 {
 	struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
@@ -813,25 +937,96 @@
 /******************************************************************************
  * FTDI SIO Serial Converter specific driver functions
  ******************************************************************************/
+
+/* Bill Ryder - bryder@sgi.com - wrote the FTDI_SIO implementation */
+/* Thanx to FTDI for so kindly providing details of the protocol required */
+/*   to talk to the device */
+
+#include "ftdi_sio.h"
+
 static int  ftdi_sio_serial_open (struct tty_struct *tty, struct file *filp)
 {
 	struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+	char buf[1]; /* Needed for the usb_control_msg I think */
 	int port = MINOR(tty->device) - serial->minor;
 
-	dbg("ftdi_serial_open port %d", port);
+	dbg("ftdi_sio_serial_open port %d", port);
 
 	if (serial->active[port]) {
 		dbg ("device already open");
 		return -EINVAL;
 	}
 	serial->active[port] = 1;
- 
+
+	usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, 
+			FTDI_SIO_RESET_SIO, 
+			0, buf, 0, HZ * 5);
+
+	/* FIXME - Should I really purge the buffers? */
+	usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, 
+			FTDI_SIO_RESET_PURGE_RX, 
+			0, buf, 0, HZ * 5);
+
+	usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, 
+			FTDI_SIO_RESET_PURGE_TX, 
+			0, buf, 0, HZ * 5);	
+
+
+	/* As per usb_serial_init s/be CS8, B9600, 1 STOP BIT */
+	if ( usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			     FTDI_SIO_SET_BAUDRATE_REQUEST,
+			     FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE,
+			     ftdi_sio_b9600, 0, 
+			     buf, 0, HZ * 5) < 0){
+		dbg("Error from baudrate urb");
+		return(-EINVAL);
+	}
+
+	if ( usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			     FTDI_SIO_SET_DATA_REQUEST, 
+			     FTDI_SIO_SET_DATA_REQUEST_TYPE,
+			     8 | FTDI_SIO_SET_DATA_PARITY_NONE | 
+			     FTDI_SIO_SET_DATA_STOP_BITS_1, 0,
+			     buf, 0, HZ * 5) < 0){
+		dbg("Error from cs8/noparity/1 stopbit urb");
+		return(-EINVAL);
+	}
+
+	/* Disable flow control */
+	if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
+			    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
+			    0, 0, 
+			    buf, 0, HZ * 5) < 0) {
+		dbg("error from flowcontrol urb");
+		return(-EINVAL);
+	}	    
+
+	/* Turn on RTS and DTR since we are not flow controlling*/
+	/* FIXME - check for correct behaviour clocal vs non clocal */
+	/* FIXME - might be able to do both simultaneously */
+	if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
+			    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
+			    (unsigned)FTDI_SIO_SET_DTR_HIGH, 0, 
+			    buf, 0, HZ * 5) < 0) {
+		dbg("Error from DTR HIGH urb");
+	}
+	if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
+			    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
+			    (unsigned)FTDI_SIO_SET_RTS_HIGH, 0, 
+			    buf, 0, HZ * 5) < 0) {
+		dbg("Error from RTS HIGH urb");
+	}
+	
 	/*Start reading from the device*/
 	if (usb_submit_urb(&serial->read_urb[port]))
 		dbg("usb_submit_urb(read bulk) failed");
 
-	/* Need to do device specific setup here (control lines, baud rate, etc.) */
-	/* FIXME!!! */
 
 	return (0);
 }
@@ -840,13 +1035,29 @@
 static void ftdi_sio_serial_close (struct tty_struct *tty, struct file *filp)
 {
 	struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+	char buf[1];
 	int port = MINOR(tty->device) - serial->minor;
 
-	dbg("ftdi_serial_close port %d", port);
-	
-	/* Need to change the control lines here */
-	/* FIXME */
+	dbg("ftdi_sio_serial_close port %d", port);
 	
+	/* FIXME - might be able to do both simultaneously */
+	if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
+			    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
+			    (unsigned)FTDI_SIO_SET_DTR_LOW, 0, 
+			    buf, 0, HZ * 5) < 0) {
+		dbg("Error from DTR LOW urb");
+	}
+	if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
+			    FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
+			    (unsigned)FTDI_SIO_SET_RTS_LOW, 0, 
+			    buf, 0, HZ * 5) < 0) {
+		dbg("Error from RTS LOW urb");
+	}	
+
+	/* FIXME Should I flush the device here? - not doing it for now */
+
 	/* shutdown our bulk reads and writes */
 	usb_unlink_urb (&serial->write_urb[port]);
 	usb_unlink_urb (&serial->read_urb[port]);
@@ -854,6 +1065,290 @@
 }
 
 
+  
+/* The ftdi_sio requires the first byte to have:
+   B0 1
+   B1 0
+   B2..7 length of message excluding byte 0
+*/
+static int ftdi_sio_serial_write (struct tty_struct * tty, int from_user, 
+				  const unsigned char *buf, int count)
+{
+	struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+	int port = MINOR(tty->device) - serial->minor;
+	const int data_offset = 1;
+
+	dbg("ftdi_sio_serial_write port %d, %d bytes", port, count);
+
+	if (count == 0) {
+		dbg("write request of 0 bytes");
+		return (0);
+	}
+
+	/* only do something if we have a bulk out endpoint */
+	if (serial->num_bulk_out) {
+		unsigned char *first_byte = serial->write_urb[port].transfer_buffer;
+
+		if (serial->write_urb[port].status == -EINPROGRESS) {
+			dbg ("already writing");
+			return (0);
+		}
+
+		count += data_offset;
+		count = (count > serial->bulk_out_size[port]) ? 
+			serial->bulk_out_size[port] : count;
+
+
+		/* Copy in the data to send */
+		if (from_user) {
+			copy_from_user(serial->write_urb[port].transfer_buffer + data_offset , 
+				       buf, count - data_offset );
+		}
+		else {
+			memcpy(serial->write_urb[port].transfer_buffer + data_offset,
+			       buf, count - data_offset );
+		}  
+
+		/* Write the control byte at the front of the packet*/
+		first_byte = serial->write_urb[port].transfer_buffer;
+		*first_byte = 1 | ((count-data_offset) << 2) ; 
+
+#ifdef DEBUG
+		dbg("Bytes: %d, Control Byte: 0o%03o",count, first_byte[0]);
+
+		if (count) {
+			int i;
+			printk (KERN_DEBUG __FILE__ ": data written - length = %d, data = ", count);
+			for (i = 0; i < count; ++i) {
+				printk ("0x%02x ", first_byte[i]);
+				if (first_byte[i] > ' ' && first_byte[i] < '~') {
+					printk("%c ", first_byte[i]);
+				} else {
+					printk("  ");
+				}
+			}
+
+		     
+			printk ("\n");
+		}
+
+#endif
+
+
+		/* send the data out the bulk port */
+		serial->write_urb[port].transfer_buffer_length = count;
+
+		if (usb_submit_urb(&serial->write_urb[port]))
+			dbg("usb_submit_urb(write bulk) failed");
+
+		dbg("write returning: %d",count - data_offset);
+		return (count - data_offset);
+	}
+	
+	/* no bulk out, so return 0 bytes written */
+	return (0);
+} 
+
+
+static void ftdi_sio_read_bulk_callback (struct urb *urb)
+{ /* ftdi_sio_serial_buld_callback */
+	struct usb_serial *serial = (struct usb_serial *)urb->context;
+       	struct tty_struct *tty = serial->tty; 
+       	unsigned char *data = urb->transfer_buffer;
+	const int data_offset = 2;
+	int i;
+
+	dbg("ftdi_sio_read_bulk_callback");
+
+	if (urb->status) {
+		dbg("nonzero read bulk status received: %d", urb->status);
+		return;
+	}
+
+#ifdef DEBUG
+	if (urb->actual_length > 2) {
+		printk (KERN_DEBUG __FILE__ ": data read - length = %d, data = ", urb->actual_length);
+		for (i = 0; i < urb->actual_length; ++i) {
+			printk ("0x%.2x ", data[i]);
+			if (data[i] > ' ' && data[i] < '~') {
+				printk("%c ", data[i]);
+			} else {
+				printk("  ");
+			}
+		}
+		printk ("\n");
+	}
+#endif
+	
+
+	if (urb->actual_length > data_offset) {
+		for (i = data_offset ; i < urb->actual_length ; ++i) {
+			tty_insert_flip_char(tty, data[i], 0);
+	  	}
+	  	tty_flip_buffer_push(tty);
+	}
+
+	/* Continue trying to always read  */
+	if (usb_submit_urb(urb))
+		dbg("failed resubmitting read urb");
+
+	return;
+} /* ftdi_sio_serial_read_bulk_callback */
+
+static void ftdi_sio_set_termios (struct tty_struct *tty, struct termios *old_termios)
+{
+	struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+	int port = MINOR(tty->device) - serial->minor;
+	unsigned int cflag = tty->termios->c_cflag;
+	__u16 urb_value; /* Will hold the new flags */
+	char buf[1]; /* Perhaps I should dynamically alloc this? */
+	dbg("ftdi_sio_set_termios port %d", port);
+
+	/* FIXME - we should keep the old termios really */
+	/* FIXME -For this cut I don't care if the line is really changing or 
+	   not  - so just do the change regardless */
+	
+	/* Set number of data bits, parity, stop bits */
+	
+	urb_value = 0;
+	urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 :
+		      FTDI_SIO_SET_DATA_STOP_BITS_1);
+	urb_value |= (cflag & PARENB ? 
+		      (cflag & PARODD ? FTDI_SIO_SET_DATA_PARITY_ODD : 
+		       FTDI_SIO_SET_DATA_PARITY_EVEN) :
+		      FTDI_SIO_SET_DATA_PARITY_NONE);
+	if (cflag & CSIZE) {
+		switch (cflag & CSIZE) {
+		case CS5: urb_value |= 5; dbg("Setting CS5"); break;
+		case CS6: urb_value |= 6; dbg("Setting CS6"); break;
+		case CS7: urb_value |= 7; dbg("Setting CS7"); break;
+		case CS8: urb_value |= 8; dbg("Setting CS8"); break;
+		default:
+			dbg("CSIZE was set but not CS5-CS8");
+		}
+	}
+	if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    FTDI_SIO_SET_DATA_REQUEST, 
+			    FTDI_SIO_SET_DATA_REQUEST_TYPE,
+			    urb_value , 0,
+			    buf, 0, 100) < 0) {
+		dbg("FAILED to set databits/stopbits/parity");
+	}	   
+
+	/* Now do the baudrate */
+	/* FIXME - should drop lines on B0 */
+	/* FIXME Should also handle CLOCAL here  */
+     
+	switch(cflag & CBAUD){
+	case B300: urb_value = ftdi_sio_b300; dbg("Set to 300"); break;
+	case B600: urb_value = ftdi_sio_b600; dbg("Set to 600") ; break;
+	case B1200: urb_value = ftdi_sio_b1200; dbg("Set to 1200") ; break;
+	case B2400: urb_value = ftdi_sio_b2400; dbg("Set to 2400") ; break;
+	case B4800: urb_value = ftdi_sio_b4800; dbg("Set to 4800") ; break;
+	case B9600: urb_value = ftdi_sio_b9600; dbg("Set to 9600") ; break;
+	case B19200: urb_value = ftdi_sio_b19200; dbg("Set to 19200") ; break;
+	case B38400: urb_value = ftdi_sio_b38400; dbg("Set to 38400") ; break;
+	case B57600: urb_value = ftdi_sio_b57600; dbg("Set to 57600") ; break;
+	case B115200: urb_value = ftdi_sio_b115200; dbg("Set to 115200") ; break;
+	default: dbg("FTDI_SIO does not support the baudrate requested"); 
+		/* FIXME - how to return an error for this? */ break;
+	}
+	/* Send the URB */
+	if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    FTDI_SIO_SET_BAUDRATE_REQUEST, 
+			    FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE,
+			    urb_value, 0, 
+			    buf, 0, 100) < 0) {
+		dbg("urb failed to set baurdrate");
+	}
+	return;
+}
+
+/*FIXME - the beginnings of this implementation - not even hooked into the driver yet */
+static int ftdi_sio_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
+{
+	struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+	int port = MINOR(tty->device) - serial->minor;
+	__u16 urb_value=0; /* Will hold the new flags */
+	char buf[1];
+	int  ret, mask;
+	dbg("ftdi_sio_ioctl port %d", port);
+
+	/* Based on code from acm.c */
+	switch (cmd) {
+
+		case TIOCMGET:
+			/* Request the status from the device */
+			if ((ret = usb_control_msg(serial->dev, 
+					    usb_sndctrlpipe(serial->dev, 0),
+					    FTDI_SIO_GET_MODEM_STATUS_REQUEST, 
+					    FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
+					    0, 0, 
+					    buf, 1, HZ * 5)) < 0 ) {
+				dbg("Get not get modem status of device");
+				return(ret);
+			}
+
+			return put_user((buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
+					(buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) |
+					(buf[0]  & FTDI_SIO_RI_MASK  ? TIOCM_RI  : 0) |
+					(buf[0]  & FTDI_SIO_RLSD_MASK ? TIOCM_CD  : 0),
+					(unsigned long *) arg);
+			break;
+
+		case TIOCMSET:
+		case TIOCMBIS:
+		case TIOCMBIC:
+			if ((ret = get_user(mask, (unsigned long *) arg))) return ret;
+
+			/* FIXME Need to remember if we have set DTR or RTS since we
+			   can't ask the device  */
+			/* FIXME - also need to find the meaning of TIOCMBIS/BIC/SET */
+			if (mask & TIOCM_DTR) {
+				switch(cmd) {
+				case TIOCMSET:
+					urb_value = FTDI_SIO_SET_DTR_HIGH | FTDI_SIO_SET_RTS_LOW;
+					break;
+
+				case TIOCMBIS:
+					/* Will leave RTS alone and set DTR */
+					urb_value =  FTDI_SIO_SET_DTR_HIGH;
+					break;
+					
+				case TIOCMBIC:
+					urb_value = FTDI_SIO_SET_DTR_LOW;
+					break;
+				}
+			}
+
+			if (mask & TIOCM_RTS) {
+				switch(cmd) {
+				case TIOCMSET:
+					urb_value = FTDI_SIO_SET_DTR_LOW | FTDI_SIO_SET_RTS_HIGH;
+					break;
+
+				case TIOCMBIS:
+					/* Will leave DTR and set RTS */
+					urb_value = FTDI_SIO_SET_RTS_HIGH;
+					break;
+
+				case TIOCMBIC:
+					/* Will unset RTS */
+					urb_value = FTDI_SIO_SET_RTS_LOW;
+					break;
+				}
+			}	
+
+			
+			return(usb_control_msg(serial->dev, 
+					       usb_sndctrlpipe(serial->dev, 0),
+					       FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
+					       FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
+					       urb_value , 0,
+					       buf, 0, HZ * 5));
+	}
+}
+
 #endif	/* CONFIG_USB_SERIAL_FTDI_SIO */
 
 
@@ -1041,6 +1536,34 @@
 }
 
 
+static void generic_throttle (struct tty_struct *tty) 
+{
+	/* do nothing for the generic device */
+	return;
+}
+
+
+static void generic_unthrottle (struct tty_struct *tty) 
+{
+	/* do nothing for the generic device */
+	return;
+}
+
+
+static int generic_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
+{
+	/* generic driver doesn't support any ioctls yet */
+	return -ENOIOCTLCMD;
+}
+
+
+static void generic_set_termios (struct tty_struct *tty, struct termios * old)
+{
+	/* generic driver doesn't really care about setting any line settings */
+	return;
+}
+
+
 static void generic_read_bulk_callback (struct urb *urb)
 {
 	struct usb_serial *serial = (struct usb_serial *)urb->context;
@@ -1059,7 +1582,7 @@
 	if (urb->actual_length) {
 		printk (KERN_DEBUG __FILE__ ": data read - length = %d, data = ", urb->actual_length);
 		for (i = 0; i < urb->actual_length; ++i) {
-			printk ("0x%.2x ", data[i]);
+			printk ("%.2x ", data[i]);
 		}
 		printk ("\n");
 	}
@@ -1352,8 +1875,8 @@
 	put_char:		NULL,
 	flush_chars:		NULL,
 	write_room:		serial_write_room,
-	ioctl:			NULL,
-	set_termios:		NULL,
+	ioctl:			serial_ioctl,
+	set_termios:		serial_set_termios,
 	set_ldisc:		NULL, 
 	throttle:		serial_throttle,
 	unthrottle:		serial_unthrottle,
@@ -1397,19 +1920,14 @@
 }
 
 
-#ifdef MODULE
-int init_module(void)
-{
-	return usb_serial_init();
-}
-
-void cleanup_module(void)
+void usb_serial_exit(void)
 {
 	tty_unregister_driver(&serial_tty_driver);
 	usb_deregister(&usb_serial_driver);
 }
 
-#else
-__initcall(usb_serial_init);
-#endif
+
+module_init(usb_serial_init);
+module_exit(usb_serial_exit);
+
 
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/usb-serial.h linux/drivers/usb/usb-serial.h
--- v2.3.47/linux/drivers/usb/usb-serial.h	Wed Feb 16 17:03:52 2000
+++ linux/drivers/usb/usb-serial.h	Thu Feb 24 22:50:41 2000
@@ -87,15 +87,6 @@
 
 #define NUM_DONT_CARE	(-1)
 
-/* local function prototypes */
-static int serial_open (struct tty_struct *tty, struct file * filp);
-static void serial_close (struct tty_struct *tty, struct file * filp);
-static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count);
-static int serial_write_room (struct tty_struct *tty);
-static int serial_chars_in_buffer (struct tty_struct *tty);
-static void serial_throttle (struct tty_struct * tty);
-static void serial_unthrottle (struct tty_struct * tty);
-
 
 /* This structure defines the individual serial converter. */
 struct usb_serial_device_type {
@@ -110,6 +101,8 @@
 	char	num_bulk_out;
 	char	num_ports;		/* number of serial ports this device has */
 
+	void	*private;		/* data private to the specific driver */
+	
 	/* function call to make before accepting driver */
 	int (*startup) (struct usb_serial *serial);	/* return 0 to continue initialization, anything else to abort */
 	
@@ -118,21 +111,30 @@
 	void (*close)(struct tty_struct * tty, struct file * filp);
 	int  (*write)(struct tty_struct * tty, int from_user,const unsigned char *buf, int count);
 	int  (*write_room)(struct tty_struct *tty);
+	int  (*ioctl)(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
+	void (*set_termios)(struct tty_struct *tty, struct termios * old);
 	int  (*chars_in_buffer)(struct tty_struct *tty);
 	void (*throttle)(struct tty_struct * tty);
 	void (*unthrottle)(struct tty_struct * tty);
+	
 	void (*read_bulk_callback)(struct urb *urb);
 	void (*write_bulk_callback)(struct urb *urb);
+
 };
 
 
 /* function prototypes for a "generic" type serial converter (no flow control, not all endpoints needed) */
 /* need to always compile these in, as some of the other devices use these functions as their own. */
+/* if a driver does not provide a function pointer, the generic function will be called. */
 static int  generic_serial_open		(struct tty_struct *tty, struct file *filp);
 static void generic_serial_close	(struct tty_struct *tty, struct file *filp);
 static int  generic_serial_write	(struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
 static int  generic_write_room		(struct tty_struct *tty);
+static int  generic_ioctl		(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
+static void generic_set_termios		(struct tty_struct *tty, struct termios * old);
 static int  generic_chars_in_buffer	(struct tty_struct *tty);
+static void generic_throttle		(struct tty_struct *tty);
+static void generic_unthrottle		(struct tty_struct *tty);
 static void generic_read_bulk_callback	(struct urb *urb);
 static void generic_write_bulk_callback	(struct urb *urb);
 
@@ -150,13 +152,6 @@
 	num_bulk_in:		NUM_DONT_CARE,
 	num_bulk_out:		NUM_DONT_CARE,
 	num_ports:		1,
-	open:			generic_serial_open,
-	close:			generic_serial_close,
-	write:			generic_serial_write,
-	write_room:		generic_write_room,
-	chars_in_buffer:	generic_chars_in_buffer,
-	read_bulk_callback:	generic_read_bulk_callback,
-	write_bulk_callback:	generic_write_bulk_callback
 };
 #endif
 
@@ -165,6 +160,7 @@
 /* function prototypes for the Connect Tech WhiteHEAT serial converter */
 static int  whiteheat_serial_open	(struct tty_struct *tty, struct file *filp);
 static void whiteheat_serial_close	(struct tty_struct *tty, struct file *filp);
+static void whiteheat_set_termios	(struct tty_struct *tty, struct termios * old);
 static void whiteheat_throttle		(struct tty_struct *tty);
 static void whiteheat_unthrottle	(struct tty_struct *tty);
 static int  whiteheat_startup		(struct usb_serial *serial);
@@ -198,11 +194,9 @@
 	num_ports:		4,
 	open:			whiteheat_serial_open,
 	close:			whiteheat_serial_close,
-	write:			generic_serial_write,
-	write_room:		generic_write_room,
-	chars_in_buffer:	generic_chars_in_buffer,
 	throttle:		whiteheat_throttle,
-	unthrottle:		whiteheat_unthrottle
+	unthrottle:		whiteheat_unthrottle,
+	set_termios:		whiteheat_set_termios,
 };
 #endif
 
@@ -283,14 +277,9 @@
 	num_ports:		2,
 	open:			visor_serial_open,
 	close:			visor_serial_close,
-	write:			generic_serial_write,
-	write_room:		generic_write_room,
-	chars_in_buffer:	generic_chars_in_buffer,
 	throttle:		visor_throttle,
 	unthrottle:		visor_unthrottle,
 	startup:		visor_startup,
-	read_bulk_callback:	generic_read_bulk_callback,
-	write_bulk_callback:	generic_write_bulk_callback
 };
 #endif
 
@@ -299,8 +288,12 @@
 /* function prototypes for a FTDI serial converter */
 static int  ftdi_sio_serial_open	(struct tty_struct *tty, struct file *filp);
 static void ftdi_sio_serial_close	(struct tty_struct *tty, struct file *filp);
+static int  ftdi_sio_serial_write	(struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
+static void ftdi_sio_read_bulk_callback	(struct urb *urb);
+static void ftdi_sio_set_termios		(struct tty_struct *tty, struct termios * old);
+static int ftdi_sio_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
 
-/* All of the device info needed for the Handspring Visor */
+/* All of the device info needed for the FTDI SIO serial converter */
 static __u16	ftdi_vendor_id		= FTDI_VENDOR_ID;
 static __u16	ftdi_sio_product_id	= FTDI_SIO_SERIAL_CONVERTER_ID;
 static struct usb_serial_device_type ftdi_sio_device = {
@@ -316,11 +309,9 @@
 	num_ports:		1,
 	open:			ftdi_sio_serial_open,
 	close:			ftdi_sio_serial_close,
-	write:			generic_serial_write,
-	write_room:		generic_write_room,
-	chars_in_buffer:	generic_chars_in_buffer,
-	read_bulk_callback:	generic_read_bulk_callback,
-	write_bulk_callback:	generic_write_bulk_callback
+	write:			ftdi_sio_serial_write,
+	read_bulk_callback:	ftdi_sio_read_bulk_callback,
+	set_termios:		ftdi_sio_set_termios
 };
 #endif
 
@@ -331,7 +322,7 @@
 static void keyspan_pda_serial_close	(struct tty_struct *tty, struct file *filp);
 static int  keyspan_pda_startup		(struct usb_serial *serial);
 
-/* All of the device info needed for the Handspring Visor */
+/* All of the device info needed for the Keyspan PDA serial converter */
 static __u16	keyspan_vendor_id		= KEYSPAN_VENDOR_ID;
 static __u16	keyspan_pda_fake_product_id	= KEYSPAN_PDA_FAKE_ID;
 static __u16	keyspan_pda_product_id		= KEYSPAN_PDA_ID;
@@ -360,17 +351,12 @@
 	num_ports:		1,
 	open:			keyspan_pda_serial_open,
 	close:			keyspan_pda_serial_close,
-	write:			generic_serial_write,
-	write_room:		generic_write_room,
-	chars_in_buffer:	generic_chars_in_buffer,
-	read_bulk_callback:	generic_read_bulk_callback,
-	write_bulk_callback:	generic_write_bulk_callback
 };
 #endif
 
 /* To add support for another serial converter, create a usb_serial_device_type
-   structure for that device, and add it to this list, making sure that the last
-   entry is NULL. */
+   structure for that device, and add it to this list, making sure that the
+   last  entry is NULL. */
 static struct usb_serial_device_type *usb_serial_devices[] = {
 #ifdef CONFIG_USB_SERIAL_GENERIC
 	&generic_device,
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/usb-storage-debug.h linux/drivers/usb/usb-storage-debug.h
--- v2.3.47/linux/drivers/usb/usb-storage-debug.h	Sun Feb 20 21:12:39 2000
+++ linux/drivers/usb/usb-storage-debug.h	Mon Feb 21 10:56:40 2000
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #ifdef CONFIG_USB_STORAGE_DEBUG
 
 /* Debug output for Driver for USB mass storage (scsi-like) devices
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/usbkbd.c linux/drivers/usb/usbkbd.c
--- v2.3.47/linux/drivers/usb/usbkbd.c	Thu Feb 10 17:11:15 2000
+++ linux/drivers/usb/usbkbd.c	Wed Feb 23 11:27:14 2000
@@ -32,6 +32,7 @@
 #include <linux/malloc.h>
 #include <linux/module.h>
 #include <linux/input.h>
+#include <linux/init.h>
 #include "usb.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
@@ -202,17 +203,16 @@
 	disconnect:	usb_kbd_disconnect
 };
 
-#ifdef MODULE
-void cleanup_module(void)
+static int __init usb_kbd_init(void)
 {
-	usb_deregister(&usb_kbd_driver);
+	usb_register(&usb_kbd_driver);
+	return 0;
 }
 
-int init_module(void)
-#else
-int usb_kbd_init(void)
-#endif
+static void __exit usb_kbd_exit(void)
 {
-	usb_register(&usb_kbd_driver);
-	return 0;
+	usb_deregister(&usb_kbd_driver);
 }
+
+module_init(usb_kbd_init);
+module_exit(usb_kbd_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/usbmouse.c linux/drivers/usb/usbmouse.c
--- v2.3.47/linux/drivers/usb/usbmouse.c	Fri Jan 28 15:09:08 2000
+++ linux/drivers/usb/usbmouse.c	Wed Feb 23 11:27:14 2000
@@ -32,6 +32,7 @@
 #include <linux/malloc.h>
 #include <linux/input.h>
 #include <linux/module.h>
+#include <linux/init.h>
 #include "usb.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
@@ -132,18 +133,16 @@
 	disconnect:	usb_mouse_disconnect,
 };
 
-#ifdef MODULE
-void cleanup_module(void)
+static int __init usb_mouse_init(void)
 {
-	usb_deregister(&usb_mouse_driver);
+	usb_register(&usb_mouse_driver);
+	return 0;
 }
 
-int init_module(void)
-#else
-int usb_mouse_init(void)
-#endif
+static void __exit usb_mouse_exit(void)
 {
-	usb_register(&usb_mouse_driver);
-	return 0;
+	usb_deregister(&usb_mouse_driver);
 }
 
+module_init(usb_mouse_init);
+module_exit(usb_mouse_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/usb/wmforce.c linux/drivers/usb/wmforce.c
--- v2.3.47/linux/drivers/usb/wmforce.c	Fri Jan 28 15:09:08 2000
+++ linux/drivers/usb/wmforce.c	Wed Feb 23 11:27:14 2000
@@ -32,6 +32,7 @@
 #include <linux/malloc.h>
 #include <linux/input.h>
 #include <linux/module.h>
+#include <linux/init.h>
 #include "usb.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
@@ -149,17 +150,16 @@
 	disconnect:	wmforce_disconnect,
 };
 
-#ifdef MODULE
-void cleanup_module(void)
+static int __init wmforce_init(void)
 {
-	usb_deregister(&wmforce_driver);
+	usb_register(&wmforce_driver);
+	return 0;
 }
 
-int init_module(void)
-#else
-int wmforce_init(void)
-#endif
+static void __exit wmforce_exit(void)
 {
-	usb_register(&wmforce_driver);
-	return 0;
+	usb_deregister(&wmforce_driver);
 }
+
+module_init(wmforce_init);
+module_exit(wmforce_exit);
diff -u --recursive --new-file v2.3.47/linux/drivers/video/Config.in linux/drivers/video/Config.in
--- v2.3.47/linux/drivers/video/Config.in	Sun Feb 13 19:29:04 2000
+++ linux/drivers/video/Config.in	Mon Feb 21 11:08:22 2000
@@ -105,6 +105,10 @@
 	    bool '    Millennium I/II support' CONFIG_FB_MATROX_MILLENIUM
 	    bool '    Mystique support' CONFIG_FB_MATROX_MYSTIQUE
 	    bool '    G100/G200/G400 support' CONFIG_FB_MATROX_G100
+	    dep_tristate '      Matrox I2C support' CONFIG_FB_MATROX_I2C $CONFIG_FB_MATROX $CONFIG_I2C_ALGOBIT
+	    if [ "$CONFIG_FB_MATROX_G100" = "y" ]; then
+	       dep_tristate '      G400 second head support' CONFIG_FB_MATROX_MAVEN $CONFIG_FB_MATROX_I2C
+	    fi
 	    bool '    Multihead support' CONFIG_FB_MATROX_MULTIHEAD
 	 fi
 	 tristate '  ATI Mach64 display support (EXPERIMENTAL)' CONFIG_FB_ATY
diff -u --recursive --new-file v2.3.47/linux/drivers/video/Makefile linux/drivers/video/Makefile
--- v2.3.47/linux/drivers/video/Makefile	Sun Feb 13 19:29:04 2000
+++ linux/drivers/video/Makefile	Mon Feb 21 11:08:22 2000
@@ -3,9 +3,9 @@
 # Rewritten to use lists instead of if-statements.
 
 SUB_DIRS        :=
-MOD_SUB_DIRS    :=
+MOD_SUB_DIRS    := $(SUB_DIRS)
 MOD_IN_SUB_DIRS :=
-ALL_SUB_DIRS    :=
+ALL_SUB_DIRS    := $(SUB_DIRS) matrox
 
 O_TARGET := video.o
 O_OBJS   :=
@@ -16,7 +16,11 @@
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
-export-objs    :=  fbmem.o fbcmap.o fbcon.o fbcon-afb.o fbcon-ilbm.o fbcon-vga.o fbcon-iplan2p2.o fbcon-iplan2p4.o fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o fbcon-vga.o
+export-objs    :=  fbmem.o fbcmap.o fbcon.o fbcon-afb.o fbcon-ilbm.o fbcon-vga.o \
+		   fbcon-iplan2p2.o fbcon-iplan2p4.o fbcon-iplan2p8.o fbcon-vga-planes.o \
+		   fbcon-cfb16.o fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o fbcon-cfb8.o \
+		   fbcon-mac.o fbcon-mfb.o fbcon-vga8-planes.o \
+		   matrox/matroxfb.o
 
 # Object file lists.
 obj-y          :=
@@ -81,10 +85,19 @@
 obj-$(CONFIG_FB_CGFOURTEEN)       += cgfourteenfb.o sbusfb.o
 obj-$(CONFIG_FB_P9100)            += p9100fb.o sbusfb.o
 obj-$(CONFIG_FB_LEO)              += leofb.o sbusfb.o
-obj-$(CONFIG_FB_MATROX)           += matroxfb.o
 obj-$(CONFIG_FB_SUN3)             += sun3fb.o
 obj-$(CONFIG_FB_BWTWO)            += bwtwofb.o
 obj-$(CONFIG_FB_VIRTUAL)          += vfb.o  
+
+ifeq ($(CONFIG_FB_MATROX),y)
+SUB_DIRS			  += matrox
+obj-y				  += matrox/matrox.o
+MOD_SUB_DIRS			  += matrox
+else
+  ifeq ($(CONFIG_FB_MATROX),m)
+  MOD_SUB_DIRS			  += matrox
+  endif
+endif
 
 # Generic Low Level Drivers
 
diff -u --recursive --new-file v2.3.47/linux/drivers/video/aty128fb.c linux/drivers/video/aty128fb.c
--- v2.3.47/linux/drivers/video/aty128fb.c	Sun Feb 20 21:12:39 2000
+++ linux/drivers/video/aty128fb.c	Tue Feb 22 22:30:59 2000
@@ -118,20 +118,19 @@
 /* chip description information */
 struct aty128_chip_info {
     const char *name;
-    unsigned short vendor;
     unsigned short device;
 };
 
 /* supported Rage128 chipsets */
-static const struct aty128_chip_info aty128_pci_probe_list[] =
+static const struct aty128_chip_info aty128_pci_probe_list[] __initdata =
 {
-    {"PCI_DEVICE_ID_ATI_RAGE128_RE", PCI_VENDOR_ID_ATI, 0x5245},
-    {"PCI_DEVICE_ID_ATI_RAGE128_RF", PCI_VENDOR_ID_ATI, 0x5246},
-    {"PCI_DEVICE_ID_ATI_RAGE128_RK", PCI_VENDOR_ID_ATI, 0x524b},
-    {"PCI_DEVICE_ID_ATI_RAGE128_RL", PCI_VENDOR_ID_ATI, 0x524c},
-    {"PCI_DEVICE_ID_ATI_RAGE128_PF", PCI_VENDOR_ID_ATI, 0x5046},
-    {"PCI_DEVICE_ID_ATI_RAGE128_PR", PCI_VENDOR_ID_ATI, 0x5052},
-    {NULL, 0, 0}
+    {"Rage128 RE (PCI)", PCI_DEVICE_ID_ATI_RAGE128_RE},
+    {"Rage128 RF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_RF},
+    {"Rage128 RK (PCI)", PCI_DEVICE_ID_ATI_RAGE128_RK},
+    {"Rage128 RL (AGP)", PCI_DEVICE_ID_ATI_RAGE128_RL},
+    {"Rage128 Pro PF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_PF},
+    {"Rage128 Pro PR (PCI)", PCI_DEVICE_ID_ATI_RAGE128_PR},
+    {NULL, 0}
 };
 
 /* packed BIOS settings */
@@ -186,7 +185,8 @@
 
 static char *aty128fb_name = "ATY Rage128";
 static char fontname[40] __initdata = { 0 };
-static char noaccel __initdata = 0;
+static char noaccel __initdata = 1;
+static unsigned int initdepth __initdata = 8;
 
 #ifndef MODULE
 static const char *mode_option __initdata = NULL;
@@ -253,7 +253,9 @@
     void *regbase;
     const struct aty128_meminfo *mem;   /* onboard mem info    */
     u32 vram_size;                      /* onboard video ram   */
-    void *BIOS_SEG;                     /* BIOS segment        */
+#ifndef CONFIG_PPC
+    void *bios_seg;                     /* video BIOS segment  */
+#endif
     unsigned short card_revision;	/* video card revision */
     struct aty128fb_par default_par, current_par;
     struct display disp;
@@ -362,12 +364,27 @@
 #endif
 #ifdef FBCON_HAS_CFB16
 static struct display_switch fbcon_aty128_16;
+static void fbcon_aty16_putc(struct vc_data *conp, struct display *p,
+                            int c, int yy, int xx);
+static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
+                             const unsigned short *s, int count,
+                             int yy, int xx);
 #endif
 #ifdef FBCON_HAS_CFB24
 static struct display_switch fbcon_aty128_24;
+static void fbcon_aty24_putc(struct vc_data *conp, struct display *p,
+                            int c, int yy, int xx);
+static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
+                             const unsigned short *s, int count,
+                             int yy, int xx);
 #endif
 #ifdef FBCON_HAS_CFB32
 static struct display_switch fbcon_aty128_32;
+static void fbcon_aty32_putc(struct vc_data *conp, struct display *p,
+                            int c, int yy, int xx);
+static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
+                             const unsigned short *s, int count,
+                             int yy, int xx);
 #endif
 
 static struct fb_ops aty128fb_ops = {
@@ -651,7 +668,7 @@
 		GMC_SRC_CLIP_DEFAULT			|
 		GMC_DST_CLIP_DEFAULT			|
 		GMC_BRUSH_SOLIDCOLOR			|
-		(bpp_to_depth(par->crtc.bpp) << 8)	|
+		(bpp_to_depth(par->crtc.bpp << 8))	|
 		GMC_SRC_DSTCOLOR			|
 		GMC_BYTE_ORDER_MSB_TO_LSB		|
 		GMC_DP_CONVERSION_TEMP_6500		|
@@ -911,6 +928,7 @@
     u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
     u32 pix_width;
 
+    /* fun with masking */
     h_total = crtc->h_total & 0x1ff;
     h_disp = (crtc->h_total>>16) & 0xff;
     h_sync_strt = (crtc->h_sync_strt_wid>>3) & 0x1ff;
@@ -1094,7 +1112,7 @@
 	x;
 
 #ifdef DEBUG
-    printk(KERN_DEBUG "x %x\n", x);
+    printk(KERN_DEBUG "aty128fb: x %x\n", x);
 #endif
     b = 0;
     while (x) {
@@ -1109,13 +1127,13 @@
     x = round_div(n, d);
     roff = x * (fifo_depth - 4);
     if ((ron + m->Rloop) >= roff) {
-	printk(KERN_ERR "Mode out of range\n");
+	printk(KERN_ERR "aty128fb: Mode out of range!\n");
 	return -EINVAL;
     }
 
 #ifdef DEBUG
-    printk(KERN_DEBUG "p: %x rloop: %x x: %x ron: %x roff: %x\n", p,
-                       m->Rloop, x, ron, roff);
+    printk(KERN_DEBUG "aty128fb: p: %x rloop: %x x: %x ron: %x roff: %x\n",
+                       p, m->Rloop, x, ron, roff);
 #endif
     dsp->dda_config = p << 16 | m->Rloop << 20 | x;
     dsp->dda_on_off = ron << 16 | roff;
@@ -1203,10 +1221,10 @@
 {
     int err;
 
-    if ((err = aty128_var_to_crtc(var, &(par->crtc), info)))
+    if ((err = aty128_var_to_crtc(var, &par->crtc, info)))
 	return err;
 
-    if ((err = aty128_var_to_pll(var->pixclock, &(par->pll), info)))
+    if ((err = aty128_var_to_pll(var->pixclock, &par->pll, info)))
 	return err;
 
     if ((err = aty128_ddafifo(&par->fifo_reg, &par->pll, par->crtc.bpp, info)))
@@ -1587,7 +1605,25 @@
 	    fontname[i] = 0;
 	} else if (!strncmp(this_opt, "noaccel", 7)) {
 	    noaccel = 1;
-	}
+	} else if (!strncmp(this_opt, "depth:", 6)) {
+            unsigned int depth = simple_strtoul(this_opt+6, NULL, 0);
+            switch (depth) {
+            case 0 ... 8:
+                initdepth = 8;
+                break;
+            case 9 ... 16:
+                initdepth = 16;
+                break;
+            case 17 ... 24:
+                initdepth = 24;
+                break;
+            case 25 ... 32:
+                initdepth = 32;
+                break;
+            default:
+                initdepth = 8;
+            }
+        }
 #ifdef CONFIG_MTRR
         else if(!strncmp(this_opt, "nomtrr", 6)) {
             mtrr = 0;
@@ -1636,9 +1672,11 @@
     u32 dac;
     int j, k;
     u8 chip_rev;
+    const struct aty128_chip_info *aci = &aty128_pci_probe_list[0];
+    char *video_card = NULL;
 
     if (!register_test(info)) {
-	printk(KERN_ERR "Can't write to video registers\n");
+	printk(KERN_ERR "aty128fb: Can't write to video registers\n");
 	return 0;
     }
 
@@ -1647,14 +1685,17 @@
 
     chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
 
-    /* TODO: be more verbose */
-    printk(KERN_INFO "aty128fb: Rage128 [chip rev 0x%x] [card rev %x] ",
-                      chip_rev, info->card_revision);
+    /* put a name with the face */
+    while (info->pdev->device != aci->device) { aci++; }
+    video_card = (char *)aci->name;
+
+    printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] [card rev %x] ",
+                      video_card, chip_rev, info->card_revision);
 
     if (info->vram_size % (1024 * 1024) == 0)
-	printk("%dM \n", info->vram_size / (1024*1024));
+	printk("%dM\n", info->vram_size / (1024*1024));
     else
-	printk("%dk \n", info->vram_size / 1024);
+	printk("%dk\n", info->vram_size / 1024);
 
     /* fill in info */
     strcpy(info->fb_info.modename, aty128fb_name);
@@ -1678,7 +1719,7 @@
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)
 	if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0,
-			  &defaultmode, 8))
+			  &defaultmode, initdepth))
 	    var = default_var;
 #endif
 
@@ -1767,13 +1808,13 @@
     struct pci_dev *pdev = NULL;
     const struct aty128_chip_info *aci = &aty128_pci_probe_list[0];
 
-    while(aci->name != NULL) {
-	pdev = pci_find_device(aci->vendor, aci->device, NULL);
-	while(pdev != NULL) {
-            if(aty128_pci_register(pdev, aci) > 0)
+    while (aci->name != NULL) {
+        pdev = pci_find_device(PCI_VENDOR_ID_ATI, aci->device, pdev);
+        while (pdev != NULL) {
+            if (aty128_pci_register(pdev, aci) == 0)
                 return;
-            pdev = pci_find_device(aci->vendor, aci->device, pdev);
-	}
+            pdev = pci_find_device(PCI_VENDOR_ID_ATI, aci->device, pdev);
+        }
 	aci++;
     }
 
@@ -1797,16 +1838,16 @@
     fb_addr = rp->start;
     fb_addr &= PCI_BASE_ADDRESS_MEM_MASK;
 
-    request_mem_region (rp->start, rp->end - rp->start + 1, "aty128fb");
+    request_mem_region(rp->start, rp->end - rp->start + 1, "aty128fb");
 
     rp = &pdev->resource[2];
     reg_addr = rp->start;
     reg_addr &= PCI_BASE_ADDRESS_MEM_MASK;
 
     if (!reg_addr) {
-        release_mem_region (pdev->resource[0].start,
-                            pdev->resource[0].end -
-                            pdev->resource[0].start + 1);
+        release_mem_region(pdev->resource[0].start,
+                           pdev->resource[0].end -
+                           pdev->resource[0].start + 1);
         return -1;
     }
 #else
@@ -1874,13 +1915,13 @@
     return 0;
 
 err_out:
-    kfree (info);
+    kfree(info);
 unmap_out:
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)
-    release_mem_region (pdev->resource[0].start,
+    release_mem_region(pdev->resource[0].start,
 			pdev->resource[0].end -
 			pdev->resource[0].start + 1);
-    release_mem_region (pdev->resource[2].start,
+    release_mem_region(pdev->resource[2].start,
 			pdev->resource[2].end -
 			pdev->resource[2].start + 1);
 #endif
@@ -1949,7 +1990,7 @@
 
         printk(KERN_INFO "aty128fb: Rage128 BIOS located at segment %4.4X\n",
                          (u32)rom_base);
-        info->BIOS_SEG = rom_base;
+        info->bios_seg = rom_base;
         flag = 1;
         break;
     }
@@ -1965,16 +2006,16 @@
     u16 bios_header_offset, pll_info_offset;
     PLL_BLOCK pll;
 
-    bios_header = info->BIOS_SEG + 0x48L;
+    bios_header = info->bios_seg + 0x48L;
     header_ptr = bios_header;
 
     bios_header_offset = readw(header_ptr);
-    bios_header = info->BIOS_SEG + bios_header_offset;
+    bios_header = info->bios_seg + bios_header_offset;
     bios_header += 0x30;
 
     header_ptr = bios_header;
     pll_info_offset = readw(header_ptr);
-    header_ptr = info->BIOS_SEG + pll_info_offset;
+    header_ptr = info->bios_seg + pll_info_offset;
 
     memcpy_fromio(&pll, header_ptr, 50);
 
@@ -2013,8 +2054,8 @@
     }       
 
     /* free up to-be unused resources */
-    if (info->BIOS_SEG)
-        iounmap(info->BIOS_SEG);
+    if (info->bios_seg)
+        iounmap(info->bios_seg);
 
     return;
 }           
@@ -2346,7 +2387,6 @@
 }
 
 
-/* TODO: Fix accel and add to these structs */
 #ifdef FBCON_HAS_CFB8
 static void fbcon_aty8_putc(struct vc_data *conp, struct display *p,
                             int c, int yy, int xx)
diff -u --recursive --new-file v2.3.47/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c
--- v2.3.47/linux/drivers/video/atyfb.c	Sun Feb 13 19:29:04 2000
+++ linux/drivers/video/atyfb.c	Sat Feb 26 20:46:44 2000
@@ -1,4 +1,4 @@
-/*  $Id: atyfb.c,v 1.139 2000/02/12 22:47:04 davem Exp $
+/*  $Id: atyfb.c,v 1.140 2000/02/25 05:46:27 davem Exp $
  *  linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
  *
  *	Copyright (C) 1997-1998  Geert Uytterhoeven
@@ -63,11 +63,13 @@
 
 #ifdef __powerpc__
 #include <linux/adb.h>
-#include <linux/pmu.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <video/macmodes.h>
 #endif
+#ifdef CONFIG_ADB_PMU
+#include <linux/pmu.h>
+#endif
 #ifdef CONFIG_NVRAM
 #include <linux/nvram.h>
 #endif
@@ -121,10 +123,6 @@
 #define GUI_RESERVE	(1 * PAGE_SIZE)
 
 
-#ifndef __powerpc__
-#define eieio()		/* Enforce In-order Execution of I/O */
-#endif
-
 /* FIXME: remove the FAIL definition */
 #define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
 
@@ -3205,25 +3203,18 @@
 			tmp |= 0x2;
 		aty_st_8(DAC_CNTL, tmp, info);
 		aty_st_8(DAC_MASK, 0xff, info);
-		eieio();
+
 		scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
 			(info->current_par.crtc.bpp == 16)) ? 3 : 0;
-		info->aty_cmap_regs->rindex = i << scale;
-		eieio();
-		atyfb_save.r[enter][i] = info->aty_cmap_regs->lut;
-		eieio();
-		atyfb_save.g[enter][i] = info->aty_cmap_regs->lut;
-		eieio();
-		atyfb_save.b[enter][i] = info->aty_cmap_regs->lut;
-		eieio();
-		info->aty_cmap_regs->windex = i << scale;
-		eieio();
-		info->aty_cmap_regs->lut = atyfb_save.r[1-enter][i];
-		eieio();
-		info->aty_cmap_regs->lut = atyfb_save.g[1-enter][i];
-		eieio();
-		info->aty_cmap_regs->lut = atyfb_save.b[1-enter][i];
-		eieio();
+		writeb(i << scale, &info->aty_cmap_regs->rindex);
+
+		atyfb_save.r[enter][i] = readb(&info->aty_cmap_regs->lut);
+		atyfb_save.g[enter][i] = readb(&info->aty_cmap_regs->lut);
+		atyfb_save.b[enter][i] = readb(&info->aty_cmap_regs->lut);
+		writeb(i << scale, &info->aty_cmap_regs->windex);
+		writeb(atyfb_save.r[1-enter][i], &info->aty_cmap_regs->lut);
+		writeb(atyfb_save.g[1-enter][i], &info->aty_cmap_regs->lut);
+		writeb(atyfb_save.b[1-enter][i], &info->aty_cmap_regs->lut);
 	}
 }
 
@@ -3276,9 +3267,6 @@
     u8 pll_ref_div;
 
     info->aty_cmap_regs = (struct aty_cmap_regs *)(info->ati_regbase+0xc0);
-#ifdef __sparc_v9__
-    info->aty_cmap_regs = __va(info->aty_cmap_regs);
-#endif
     chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
     Gx = chip_id & CFG_CHIP_TYPE;
     Rev = (chip_id & CFG_CHIP_REV)>>24;
@@ -3519,6 +3507,9 @@
 	    info->total_vram -= GUI_RESERVE;
 	}
 
+    /* Clear the video memory */
+    memset_io(info->frame_buffer, 0, info->total_vram);
+
     disp = &info->disp;
 
     strcpy(info->fb_info.modename, atyfb_name);
@@ -3692,7 +3683,7 @@
 	    /*
 	     * Map in big-endian aperture.
 	     */
-	    info->frame_buffer = (unsigned long) __va(addr + 0x800000UL);
+	    info->frame_buffer = (unsigned long) addr + 0x800000UL;
 	    info->frame_buffer_phys = addr + 0x800000UL;
 
 	    /*
@@ -3937,7 +3928,7 @@
 	     * Add /dev/fb mmap values.
 	     */
 	    info->mmap_map[0].voff = 0x8000000000000000UL;
-	    info->mmap_map[0].poff = __pa(info->frame_buffer & PAGE_MASK);
+	    info->mmap_map[0].poff = info->frame_buffer & PAGE_MASK;
 	    info->mmap_map[0].size = info->total_vram;
 	    info->mmap_map[0].prot_mask = _PAGE_CACHE;
 	    info->mmap_map[0].prot_flag = _PAGE_E;
@@ -4186,7 +4177,7 @@
     struct fb_info_aty *info = (struct fb_info_aty *)fb;
     u8 gen_cntl;
 
-#ifdef CONFIG_PPC
+#ifdef CONFIG_ADB_PMU
     if ((_machine == _MACH_Pmac) && blank)
     	pmu_enable_backlight(0);
 #endif
@@ -4211,7 +4202,7 @@
 	gen_cntl &= ~(0x4c);
     aty_st_8(CRTC_GEN_CNTL, gen_cntl, info);
 
-#ifdef CONFIG_PPC
+#ifdef CONFIG_ADB_PMU
     if ((_machine == _MACH_Pmac) && !blank)
     	pmu_enable_backlight(1);
 #endif
@@ -4268,14 +4259,10 @@
     aty_st_8(DAC_MASK, 0xff, info);
     scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
 	     (info->current_par.crtc.bpp == 16)) ? 3 : 0;
-    info->aty_cmap_regs->windex = regno << scale;
-    eieio();
-    info->aty_cmap_regs->lut = red;
-    eieio();
-    info->aty_cmap_regs->lut = green;
-    eieio();
-    info->aty_cmap_regs->lut = blue;
-    eieio();
+    writeb(regno << scale, &info->aty_cmap_regs->windex);
+    writeb(red, &info->aty_cmap_regs->lut);
+    writeb(green, &info->aty_cmap_regs->lut);
+    writeb(blue, &info->aty_cmap_regs->lut);
     if (regno < 16)
 	switch (info->current_par.crtc.bpp) {
 #ifdef FBCON_HAS_CFB16
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/Makefile linux/drivers/video/matrox/Makefile
--- v2.3.47/linux/drivers/video/matrox/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/Makefile	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,60 @@
+# Makefile for the Linux video drivers.
+# 5 Aug 1999, James Simmons, <mailto:jsimmons@edgeglobal.com>
+# Rewritten to use lists instead of if-statements.
+
+SUB_DIRS        :=
+MOD_SUB_DIRS    := $(SUB_DIRS)
+MOD_IN_SUB_DIRS :=
+ALL_SUB_DIRS    := $(SUB_DIRS)
+
+O_TARGET := matrox.o
+O_OBJS   :=
+M_OBJS   :=
+# This is a nice idea but needs depmod altering
+# MOD_LIST_NAME := VIDEO_MODULES
+
+# All of the (potential) objects that export symbols.
+# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
+
+export-objs    :=  matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o
+
+# Object file lists.
+obj-y          :=
+obj-m          :=
+obj-n          :=
+obj-           :=
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_FB_MATROX)           += matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o
+obj-$(CONFIG_FB_MATROX_I2C)       += i2c-matroxfb.o
+obj-$(CONFIG_FB_MATROX_MAVEN)     += matroxfb_maven.o matroxfb_crtc2.o
+
+# Extract lists of the multi-part drivers.
+# The 'int-*' lists are the intermediate files used to build the multi's.
+
+multi-y         := $(filter $(list-multi), $(obj-y))
+multi-m         := $(filter $(list-multi), $(obj-m))
+int-y           := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs)))
+int-m           := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs)))
+
+# Files that are both resident and modular: remove from modular.
+
+obj-m          := $(filter-out $(obj-y), $(obj-m))
+int-m          := $(filter-out $(int-y), $(int-m))
+
+# Take multi-part drivers out of obj-y and put components in.
+
+obj-y          := $(filter-out $(list-multi), $(obj-y)) $(int-y)
+
+# Translate to Rules.make lists.
+
+O_OBJS         := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS        := $(filter     $(export-objs), $(obj-y))
+M_OBJS         := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS        := $(sort $(filter     $(export-objs), $(obj-m)))
+
+include $(TOPDIR)/Rules.make
+
+clean:
+	rm -f core *.o *.a *.s
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/i2c-matroxfb.c linux/drivers/video/matrox/i2c-matroxfb.c
--- v2.3.47/linux/drivers/video/matrox/i2c-matroxfb.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/i2c-matroxfb.c	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,348 @@
+#include "matroxfb_base.h"
+#include "matroxfb_maven.h"
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+/* MGA-TVO I2C for G200, G400 */
+#define MAT_CLK		0x20
+#define MAT_DATA	0x10
+/* primary head DDC for Mystique(?), G100, G200, G400 */
+#define DDC1_CLK	0x08
+#define DDC1_DATA	0x02
+/* primary head DDC for Millennium, Millennium II */
+#define DDC1B_CLK	0x10
+#define DDC1B_DATA	0x04
+/* secondary head DDC for G400 */
+#define DDC2_CLK	0x04
+#define DDC2_DATA	0x01
+
+/******************************************************/
+
+static int matroxfb_read_gpio(struct matrox_fb_info* minfo) {
+	unsigned long flags;
+	int v;
+
+	matroxfb_DAC_lock_irqsave(flags);
+	v = matroxfb_DAC_in(PMINFO DAC_XGENIODATA);
+	matroxfb_DAC_unlock_irqrestore(flags);
+	return v;
+}
+
+static inline void matroxfb_set_gpio(struct matrox_fb_info* minfo, int mask, int val) {
+	unsigned long flags;
+	int v;
+
+	matroxfb_DAC_lock_irqsave(flags);
+	v = (matroxfb_DAC_in(PMINFO DAC_XGENIOCTRL) & mask) | val;
+	matroxfb_DAC_out(PMINFO DAC_XGENIOCTRL, v);
+	/* We must reset GENIODATA very often... XFree plays with this register */
+	matroxfb_DAC_out(PMINFO DAC_XGENIODATA, 0x00);
+	matroxfb_DAC_unlock_irqrestore(flags);
+}
+
+/* software I2C functions */
+static void matroxfb_i2c_set(struct matrox_fb_info* minfo, int mask, int state) {
+	if (state)
+		state = 0;
+	else
+		state = mask;
+	matroxfb_set_gpio(minfo, ~mask, state);
+}
+
+static void matroxfb_maven_setsda(void* data, int state) {
+	matroxfb_i2c_set(data, MAT_DATA, state);
+}
+
+static void matroxfb_maven_setscl(void* data, int state) {
+	matroxfb_i2c_set(data, MAT_CLK, state);
+}
+
+static int matroxfb_maven_getsda(void* data) {
+	return (matroxfb_read_gpio(data) & MAT_DATA) ? 1 : 0;
+}
+
+static int matroxfb_maven_getscl(void* data) {
+	return (matroxfb_read_gpio(data) & MAT_CLK) ? 1 : 0;
+}
+
+static void matroxfb_ddc1_setsda(void* data, int state) {
+	matroxfb_i2c_set(data, DDC1_DATA, state);
+}
+
+static void matroxfb_ddc1_setscl(void* data, int state) {
+	matroxfb_i2c_set(data, DDC1_CLK, state);
+}
+
+static int matroxfb_ddc1_getsda(void* data) {
+	return (matroxfb_read_gpio(data) & DDC1_DATA) ? 1 : 0;
+}
+
+static int matroxfb_ddc1_getscl(void* data) {
+	return (matroxfb_read_gpio(data) & DDC1_CLK) ? 1 : 0;
+}
+
+static void matroxfb_ddc1b_setsda(void* data, int state) {
+	matroxfb_i2c_set(data, DDC1B_DATA, state);
+}
+
+static void matroxfb_ddc1b_setscl(void* data, int state) {
+	matroxfb_i2c_set(data, DDC1B_CLK, state);
+}
+
+static int matroxfb_ddc1b_getsda(void* data) {
+	return (matroxfb_read_gpio(data) & DDC1B_DATA) ? 1 : 0;
+}
+
+static int matroxfb_ddc1b_getscl(void* data) {
+	return (matroxfb_read_gpio(data) & DDC1B_CLK) ? 1 : 0;
+}
+
+static void matroxfb_ddc2_setsda(void* data, int state) {
+	matroxfb_i2c_set(data, DDC2_DATA, state);
+}
+
+static void matroxfb_ddc2_setscl(void* data, int state) {
+	matroxfb_i2c_set(data, DDC2_CLK, state);
+}
+
+static int matroxfb_ddc2_getsda(void* data) {
+	return (matroxfb_read_gpio(data) & DDC2_DATA) ? 1 : 0;
+}
+
+static int matroxfb_ddc2_getscl(void* data) {
+	return (matroxfb_read_gpio(data) & DDC2_CLK) ? 1 : 0;
+}
+
+static void matroxfb_dh_inc_use(struct i2c_adapter* dummy) {
+	MOD_INC_USE_COUNT;
+}
+
+static void matroxfb_dh_dec_use(struct i2c_adapter* dummy) {
+	MOD_DEC_USE_COUNT;
+}
+
+static struct i2c_adapter matroxmaven_i2c_adapter_template =
+{
+	"",
+	I2C_HW_B_G400,
+
+	NULL,
+	NULL,
+
+	matroxfb_dh_inc_use,
+	matroxfb_dh_dec_use,
+	NULL,
+	NULL,
+	NULL,
+};
+
+static struct i2c_algo_bit_data matroxmaven_i2c_algo_template =
+{
+	NULL,
+	matroxfb_maven_setsda,
+	matroxfb_maven_setscl,
+	matroxfb_maven_getsda,
+	matroxfb_maven_getscl,
+	10, 10, 100,
+};
+
+static struct i2c_adapter matrox_ddc1_adapter_template =
+{
+	"",
+	I2C_HW_B_G400, /* DDC */
+
+	NULL,
+	NULL,
+
+	matroxfb_dh_inc_use,
+	matroxfb_dh_dec_use,
+	NULL,
+	NULL,
+	NULL,
+};
+
+static struct i2c_algo_bit_data matrox_ddc1_algo_template =
+{
+	NULL,
+	matroxfb_ddc1_setsda,
+	matroxfb_ddc1_setscl,
+	matroxfb_ddc1_getsda,
+	matroxfb_ddc1_getscl,
+	10, 10, 100,
+};
+
+static struct i2c_algo_bit_data matrox_ddc1b_algo_template =
+{
+	NULL,
+	matroxfb_ddc1b_setsda,
+	matroxfb_ddc1b_setscl,
+	matroxfb_ddc1b_getsda,
+	matroxfb_ddc1b_getscl,
+	10, 10, 100,
+};
+
+static struct i2c_adapter matrox_ddc2_adapter_template =
+{
+	"",
+	I2C_HW_B_G400,	/* DDC */
+
+	NULL,
+	NULL,
+
+	matroxfb_dh_inc_use, /* should increment matroxfb_maven usage too, this DDC is coupled with maven_client */
+	matroxfb_dh_dec_use, /* should decrement matroxfb_maven usage too */
+	NULL,
+	NULL,
+	NULL,
+};
+
+static struct i2c_algo_bit_data matrox_ddc2_algo_template =
+{
+	NULL,
+	matroxfb_ddc2_setsda,
+	matroxfb_ddc2_setscl,
+	matroxfb_ddc2_getsda,
+	matroxfb_ddc2_getscl,
+	10, 10, 100,
+};
+
+static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo) {
+	int err;
+
+	b->adapter.data = minfo;
+	b->adapter.algo_data = &b->bac;
+	b->bac.data = minfo;
+	err = i2c_bit_add_bus(&b->adapter);
+	b->initialized = !err;
+	return err;
+}
+
+static void i2c_bit_bus_del(struct i2c_bit_adapter* b) {
+	if (b->initialized) {
+		i2c_bit_del_bus(&b->adapter);
+		b->initialized = 0;
+	}
+}
+
+static inline int i2c_maven_init(struct matroxfb_dh_maven_info* minfo2) {
+	struct i2c_bit_adapter *b = &minfo2->maven;
+
+	b->adapter = matroxmaven_i2c_adapter_template;
+	b->bac = matroxmaven_i2c_algo_template;
+	sprintf(b->adapter.name, "MAVEN:fb%u on i2c-matroxfb", GET_FB_IDX(minfo2->primary_dev->fbcon.node));
+	return i2c_bus_reg(b, minfo2->primary_dev);
+}
+
+static inline void i2c_maven_done(struct matroxfb_dh_maven_info* minfo2) {
+	i2c_bit_bus_del(&minfo2->maven);
+}
+
+static inline int i2c_ddc1_init(struct matroxfb_dh_maven_info* minfo2) {
+	struct i2c_bit_adapter *b = &minfo2->ddc1;
+
+	b->adapter = matrox_ddc1_adapter_template;
+	b->bac = matrox_ddc1_algo_template;
+	sprintf(b->adapter.name, "DDC:fb%u #0 on i2c-matroxfb", GET_FB_IDX(minfo2->primary_dev->fbcon.node));
+	return i2c_bus_reg(b, minfo2->primary_dev);
+}
+
+static inline int i2c_ddc1b_init(struct matroxfb_dh_maven_info* minfo2) {
+	struct i2c_bit_adapter *b = &minfo2->ddc1;
+
+	b->adapter = matrox_ddc1_adapter_template;
+	b->bac = matrox_ddc1b_algo_template;
+	sprintf(b->adapter.name, "DDC:fb%u #0 on i2c-matroxfb", GET_FB_IDX(minfo2->primary_dev->fbcon.node));
+	return i2c_bus_reg(b, minfo2->primary_dev);
+}
+
+static inline void i2c_ddc1_done(struct matroxfb_dh_maven_info* minfo2) {
+	i2c_bit_bus_del(&minfo2->ddc1);
+}
+
+static inline int i2c_ddc2_init(struct matroxfb_dh_maven_info* minfo2) {
+	struct i2c_bit_adapter *b = &minfo2->ddc2;
+
+	b->adapter = matrox_ddc2_adapter_template;
+	b->bac = matrox_ddc2_algo_template;
+	sprintf(b->adapter.name, "DDC:fb%u #1 on i2c-matroxfb", GET_FB_IDX(minfo2->primary_dev->fbcon.node));
+	return i2c_bus_reg(b, minfo2->primary_dev);
+}
+
+static inline void i2c_ddc2_done(struct matroxfb_dh_maven_info* minfo2) {
+	i2c_bit_bus_del(&minfo2->ddc2);
+}
+
+static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
+	int err;
+	unsigned long flags;
+	struct matroxfb_dh_maven_info* m2info;
+
+	m2info = (struct matroxfb_dh_maven_info*)kmalloc(sizeof(*m2info), GFP_KERNEL);
+	if (!m2info)
+		return NULL;
+
+	matroxfb_DAC_lock_irqsave(flags);
+	matroxfb_DAC_out(PMINFO DAC_XGENIODATA, 0x00);
+	matroxfb_DAC_out(PMINFO DAC_XGENIOCTRL, 0xFF);
+	matroxfb_DAC_unlock_irqrestore(flags);
+
+	memset(m2info, 0, sizeof(*m2info));
+	m2info->primary_dev = minfo;
+
+	if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGA2064W ||
+	    ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGA2164W ||
+	    ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGA2164W_AGP)
+		err = i2c_ddc1b_init(m2info);
+	else
+		err = i2c_ddc1_init(m2info);
+	if (err)
+		goto fail_ddc1;
+	if (ACCESS_FBINFO(devflags.maven_capable)) {
+		err = i2c_ddc2_init(m2info);
+		if (err)
+			printk(KERN_INFO "i2c-matroxfb: Could not register secondary output i2c bus. Continuing anyway.\n");
+		err = i2c_maven_init(m2info);
+		if (err)
+			printk(KERN_INFO "i2c-matroxfb: Could not register Maven i2c bus. Continuing anyway.\n");
+	}
+	return m2info;
+fail_ddc1:;
+	kfree(m2info);
+	printk(KERN_ERR "i2c-matroxfb: Could not register primary adapter DDC bus.\n");
+	return NULL;
+}
+
+static void i2c_matroxfb_remove(struct matrox_fb_info* minfo, void* data) {
+	struct matroxfb_dh_maven_info* m2info = data;
+
+	i2c_maven_done(m2info);
+	i2c_ddc2_done(m2info);
+	i2c_ddc1_done(m2info);
+	kfree(m2info);
+}
+
+static struct matroxfb_driver i2c_matroxfb = {
+	LIST_HEAD_INIT(i2c_matroxfb.node),
+	"i2c-matroxfb",
+	i2c_matroxfb_probe,
+	i2c_matroxfb_remove,
+};
+
+static int __init i2c_matroxfb_init(void) {
+	if (matroxfb_register_driver(&i2c_matroxfb)) {
+		printk(KERN_ERR "i2c-matroxfb: failed to register driver\n");
+		return -ENXIO;
+	}
+	return 0;
+}
+
+static void __exit i2c_matroxfb_exit(void) {
+	matroxfb_unregister_driver(&i2c_matroxfb);
+}
+
+MODULE_AUTHOR("(c) 1999 Petr Vandrovec <vandrove@vc.cvut.cz>");
+MODULE_DESCRIPTION("Support module providing I2C buses present on Matrox videocards");
+
+module_init(i2c_matroxfb_init);
+module_exit(i2c_matroxfb_exit);
+/* no __setup required */
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_DAC1064.c linux/drivers/video/matrox/matroxfb_DAC1064.c
--- v2.3.47/linux/drivers/video/matrox/matroxfb_DAC1064.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_DAC1064.c	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,924 @@
+/*
+ *
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
+ *
+ * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>
+ *
+ * Version: 1.21 1999/01/09
+ *
+ * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
+ *
+ * Contributors: "menion?" <menion@mindless.com>
+ *                     Betatesting, fixes, ideas
+ *
+ *               "Kurt Garloff" <garloff@kg1.ping.de>
+ *                     Betatesting, fixes, ideas, videomodes, videomodes timmings
+ *
+ *               "Tom Rini" <trini@kernel.crashing.org>
+ *                     MTRR stuff, PPC cleanups, betatesting, fixes, ideas
+ *
+ *               "Bibek Sahu" <scorpio@dodds.net>
+ *                     Access device through readb|w|l and write b|w|l
+ *                     Extensive debugging stuff
+ *
+ *               "Daniel Haun" <haund@usa.net>
+ *                     Testing, hardware cursor fixes
+ *
+ *               "Scott Wood" <sawst46+@pitt.edu>
+ *                     Fixes
+ *
+ *               "Gerd Knorr" <kraxel@goldbach.isdn.cs.tu-berlin.de>
+ *                     Betatesting
+ *
+ *               "Kelly French" <targon@hazmat.com>
+ *               "Fernando Herrera" <fherrera@eurielec.etsit.upm.es>
+ *                     Betatesting, bug reporting
+ *
+ *               "Pablo Bianucci" <pbian@pccp.com.ar>
+ *                     Fixes, ideas, betatesting
+ *
+ *               "Inaky Perez Gonzalez" <inaky@peloncho.fis.ucm.es>
+ *                     Fixes, enhandcements, ideas, betatesting
+ *
+ *               "Ryuichi Oikawa" <roikawa@rr.iiij4u.or.jp>
+ *                     PPC betatesting, PPC support, backward compatibility
+ *
+ *               "Paul Womar" <Paul@pwomar.demon.co.uk>
+ *               "Owen Waller" <O.Waller@ee.qub.ac.uk>
+ *                     PPC betatesting
+ *
+ *               "Thomas Pornin" <pornin@bolet.ens.fr>
+ *                     Alpha betatesting
+ *
+ *               "Pieter van Leuven" <pvl@iae.nl>
+ *               "Ulf Jaenicke-Roessler" <ujr@physik.phy.tu-dresden.de>
+ *                     G100 testing
+ *
+ *               "H. Peter Arvin" <hpa@transmeta.com>
+ *                     Ideas
+ *
+ *               "Cort Dougan" <cort@cs.nmt.edu>
+ *                     CHRP fixes and PReP cleanup
+ *
+ *               "Mark Vojkovich" <mvojkovi@ucsd.edu>
+ *                     G400 support
+ *
+ * (following author is not in any relation with this code, but his code
+ *  is included in this driver)
+ *
+ * Based on framebuffer driver for VBE 2.0 compliant graphic boards
+ *     (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
+ *
+ * (following author is not in any relation with this code, but his ideas
+ *  were used when writting this driver)
+ *
+ *		 FreeVBE/AF (Matrox), "Shawn Hargreaves" <shawn@talula.demon.co.uk>
+ *
+ */
+
+/* make checkconfig does not walk through include tree :-( */
+#include <linux/config.h>
+
+#include "matroxfb_DAC1064.h"
+#include "matroxfb_misc.h"
+#include "matroxfb_accel.h"
+#include <linux/matroxfb.h>
+
+#ifdef NEED_DAC1064
+#define outDAC1064 matroxfb_DAC_out
+#define inDAC1064 matroxfb_DAC_in
+
+#define DAC1064_OPT_SCLK_PCI	0x00
+#define DAC1064_OPT_SCLK_PLL	0x01
+#define DAC1064_OPT_SCLK_EXT	0x02
+#define DAC1064_OPT_SCLK_MASK	0x03
+#define DAC1064_OPT_GDIV1	0x04	/* maybe it is GDIV2 on G100 ?! */
+#define DAC1064_OPT_GDIV3	0x00
+#define DAC1064_OPT_MDIV1	0x08
+#define DAC1064_OPT_MDIV2	0x00
+#define DAC1064_OPT_RESERVED	0x10
+
+static void matroxfb_DAC1064_flashcursor(unsigned long ptr) {
+#define minfo ((struct matrox_fb_info*)ptr)
+	matroxfb_DAC_lock();
+	outDAC1064(PMINFO M1064_XCURCTRL, inDAC1064(PMINFO M1064_XCURCTRL) ^ M1064_XCURCTRL_DIS ^ M1064_XCURCTRL_XGA);
+	ACCESS_FBINFO(cursor.timer.expires) = jiffies + HZ/2;
+	add_timer(&ACCESS_FBINFO(cursor.timer));
+	matroxfb_DAC_unlock();
+#undef minfo
+}
+
+static void matroxfb_DAC1064_createcursor(WPMINFO struct display* p) {
+	vaddr_t cursorbase;
+	u_int32_t xline;
+	unsigned int i;
+	unsigned int h, to;
+	CRITFLAGS
+
+	if (ACCESS_FBINFO(currcon_display) != p)
+		return;
+
+	matroxfb_createcursorshape(PMINFO p, p->var.vmode);
+
+	xline = (~0) << (32 - ACCESS_FBINFO(cursor.w));
+	cursorbase = ACCESS_FBINFO(video.vbase);
+	h = ACCESS_FBINFO(features.DAC1064.cursorimage);
+
+	CRITBEGIN
+
+#ifdef __BIG_ENDIAN
+	WaitTillIdle();
+	mga_outl(M_OPMODE, M_OPMODE_32BPP);
+#endif
+	to = ACCESS_FBINFO(cursor.u);
+	for (i = 0; i < to; i++) {
+		mga_writel(cursorbase, h, 0);
+		mga_writel(cursorbase, h+4, 0);
+		mga_writel(cursorbase, h+8, ~0);
+		mga_writel(cursorbase, h+12, ~0);
+		h += 16;
+	}
+	to = ACCESS_FBINFO(cursor.d);
+	for (; i < to; i++) {
+		mga_writel(cursorbase, h, 0);
+		mga_writel(cursorbase, h+4, xline);
+		mga_writel(cursorbase, h+8, ~0);
+		mga_writel(cursorbase, h+12, ~0);
+		h += 16;
+	}
+	for (; i < 64; i++) {
+		mga_writel(cursorbase, h, 0);
+		mga_writel(cursorbase, h+4, 0);
+		mga_writel(cursorbase, h+8, ~0);
+		mga_writel(cursorbase, h+12, ~0);
+		h += 16;
+	}
+#ifdef __BIG_ENDIAN
+	mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
+#endif
+
+	CRITEND
+}
+
+static void matroxfb_DAC1064_cursor(struct display* p, int mode, int x, int y) {
+	unsigned long flags;
+	MINFO_FROM_DISP(p);
+
+	if (ACCESS_FBINFO(currcon_display) != p)
+		return;
+
+	if (mode == CM_ERASE) {
+		if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
+			matroxfb_DAC_lock_irqsave(flags);
+			ACCESS_FBINFO(cursor.state) = CM_ERASE;
+			del_timer(&ACCESS_FBINFO(cursor.timer));
+			outDAC1064(PMINFO M1064_XCURCTRL, M1064_XCURCTRL_DIS);
+			matroxfb_DAC_unlock_irqrestore(flags);
+		}
+		return;
+	}
+	if ((p->conp->vc_cursor_type & CUR_HWMASK) != ACCESS_FBINFO(cursor.type))
+		matroxfb_DAC1064_createcursor(PMINFO p);
+	x *= fontwidth(p);
+	y *= fontheight(p);
+	y -= p->var.yoffset;
+	if (p->var.vmode & FB_VMODE_DOUBLE)
+		y *= 2;
+	matroxfb_DAC_lock_irqsave(flags);
+	if ((x != ACCESS_FBINFO(cursor.x)) || (y != ACCESS_FBINFO(cursor.y)) || ACCESS_FBINFO(cursor.redraw)) {
+		ACCESS_FBINFO(cursor.redraw) = 0;
+		ACCESS_FBINFO(cursor.x) = x;
+		ACCESS_FBINFO(cursor.y) = y;
+		x += 64;
+		y += 64;
+		outDAC1064(PMINFO M1064_XCURCTRL, M1064_XCURCTRL_DIS);
+		mga_outb(M_RAMDAC_BASE+M1064_CURPOSXL, x);
+		mga_outb(M_RAMDAC_BASE+M1064_CURPOSXH, x >> 8);
+		mga_outb(M_RAMDAC_BASE+M1064_CURPOSYL, y);
+		mga_outb(M_RAMDAC_BASE+M1064_CURPOSYH, y >> 8);
+	}
+	ACCESS_FBINFO(cursor.state) = CM_DRAW;
+	if (ACCESS_FBINFO(devflags.blink))
+		mod_timer(&ACCESS_FBINFO(cursor.timer), jiffies + HZ/2);
+	outDAC1064(PMINFO M1064_XCURCTRL, M1064_XCURCTRL_XGA);
+	matroxfb_DAC_unlock_irqrestore(flags);
+}
+
+static int matroxfb_DAC1064_setfont(struct display* p, int width, int height) {
+	if (p && p->conp)
+		matroxfb_DAC1064_createcursor(PMXINFO(p) p);
+	return 0;
+}
+
+static int DAC1064_selhwcursor(WPMINFO struct display* p) {
+	ACCESS_FBINFO(dispsw.cursor) = matroxfb_DAC1064_cursor;
+	ACCESS_FBINFO(dispsw.set_font) = matroxfb_DAC1064_setfont;
+	return 0;
+}
+
+static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) {
+	unsigned int fvco;
+	unsigned int p;
+
+	DBG("DAC1064_calcclock")
+
+	fvco = PLL_calcclock(PMINFO freq, fmax, in, feed, &p);
+	p = (1 << p) - 1;
+	if (fvco <= 100000)
+		;
+	else if (fvco <= 140000)
+		p |= 0x08;
+	else if (fvco <= 180000)
+		p |= 0x10;
+	else
+		p |= 0x18;
+	*post = p;
+}
+
+/* they must be in POS order */
+static const unsigned char MGA1064_DAC_regs[] = {
+		M1064_XCURADDL, M1064_XCURADDH, M1064_XCURCTRL,
+		M1064_XCURCOL0RED, M1064_XCURCOL0GREEN, M1064_XCURCOL0BLUE,
+		M1064_XCURCOL1RED, M1064_XCURCOL1GREEN, M1064_XCURCOL1BLUE,
+		M1064_XCURCOL2RED, M1064_XCURCOL2GREEN, M1064_XCURCOL2BLUE,
+		DAC1064_XVREFCTRL, M1064_XMULCTRL, M1064_XPIXCLKCTRL, M1064_XGENCTRL,
+		M1064_XMISCCTRL,
+		M1064_XGENIOCTRL, M1064_XGENIODATA, M1064_XZOOMCTRL, M1064_XSENSETEST,
+		M1064_XCRCBITSEL,
+		M1064_XCOLKEYMASKL, M1064_XCOLKEYMASKH, M1064_XCOLKEYL, M1064_XCOLKEYH };
+
+static const unsigned char MGA1064_DAC[] = {
+		0x00, 0x00, M1064_XCURCTRL_DIS,
+		0x00, 0x00, 0x00, 	/* black */
+		0xFF, 0xFF, 0xFF,	/* white */
+		0xFF, 0x00, 0x00,	/* red */
+		0x00, 0,
+		M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL,
+		M1064_XGENCTRL_VS_0 | M1064_XGENCTRL_ALPHA_DIS | M1064_XGENCTRL_BLACK_0IRE | M1064_XGENCTRL_NO_SYNC_ON_GREEN,
+		M1064_XMISCCTRL_DAC_8BIT,
+		0x00, 0x00, M1064_XZOOMCTRL_1, M1064_XSENSETEST_BCOMP | M1064_XSENSETEST_GCOMP | M1064_XSENSETEST_RCOMP | M1064_XSENSETEST_PDOWN,
+		0x00,
+		0x00, 0x00, 0xFF, 0xFF};
+
+static void DAC1064_setpclk(CPMINFO struct matrox_hw_state* hw, unsigned long fout) {
+	unsigned int m, n, p;
+
+	DBG("DAC1064_setpclk")
+
+	DAC1064_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
+	hw->DACclk[0] = m;
+	hw->DACclk[1] = n;
+	hw->DACclk[2] = p;
+}
+
+static void DAC1064_setmclk(CPMINFO struct matrox_hw_state* hw, int oscinfo, unsigned long fmem){
+	u_int32_t mx;
+
+	DBG("DAC1064_setmclk")
+
+	if (ACCESS_FBINFO(devflags.noinit)) {
+		/* read MCLK and give up... */
+		hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);
+		hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);
+		hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);
+		return;
+	}
+	mx = hw->MXoptionReg | 0x00000004;
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
+	mx &= ~0x000000BB;
+	if (oscinfo & DAC1064_OPT_GDIV1)
+		mx |= 0x00000008;
+	if (oscinfo & DAC1064_OPT_MDIV1)
+		mx |= 0x00000010;
+	if (oscinfo & DAC1064_OPT_RESERVED)
+		mx |= 0x00000080;
+	if ((oscinfo & DAC1064_OPT_SCLK_MASK) == DAC1064_OPT_SCLK_PLL) {
+		/* select PCI clock until we have setup oscilator... */
+		int clk;
+		unsigned int m, n, p;
+
+		/* powerup system PLL, select PCI clock */
+		mx |= 0x00000020;
+		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
+		mx &= ~0x00000004;
+		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
+
+		/* !!! you must not access device if MCLK is not running !!!
+		   Doing so cause immediate PCI lockup :-( Maybe they should
+		   generate ABORT or I/O (parity...) error and Linux should
+		   recover from this... (kill driver/process). But world is not
+		   perfect... */
+		/* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not
+		   select PLL... because of PLL can be stopped at this time) */
+		DAC1064_calcclock(PMINFO fmem, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
+		outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3] = m);
+		outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4] = n);
+		outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5] = p);
+		for (clk = 65536; clk; --clk) {
+			if (inDAC1064(PMINFO DAC1064_XSYSPLLSTAT) & 0x40)
+				break;
+		}
+		if (!clk)
+			printk(KERN_ERR "matroxfb: aiee, SYSPLL not locked\n");
+		/* select PLL */
+		mx |= 0x00000005;
+	} else {
+		/* select specified system clock source */
+		mx |= oscinfo & DAC1064_OPT_SCLK_MASK;
+	}
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
+	mx &= ~0x00000004;
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
+	hw->MXoptionReg = mx;
+}
+
+void DAC1064_global_init(CPMINFO struct matrox_hw_state* hw) {
+	hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;
+	hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
+	hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
+#if defined(CONFIG_FB_MATROX_MAVEN) || defined(CONFIG_FB_MATROX_MAVEN_MODULE)
+	if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) {
+		hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT;
+		hw->DACreg[POS1064_XMISCCTRL] |= G400_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12;
+	} else if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY)
+		hw->DACreg[POS1064_XMISCCTRL] |= G400_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12;
+	else
+		hw->DACreg[POS1064_XMISCCTRL] |= G400_XMISCCTRL_MFC_DIS;
+	if ((ACCESS_FBINFO(output.ph) | ACCESS_FBINFO(output.sh)) & MATROXFB_OUTPUT_CONN_PRIMARY)
+		hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
+#else
+	hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_MFC_DIS | M1064_XMISCCTRL_DAC_EN;
+#endif
+}
+
+void DAC1064_global_restore(CPMINFO const struct matrox_hw_state* hw) {
+	outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
+	outDAC1064(PMINFO M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]);
+	if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
+		outDAC1064(PMINFO 0x20, 0x04);
+		outDAC1064(PMINFO 0x1F, 0x00);
+	}
+}
+
+static int DAC1064_init_1(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display *p) {
+	DBG("DAC1064_init_1")
+
+	memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs));
+	if (p->type == FB_TYPE_TEXT) {
+		hw->DACreg[POS1064_XMISCCTRL] = M1064_XMISCCTRL_DAC_6BIT;
+		hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP
+					     | M1064_XMULCTRL_GRAPHICS_PALETIZED;
+	} else {
+		switch (p->var.bits_per_pixel) {
+		/* case 4: not supported by MGA1064 DAC */
+		case 8:
+			hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
+			break;
+		case 16:
+			if (p->var.green.length == 5)
+				hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
+			else
+				hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
+			break;
+		case 24:
+			hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_24BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
+			break;
+		case 32:
+			hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_32BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
+			break;
+		default:
+			return 1;	/* unsupported depth */
+		}
+	}
+
+	DAC1064_global_init(PMINFO hw);
+	hw->DACreg[POS1064_XVREFCTRL] = ACCESS_FBINFO(features.DAC1064.xvrefctrl);
+	hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK;
+	hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN;
+	hw->DACreg[POS1064_XCURADDL] = ACCESS_FBINFO(features.DAC1064.cursorimage) >> 10;
+	hw->DACreg[POS1064_XCURADDH] = ACCESS_FBINFO(features.DAC1064.cursorimage) >> 18;
+	return 0;
+}
+
+static int DAC1064_init_2(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
+
+	DBG("DAC1064_init_2")
+
+	if (p->var.bits_per_pixel > 16) {	/* 256 entries */
+		int i;
+
+		for (i = 0; i < 256; i++) {
+			hw->DACpal[i * 3 + 0] = i;
+			hw->DACpal[i * 3 + 1] = i;
+			hw->DACpal[i * 3 + 2] = i;
+		}
+	} else if (p->var.bits_per_pixel > 8) {
+		if (p->var.green.length == 5) {	/* 0..31, 128..159 */
+			int i;
+
+			for (i = 0; i < 32; i++) {
+				/* with p15 == 0 */
+				hw->DACpal[i * 3 + 0] = i << 3;
+				hw->DACpal[i * 3 + 1] = i << 3;
+				hw->DACpal[i * 3 + 2] = i << 3;
+				/* with p15 == 1 */
+				hw->DACpal[(i + 128) * 3 + 0] = i << 3;
+				hw->DACpal[(i + 128) * 3 + 1] = i << 3;
+				hw->DACpal[(i + 128) * 3 + 2] = i << 3;
+			}
+		} else {
+			int i;
+
+			for (i = 0; i < 64; i++) {		/* 0..63 */
+				hw->DACpal[i * 3 + 0] = i << 3;
+				hw->DACpal[i * 3 + 1] = i << 2;
+				hw->DACpal[i * 3 + 2] = i << 3;
+			}
+		}
+	} else {
+		memset(hw->DACpal, 0, 768);
+	}
+	return 0;
+}
+
+static void DAC1064_restore_1(WPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw) {
+	CRITFLAGS
+
+	DBG("DAC1064_restore_1")
+
+	CRITBEGIN
+
+	outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]);
+	outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]);
+	outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]);
+	if (!oldhw || memcmp(hw->DACreg, oldhw->DACreg, sizeof(MGA1064_DAC_regs))) {
+		unsigned int i;
+
+		for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
+			if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL))
+				outDAC1064(PMINFO MGA1064_DAC_regs[i], hw->DACreg[i]);
+		}
+	}
+
+	DAC1064_global_restore(PMINFO hw);
+
+	CRITEND
+};
+
+static void DAC1064_restore_2(WPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw, struct display* p) {
+#ifdef DEBUG
+	unsigned int i;
+#endif
+
+	DBG("DAC1064_restore_2")
+
+	matrox_init_putc(PMINFO p, matroxfb_DAC1064_createcursor);
+#ifdef DEBUG
+	dprintk(KERN_DEBUG "DAC1064regs ");
+	for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
+		dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], hw->DACreg[i]);
+		if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
+	}
+	dprintk("\n" KERN_DEBUG "DAC1064clk ");
+	for (i = 0; i < 6; i++)
+		dprintk("C%02X=%02X ", i, hw->DACclk[i]);
+	dprintk("\n");
+#endif
+}
+
+static int m1064_compute(void* outdev, struct my_timming* m, struct matrox_hw_state* hw) {
+#define minfo ((struct matrox_fb_info*)outdev)
+	DAC1064_setpclk(PMINFO hw, m->pixclock);
+#undef minfo
+	return 0;
+}
+
+static int m1064_program(void* outdev, const struct matrox_hw_state* hw) {
+#define minfo ((struct matrox_fb_info*)outdev)
+	int i;
+	int tmout;
+	CRITFLAGS
+
+	CRITBEGIN
+
+	for (i = 0; i < 3; i++)
+		outDAC1064(PMINFO M1064_XPIXPLLCM + i, hw->DACclk[i]);
+	for (tmout = 500000; tmout; tmout--) {
+		if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
+			break;
+		udelay(10);
+	};
+
+	CRITEND
+
+	if (!tmout)
+		printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
+
+#undef minfo
+	return 0;
+}
+
+static int m1064_start(void* outdev) {
+	/* nothing */
+	return 0;
+}
+
+static void m1064_incuse(void* outdev) {
+	/* nothing yet; MODULE_INC_USE in future... */
+}
+
+static void m1064_decuse(void* outdev) {
+	/* nothing yet; MODULE_DEC_USE in future... */
+}
+
+static int m1064_setmode(void* outdev, u_int32_t mode) {
+	if (mode != MATROXFB_OUTPUT_MODE_MONITOR)
+		return -EINVAL;
+	return 0;
+}
+
+static struct matrox_altout m1064 = {
+	m1064_compute,
+	m1064_program,
+	m1064_start,
+	m1064_incuse,
+	m1064_decuse,
+	m1064_setmode
+};
+
+#endif /* NEED_DAC1064 */
+
+#ifdef CONFIG_FB_MATROX_MYSTIQUE
+static int MGA1064_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
+
+	DBG("MGA1064_init")
+
+	if (DAC1064_init_1(PMINFO hw, m, p)) return 1;
+	if (matroxfb_vgaHWinit(PMINFO hw, m, p)) return 1;
+
+	hw->MiscOutReg = 0xCB;
+	if (m->sync & FB_SYNC_HOR_HIGH_ACT)
+		hw->MiscOutReg &= ~0x40;
+	if (m->sync & FB_SYNC_VERT_HIGH_ACT)
+		hw->MiscOutReg &= ~0x80;
+	if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
+		hw->CRTCEXT[3] |= 0x40;
+
+	if (DAC1064_init_2(PMINFO hw, m, p)) return 1;
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_FB_MATROX_G100
+static int MGAG100_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
+
+	DBG("MGAG100_init")
+
+	if (DAC1064_init_1(PMINFO hw, m, p)) return 1;
+	hw->MXoptionReg &= ~0x2000;
+	if (matroxfb_vgaHWinit(PMINFO hw, m, p)) return 1;
+
+	hw->MiscOutReg = 0xEF;
+	if (m->sync & FB_SYNC_HOR_HIGH_ACT)
+		hw->MiscOutReg &= ~0x40;
+	if (m->sync & FB_SYNC_VERT_HIGH_ACT)
+		hw->MiscOutReg &= ~0x80;
+	if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
+		hw->CRTCEXT[3] |= 0x40;
+
+	if (DAC1064_init_2(PMINFO hw, m, p)) return 1;
+	return 0;
+}
+#endif	/* G100 */
+
+#ifdef CONFIG_FB_MATROX_MYSTIQUE
+static void MGA1064_ramdac_init(WPMINFO struct matrox_hw_state* hw){
+
+	DBG("MGA1064_ramdac_init");
+
+	/* ACCESS_FBINFO(features.DAC1064.vco_freq_min) = 120000; */
+	ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
+	ACCESS_FBINFO(features.pll.ref_freq)	 = 14318;
+	ACCESS_FBINFO(features.pll.feed_div_min) = 100;
+	ACCESS_FBINFO(features.pll.feed_div_max) = 127;
+	ACCESS_FBINFO(features.pll.in_div_min)	 = 1;
+	ACCESS_FBINFO(features.pll.in_div_max)	 = 31;
+	ACCESS_FBINFO(features.pll.post_shift_max) = 3;
+	ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_EXTERNAL;
+	/* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
+	DAC1064_setmclk(PMINFO hw, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
+}
+#endif
+
+#ifdef CONFIG_FB_MATROX_G100
+/* BIOS environ */
+static int x7AF4 = 0x10;	/* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
+				/* G100 wants 0x10, G200 SGRAM does not care... */
+#if 0
+static int def50 = 0;	/* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
+#endif
+
+static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p){
+	int reg;
+	int selClk;
+	int clk;
+
+	DBG("MGAG100_progPixClock")
+
+	outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS |
+		   M1064_XPIXCLKCTRL_PLL_UP);
+	switch (flags & 3) {
+		case 0:		reg = M1064_XPIXPLLAM; break;
+		case 1:		reg = M1064_XPIXPLLBM; break;
+		default:	reg = M1064_XPIXPLLCM; break;
+	}
+	outDAC1064(PMINFO reg++, m);
+	outDAC1064(PMINFO reg++, n);
+	outDAC1064(PMINFO reg, p);
+	selClk = mga_inb(M_MISC_REG_READ) & ~0xC;
+	/* there should be flags & 0x03 & case 0/1/else */
+	/* and we should first select source and after that we should wait for PLL */
+	/* and we are waiting for PLL with oscilator disabled... Is it right? */
+	switch (flags & 0x03) {
+		case 0x00:	break;
+		case 0x01:	selClk |= 4; break;
+		default:	selClk |= 0x0C; break;
+	}
+	mga_outb(M_MISC_REG, selClk);
+	for (clk = 500000; clk; clk--) {
+		if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
+			break;
+		udelay(10);
+	};
+	if (!clk)
+		printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A');
+	selClk = inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK;
+	switch (flags & 0x0C) {
+		case 0x00:	selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break;
+		case 0x04:	selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break;
+		default:	selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break;
+	}
+	outDAC1064(PMINFO M1064_XPIXCLKCTRL, selClk);
+	outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);
+}
+
+static void MGAG100_setPixClock(CPMINFO int flags, int freq){
+	unsigned int m, n, p;
+
+	DBG("MGAG100_setPixClock")
+
+	DAC1064_calcclock(PMINFO freq, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
+	MGAG100_progPixClock(PMINFO flags, m, n, p);
+}
+#endif
+
+#ifdef CONFIG_FB_MATROX_MYSTIQUE
+static int MGA1064_preinit(WPMINFO struct matrox_hw_state* hw){
+	static const int vxres_mystique[] = { 512,        640, 768,  800,  832,  960,
+					     1024, 1152, 1280,      1600, 1664, 1920,
+					     2048,    0};
+	DBG("MGA1064_preinit")
+
+	/* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
+	ACCESS_FBINFO(capable.text) = 1;
+	ACCESS_FBINFO(capable.vxres) = vxres_mystique;
+	ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
+	ACCESS_FBINFO(cursor.timer.function) = matroxfb_DAC1064_flashcursor;
+
+	ACCESS_FBINFO(primout) = &m1064;
+
+	if (ACCESS_FBINFO(devflags.noinit))
+		return 0;	/* do not modify settings */
+	hw->MXoptionReg &= 0xC0000100;
+	hw->MXoptionReg |= 0x00094E20;
+	if (ACCESS_FBINFO(devflags.novga))
+		hw->MXoptionReg &= ~0x00000100;
+	if (ACCESS_FBINFO(devflags.nobios))
+		hw->MXoptionReg &= ~0x40000000;
+	if (ACCESS_FBINFO(devflags.nopciretry))
+		hw->MXoptionReg |=  0x20000000;
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+	mga_setr(M_SEQ_INDEX, 0x01, 0x20);
+	mga_outl(M_CTLWTST, 0x00000000);
+	udelay(200);
+	mga_outl(M_MACCESS, 0x00008000);
+	udelay(100);
+	mga_outl(M_MACCESS, 0x0000C000);
+	return 0;
+}
+
+static void MGA1064_reset(WPMINFO struct matrox_hw_state* hw){
+
+	DBG("MGA1064_reset");
+
+	ACCESS_FBINFO(features.DAC1064.cursorimage) = ACCESS_FBINFO(video.len_usable) - 1024;
+	if (ACCESS_FBINFO(devflags.hwcursor))
+		ACCESS_FBINFO(video.len_usable) -= 1024;
+	matroxfb_fastfont_init(MINFO);
+	MGA1064_ramdac_init(PMINFO hw);
+}
+#endif
+
+#ifdef CONFIG_FB_MATROX_G100
+static int MGAG100_preinit(WPMINFO struct matrox_hw_state* hw){
+	static const int vxres_g100[] = {  512,        640, 768,  800,  832,  960,
+                                          1024, 1152, 1280,      1600, 1664, 1920,
+                                          2048, 0};
+        u_int32_t reg50;
+#if 0
+	u_int32_t q;
+#endif
+
+	DBG("MGAG100_preinit")
+
+	/* there are some instabilities if in_div > 19 && vco < 61000 */
+	ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
+	ACCESS_FBINFO(features.pll.ref_freq)	 = 27000;
+	ACCESS_FBINFO(features.pll.feed_div_min) = 7;
+	ACCESS_FBINFO(features.pll.feed_div_max) = 127;
+	ACCESS_FBINFO(features.pll.in_div_min)	 = 1;
+	ACCESS_FBINFO(features.pll.in_div_max)	 = 31;
+	ACCESS_FBINFO(features.pll.post_shift_max) = 3;
+	ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_G100_DEFAULT;
+	/* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
+	ACCESS_FBINFO(capable.text) = 1;
+	ACCESS_FBINFO(capable.vxres) = vxres_g100;
+	ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
+	ACCESS_FBINFO(cursor.timer.function) = matroxfb_DAC1064_flashcursor;
+	ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) != FB_ACCEL_MATROX_MGAG100;
+
+	ACCESS_FBINFO(primout) = &m1064;
+
+	if (ACCESS_FBINFO(devflags.noinit))
+		return 0;
+	hw->MXoptionReg &= 0xC0000100;
+	hw->MXoptionReg |= 0x00078020;
+	if (ACCESS_FBINFO(devflags.novga))
+		hw->MXoptionReg &= ~0x00000100;
+	if (ACCESS_FBINFO(devflags.nobios))
+		hw->MXoptionReg &= ~0x40000000;
+	if (ACCESS_FBINFO(devflags.nopciretry))
+		hw->MXoptionReg |=  0x20000000;
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+	pci_read_config_dword(ACCESS_FBINFO(pcidev), 0x50, &reg50);
+	reg50 &= ~0x3000;
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
+
+	DAC1064_setmclk(PMINFO hw, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333);
+
+	if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100) {
+		hw->MXoptionReg |= 0x1080;
+		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+		mga_outl(M_CTLWTST, 0x00000300);
+		/* mga_outl(M_CTLWTST, 0x03258A31); */
+		udelay(100);
+		mga_outb(0x1C05, 0x00);
+		mga_outb(0x1C05, 0x80);
+		udelay(100);
+		mga_outb(0x1C05, 0x40);
+		mga_outb(0x1C05, 0xC0);
+		udelay(100);
+		reg50 &= ~0xFF;
+		reg50 |=  0x07;
+		pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
+		/* it should help with G100 */
+		mga_outb(M_GRAPHICS_INDEX, 6);
+		mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4);
+		mga_setr(M_EXTVGA_INDEX, 0x03, 0x81);
+		mga_setr(M_EXTVGA_INDEX, 0x04, 0x00);
+		mga_writeb(ACCESS_FBINFO(video.vbase), 0x0000, 0xAA);
+		mga_writeb(ACCESS_FBINFO(video.vbase), 0x0800, 0x55);
+		mga_writeb(ACCESS_FBINFO(video.vbase), 0x4000, 0x55);
+#if 0
+		if (mga_readb(ACCESS_FBINFO(video.vbase), 0x0000) != 0xAA) {
+			hw->MXoptionReg &= ~0x1000;
+		}
+#endif
+	} else {
+		hw->MXoptionReg |= 0x00000C00;
+		if (ACCESS_FBINFO(devflags.sgram))
+			hw->MXoptionReg |= 0x4000;
+		mga_outl(M_CTLWTST, 0x042450A1);
+		mga_outb(0x1E47, 0x00);
+		mga_outb(0x1E46, 0x00);
+		udelay(10);
+		mga_outb(0x1C05, 0x00);
+		mga_outb(0x1C05, 0x80);
+		udelay(100);
+		mga_outw(0x1E44, 0x0108);
+	}
+	hw->MXoptionReg = (hw->MXoptionReg & ~0x1F8000) | 0x78000;
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+	return 0;
+}
+
+static void MGAG100_reset(WPMINFO struct matrox_hw_state* hw){
+	u_int8_t b;
+
+	DBG("MGAG100_reset")
+
+	ACCESS_FBINFO(features.DAC1064.cursorimage) = ACCESS_FBINFO(video.len_usable) - 1024;
+	if (ACCESS_FBINFO(devflags.hwcursor))
+		ACCESS_FBINFO(video.len_usable) -= 1024;
+	matroxfb_fastfont_init(MINFO);
+
+	{
+#ifdef G100_BROKEN_IBM_82351
+		u_int32_t d;
+
+		find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */
+		pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b);
+		if (b == ACCESS_FBINFO(pcidev)->bus->number) {
+			pci_write_config_byte(ibm, PCI_COMMAND+1, 0);	/* disable back-to-back & SERR */
+			pci_write_config_byte(ibm, 0x41, 0xF4);		/* ??? */
+			pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0);	/* ??? */
+			pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00);	/* ??? */
+		}
+#endif
+		if (!ACCESS_FBINFO(devflags.noinit)) {
+			if (x7AF4 & 8) {
+				hw->MXoptionReg |= 0x40;
+				pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+			}
+			mga_setr(M_EXTVGA_INDEX, 0x06, 0x50);
+		}
+	}
+	DAC1064_setmclk(PMINFO hw, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
+	if (ACCESS_FBINFO(devflags.noinit))
+		return;
+	MGAG100_setPixClock(PMINFO 4, 25175);
+	MGAG100_setPixClock(PMINFO 5, 28322);
+	if (x7AF4 & 0x10) {
+		b = inDAC1064(PMINFO M1064_XGENIODATA) & ~1;
+		outDAC1064(PMINFO M1064_XGENIODATA, b);
+		b = inDAC1064(PMINFO M1064_XGENIOCTRL) | 1;
+		outDAC1064(PMINFO M1064_XGENIOCTRL, b);
+	}
+}
+#endif
+
+#ifdef CONFIG_FB_MATROX_MYSTIQUE
+static void MGA1064_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) {
+	int i;
+	CRITFLAGS
+
+	DBG("MGA1064_restore")
+
+	CRITBEGIN
+
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+	mga_outb(M_IEN, 0x00);
+	mga_outb(M_CACHEFLUSH, 0x00);
+
+	CRITEND
+
+	DAC1064_restore_1(PMINFO hw, oldhw);
+	matroxfb_vgaHWrestore(PMINFO hw, oldhw);
+	for (i = 0; i < 6; i++)
+		mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
+	DAC1064_restore_2(PMINFO hw, oldhw, p);
+}
+#endif
+
+#ifdef CONFIG_FB_MATROX_G100
+static void MGAG100_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) {
+	int i;
+	CRITFLAGS
+
+	DBG("MGAG100_restore")
+
+	CRITBEGIN
+
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+	CRITEND
+
+	DAC1064_restore_1(PMINFO hw, oldhw);
+	matroxfb_vgaHWrestore(PMINFO hw, oldhw);
+#ifdef CONFIG_FB_MATROX_32MB
+	if (ACCESS_FBINFO(devflags.support32MB))
+		mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
+#endif
+	for (i = 0; i < 6; i++)
+		mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
+	DAC1064_restore_2(PMINFO hw, oldhw, p);
+}
+#endif
+
+#ifdef CONFIG_FB_MATROX_MYSTIQUE
+struct matrox_switch matrox_mystique = {
+	MGA1064_preinit, MGA1064_reset, MGA1064_init, MGA1064_restore, DAC1064_selhwcursor
+};
+EXPORT_SYMBOL(matrox_mystique);
+#endif
+
+#ifdef CONFIG_FB_MATROX_G100
+struct matrox_switch matrox_G100 = {
+	MGAG100_preinit, MGAG100_reset, MGAG100_init, MGAG100_restore, DAC1064_selhwcursor
+};
+EXPORT_SYMBOL(matrox_G100);
+#endif
+
+#ifdef NEED_DAC1064
+EXPORT_SYMBOL(DAC1064_global_init);
+EXPORT_SYMBOL(DAC1064_global_restore);
+#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_DAC1064.h linux/drivers/video/matrox/matroxfb_DAC1064.h
--- v2.3.47/linux/drivers/video/matrox/matroxfb_DAC1064.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_DAC1064.h	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,147 @@
+#ifndef __MATROXFB_DAC1064_H__
+#define __MATROXFB_DAC1064_H__
+
+/* make checkconfig does not walk through include tree */
+#include <linux/config.h>
+
+#include "matroxfb_base.h"
+
+#ifdef CONFIG_FB_MATROX_MYSTIQUE
+extern struct matrox_switch matrox_mystique;
+#endif
+#ifdef CONFIG_FB_MATROX_G100
+extern struct matrox_switch matrox_G100;
+#endif
+#ifdef NEED_DAC1064
+void DAC1064_global_init(CPMINFO struct matrox_hw_state*);
+void DAC1064_global_restore(CPMINFO const struct matrox_hw_state*);
+#endif
+
+#define M1064_INDEX	0x00
+#define M1064_PALWRADD	0x00
+#define M1064_PALDATA	0x01
+#define M1064_PIXRDMSK	0x02
+#define M1064_PALRDADD	0x03
+#define M1064_X_DATAREG	0x0A
+#define M1064_CURPOSXL	0x0C	/* can be accessed as DWORD */
+#define M1064_CURPOSXH	0x0D
+#define M1064_CURPOSYL	0x0E
+#define M1064_CURPOSYH	0x0F
+
+#define M1064_XCURADDL		0x04
+#define M1064_XCURADDH		0x05
+#define M1064_XCURCTRL		0x06
+#define     M1064_XCURCTRL_DIS		0x00	/* transparent, transparent, transparent, transparent */
+#define     M1064_XCURCTRL_3COLOR	0x01	/* transparent, 0, 1, 2 */
+#define     M1064_XCURCTRL_XGA		0x02	/* 0, 1, transparent, complement */
+#define     M1064_XCURCTRL_XWIN		0x03	/* transparent, transparent, 0, 1 */
+#define M1064_XCURCOL0RED	0x08
+#define M1064_XCURCOL0GREEN	0x09
+#define M1064_XCURCOL0BLUE	0x0A
+#define M1064_XCURCOL1RED	0x0C
+#define M1064_XCURCOL1GREEN	0x0D
+#define M1064_XCURCOL1BLUE	0x0E
+#define M1064_XCURCOL2RED	0x10
+#define M1064_XCURCOL2GREEN	0x11
+#define M1064_XCURCOL2BLUE	0x12
+#define DAC1064_XVREFCTRL	0x18
+#define      DAC1064_XVREFCTRL_INTERNAL		0x3F
+#define      DAC1064_XVREFCTRL_EXTERNAL		0x00
+#define      DAC1064_XVREFCTRL_G100_DEFAULT	0x03
+#define M1064_XMULCTRL		0x19
+#define      M1064_XMULCTRL_DEPTH_8BPP		0x00	/* 8 bpp paletized */
+#define      M1064_XMULCTRL_DEPTH_15BPP_1BPP	0x01	/* 15 bpp paletized + 1 bpp overlay */
+#define      M1064_XMULCTRL_DEPTH_16BPP		0x02	/* 16 bpp paletized */
+#define      M1064_XMULCTRL_DEPTH_24BPP		0x03	/* 24 bpp paletized */
+#define      M1064_XMULCTRL_DEPTH_24BPP_8BPP	0x04	/* 24 bpp direct + 8 bpp overlay paletized */
+#define      M1064_XMULCTRL_2G8V16		0x05	/* 15 bpp video direct, half xres, 8bpp paletized */
+#define      M1064_XMULCTRL_G16V16		0x06	/* 15 bpp video, 15bpp graphics, one of them paletized */
+#define      M1064_XMULCTRL_DEPTH_32BPP		0x07	/* 24 bpp paletized + 8 bpp unused */
+#define      M1064_XMULCTRL_GRAPHICS_PALETIZED	0x00
+#define      M1064_XMULCTRL_VIDEO_PALETIZED	0x08
+#define M1064_XPIXCLKCTRL	0x1A
+#define      M1064_XPIXCLKCTRL_SRC_PCI		0x00
+#define      M1064_XPIXCLKCTRL_SRC_PLL		0x01
+#define      M1064_XPIXCLKCTRL_SRC_EXT		0x02
+#define      M1064_XPIXCLKCTRL_SRC_MASK		0x03
+#define      M1064_XPIXCLKCTRL_EN		0x00
+#define      M1064_XPIXCLKCTRL_DIS		0x04
+#define      M1064_XPIXCLKCTRL_PLL_DOWN		0x00
+#define      M1064_XPIXCLKCTRL_PLL_UP		0x08
+#define M1064_XGENCTRL		0x1D
+#define      M1064_XGENCTRL_VS_0		0x00
+#define      M1064_XGENCTRL_VS_1		0x01
+#define      M1064_XGENCTRL_ALPHA_DIS		0x00
+#define      M1064_XGENCTRL_ALPHA_EN		0x02
+#define      M1064_XGENCTRL_BLACK_0IRE		0x00
+#define      M1064_XGENCTRL_BLACK_75IRE		0x10
+#define      M1064_XGENCTRL_SYNC_ON_GREEN	0x00
+#define      M1064_XGENCTRL_NO_SYNC_ON_GREEN	0x20
+#define      M1064_XGENCTRL_SYNC_ON_GREEN_MASK	0x20
+#define M1064_XMISCCTRL		0x1E
+#define      M1064_XMISCCTRL_DAC_DIS		0x00
+#define      M1064_XMISCCTRL_DAC_EN		0x01
+#define      M1064_XMISCCTRL_MFC_VGA		0x00
+#define      M1064_XMISCCTRL_MFC_MAFC		0x02
+#define      M1064_XMISCCTRL_MFC_DIS		0x06
+#define      G400_XMISCCTRL_MFC_MAFC		0x02
+#define      G400_XMISCCTRL_MFC_PANELLINK	0x04
+#define      G400_XMISCCTRL_MFC_DIS		0x06
+#define      G400_XMISCCTRL_MFC_MASK		0x06
+#define      M1064_XMISCCTRL_DAC_6BIT		0x00
+#define      M1064_XMISCCTRL_DAC_8BIT		0x08
+#define      M1064_XMISCCTRL_DAC_WIDTHMASK	0x08
+#define      M1064_XMISCCTRL_LUT_DIS		0x00
+#define      M1064_XMISCCTRL_LUT_EN		0x10
+#define      G400_XMISCCTRL_VDO_MAFC12		0x00
+#define      G400_XMISCCTRL_VDO_BYPASS656	0x40
+#define      G400_XMISCCTRL_VDO_C2_MAFC12	0x80
+#define      G400_XMISCCTRL_VDO_C2_BYPASS656	0xC0
+#define      G400_XMISCCTRL_VDO_MASK		0xE0
+#define M1064_XGENIOCTRL	0x2A
+#define M1064_XGENIODATA	0x2B
+#define DAC1064_XSYSPLLM	0x2C
+#define DAC1064_XSYSPLLN	0x2D
+#define DAC1064_XSYSPLLP	0x2E
+#define DAC1064_XSYSPLLSTAT	0x2F
+#define M1064_XZOOMCTRL		0x38
+#define      M1064_XZOOMCTRL_1			0x00
+#define      M1064_XZOOMCTRL_2			0x01
+#define      M1064_XZOOMCTRL_4			0x03
+#define M1064_XSENSETEST	0x3A
+#define      M1064_XSENSETEST_BCOMP		0x01
+#define      M1064_XSENSETEST_GCOMP		0x02
+#define      M1064_XSENSETEST_RCOMP		0x04
+#define      M1064_XSENSETEST_PDOWN		0x00
+#define      M1064_XSENSETEST_PUP		0x80
+#define M1064_XCRCREML		0x3C
+#define M1064_XCRCREMH		0x3D
+#define M1064_XCRCBITSEL	0x3E
+#define M1064_XCOLKEYMASKL	0x40
+#define M1064_XCOLKEYMASKH	0x41
+#define M1064_XCOLKEYL		0x42
+#define M1064_XCOLKEYH		0x43
+#define M1064_XPIXPLLAM		0x44
+#define M1064_XPIXPLLAN		0x45
+#define M1064_XPIXPLLAP		0x46
+#define M1064_XPIXPLLBM		0x48
+#define M1064_XPIXPLLBN		0x49
+#define M1064_XPIXPLLBP		0x4A
+#define M1064_XPIXPLLCM		0x4C
+#define M1064_XPIXPLLCN		0x4D
+#define M1064_XPIXPLLCP		0x4E
+#define M1064_XPIXPLLSTAT	0x4F
+
+enum POS1064 {
+	POS1064_XCURADDL=0, POS1064_XCURADDH, POS1064_XCURCTRL,
+	POS1064_XCURCOL0RED, POS1064_XCURCOL0GREEN, POS1064_XCURCOL0BLUE,
+	POS1064_XCURCOL1RED, POS1064_XCURCOL1GREEN, POS1064_XCURCOL1BLUE,
+	POS1064_XCURCOL2RED, POS1064_XCURCOL2GREEN, POS1064_XCURCOL2BLUE,
+	POS1064_XVREFCTRL, POS1064_XMULCTRL, POS1064_XPIXCLKCTRL, POS1064_XGENCTRL,
+	POS1064_XMISCCTRL,
+	POS1064_XGENIOCTRL, POS1064_XGENIODATA, POS1064_XZOOMCTRL, POS1064_XSENSETEST,
+	POS1064_XCRCBITSEL,
+	POS1064_XCOLKEYMASKL, POS1064_XCOLKEYMASKH, POS1064_XCOLKEYL, POS1064_XCOLKEYH };
+
+
+#endif	/* __MATROXFB_DAC1064_H__ */
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_Ti3026.c linux/drivers/video/matrox/matroxfb_Ti3026.c
--- v2.3.47/linux/drivers/video/matrox/matroxfb_Ti3026.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_Ti3026.c	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,862 @@
+/*
+ *
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
+ *
+ * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>
+ *
+ * Version: 1.21 2000/01/09
+ *
+ * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
+ *
+ * Contributors: "menion?" <menion@mindless.com>
+ *                     Betatesting, fixes, ideas
+ *
+ *               "Kurt Garloff" <garloff@kg1.ping.de>
+ *                     Betatesting, fixes, ideas, videomodes, videomodes timmings
+ *
+ *               "Tom Rini" <trini@kernel.crashing.org>
+ *                     MTRR stuff, PPC cleanups, betatesting, fixes, ideas
+ *
+ *               "Bibek Sahu" <scorpio@dodds.net>
+ *                     Access device through readb|w|l and write b|w|l
+ *                     Extensive debugging stuff
+ *
+ *               "Daniel Haun" <haund@usa.net>
+ *                     Testing, hardware cursor fixes
+ *
+ *               "Scott Wood" <sawst46+@pitt.edu>
+ *                     Fixes
+ *
+ *               "Gerd Knorr" <kraxel@goldbach.isdn.cs.tu-berlin.de>
+ *                     Betatesting
+ *
+ *               "Kelly French" <targon@hazmat.com>
+ *               "Fernando Herrera" <fherrera@eurielec.etsit.upm.es>
+ *                     Betatesting, bug reporting
+ *
+ *               "Pablo Bianucci" <pbian@pccp.com.ar>
+ *                     Fixes, ideas, betatesting
+ *
+ *               "Inaky Perez Gonzalez" <inaky@peloncho.fis.ucm.es>
+ *                     Fixes, enhandcements, ideas, betatesting
+ *
+ *               "Ryuichi Oikawa" <roikawa@rr.iiij4u.or.jp>
+ *                     PPC betatesting, PPC support, backward compatibility
+ *
+ *               "Paul Womar" <Paul@pwomar.demon.co.uk>
+ *               "Owen Waller" <O.Waller@ee.qub.ac.uk>
+ *                     PPC betatesting
+ *
+ *               "Thomas Pornin" <pornin@bolet.ens.fr>
+ *                     Alpha betatesting
+ *
+ *               "Pieter van Leuven" <pvl@iae.nl>
+ *               "Ulf Jaenicke-Roessler" <ujr@physik.phy.tu-dresden.de>
+ *                     G100 testing
+ *
+ *               "H. Peter Arvin" <hpa@transmeta.com>
+ *                     Ideas
+ *
+ *               "Cort Dougan" <cort@cs.nmt.edu>
+ *                     CHRP fixes and PReP cleanup
+ *
+ *               "Mark Vojkovich" <mvojkovi@ucsd.edu>
+ *                     G400 support
+ *
+ * (following author is not in any relation with this code, but his code
+ *  is included in this driver)
+ *
+ * Based on framebuffer driver for VBE 2.0 compliant graphic boards
+ *     (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
+ *
+ * (following author is not in any relation with this code, but his ideas
+ *  were used when writting this driver)
+ *
+ *		 FreeVBE/AF (Matrox), "Shawn Hargreaves" <shawn@talula.demon.co.uk>
+ *
+ */
+
+/* make checkconfig does not verify included files... */
+#include <linux/config.h>
+
+#include "matroxfb_Ti3026.h"
+#include "matroxfb_misc.h"
+#include "matroxfb_accel.h"
+
+#ifdef CONFIG_FB_MATROX_MILLENIUM
+#define outTi3026 matroxfb_DAC_out
+#define inTi3026 matroxfb_DAC_in
+
+#define TVP3026_INDEX		0x00
+#define TVP3026_PALWRADD	0x00
+#define TVP3026_PALDATA		0x01
+#define TVP3026_PIXRDMSK	0x02
+#define TVP3026_PALRDADD	0x03
+#define TVP3026_CURCOLWRADD	0x04
+#define     TVP3026_CLOVERSCAN		0x00
+#define     TVP3026_CLCOLOR0		0x01
+#define     TVP3026_CLCOLOR1		0x02
+#define     TVP3026_CLCOLOR2		0x03
+#define TVP3026_CURCOLDATA	0x05
+#define TVP3026_CURCOLRDADD	0x07
+#define TVP3026_CURCTRL		0x09
+#define TVP3026_X_DATAREG	0x0A
+#define TVP3026_CURRAMDATA	0x0B
+#define TVP3026_CURPOSXL	0x0C
+#define TVP3026_CURPOSXH	0x0D
+#define TVP3026_CURPOSYL	0x0E
+#define TVP3026_CURPOSYH	0x0F
+
+#define TVP3026_XSILICONREV	0x01
+#define TVP3026_XCURCTRL	0x06
+#define     TVP3026_XCURCTRL_DIS	0x00	/* transparent, transparent, transparent, transparent */
+#define     TVP3026_XCURCTRL_3COLOR	0x01	/* transparent, 0, 1, 2 */
+#define     TVP3026_XCURCTRL_XGA	0x02	/* 0, 1, transparent, complement */
+#define     TVP3026_XCURCTRL_XWIN	0x03	/* transparent, transparent, 0, 1 */
+#define     TVP3026_XCURCTRL_BLANK2048	0x00
+#define     TVP3026_XCURCTRL_BLANK4096	0x10
+#define     TVP3026_XCURCTRL_INTERLACED	0x20
+#define     TVP3026_XCURCTRL_ODD	0x00 /* ext.signal ODD/\EVEN */
+#define     TVP3026_XCURCTRL_EVEN	0x40 /* ext.signal EVEN/\ODD */
+#define     TVP3026_XCURCTRL_INDIRECT	0x00
+#define     TVP3026_XCURCTRL_DIRECT	0x80
+#define TVP3026_XLATCHCTRL	0x0F
+#define     TVP3026_XLATCHCTRL_1_1	0x06
+#define     TVP3026_XLATCHCTRL_2_1	0x07
+#define     TVP3026_XLATCHCTRL_4_1	0x06
+#define     TVP3026_XLATCHCTRL_8_1	0x06
+#define     TVP3026_XLATCHCTRL_16_1	0x06
+#define     TVP3026A_XLATCHCTRL_4_3	0x06	/* ??? do not understand... but it works... !!! */
+#define     TVP3026A_XLATCHCTRL_8_3	0x07
+#define     TVP3026B_XLATCHCTRL_4_3	0x08
+#define     TVP3026B_XLATCHCTRL_8_3	0x06	/* ??? do not understand... but it works... !!! */
+#define TVP3026_XTRUECOLORCTRL	0x18
+#define     TVP3026_XTRUECOLORCTRL_VRAM_SHIFT_ACCEL	0x00
+#define     TVP3026_XTRUECOLORCTRL_VRAM_SHIFT_TVP	0x20
+#define     TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR		0x80
+#define     TVP3026_XTRUECOLORCTRL_TRUECOLOR		0x40 /* paletized */
+#define     TVP3026_XTRUECOLORCTRL_DIRECTCOLOR		0x00
+#define     TVP3026_XTRUECOLORCTRL_24_ALTERNATE		0x08 /* 5:4/5:2 instead of 4:3/8:3 */
+#define     TVP3026_XTRUECOLORCTRL_RGB_888		0x16 /* 4:3/8:3 (or 5:4/5:2) */
+#define	    TVP3026_XTRUECOLORCTRL_BGR_888		0x17
+#define     TVP3026_XTRUECOLORCTRL_ORGB_8888		0x06
+#define     TVP3026_XTRUECOLORCTRL_BGRO_8888		0x07
+#define     TVP3026_XTRUECOLORCTRL_RGB_565		0x05
+#define     TVP3026_XTRUECOLORCTRL_ORGB_1555		0x04
+#define     TVP3026_XTRUECOLORCTRL_RGB_664		0x03
+#define     TVP3026_XTRUECOLORCTRL_RGBO_4444		0x01
+#define TVP3026_XMUXCTRL	0x19
+#define     TVP3026_XMUXCTRL_MEMORY_8BIT			0x01 /* - */
+#define     TVP3026_XMUXCTRL_MEMORY_16BIT			0x02 /* - */
+#define     TVP3026_XMUXCTRL_MEMORY_32BIT			0x03 /* 2MB RAM, 512K * 4 */
+#define     TVP3026_XMUXCTRL_MEMORY_64BIT			0x04 /* >2MB RAM, 512K * 8 & more */
+#define     TVP3026_XMUXCTRL_PIXEL_4BIT				0x40 /* L0,H0,L1,H1... */
+#define     TVP3026_XMUXCTRL_PIXEL_4BIT_SWAPPED			0x60 /* H0,L0,H1,L1... */
+#define     TVP3026_XMUXCTRL_PIXEL_8BIT				0x48
+#define     TVP3026_XMUXCTRL_PIXEL_16BIT			0x50
+#define     TVP3026_XMUXCTRL_PIXEL_32BIT			0x58
+#define     TVP3026_XMUXCTRL_VGA				0x98 /* VGA MEMORY, 8BIT PIXEL */
+#define TVP3026_XCLKCTRL	0x1A
+#define     TVP3026_XCLKCTRL_DIV1	0x00
+#define     TVP3026_XCLKCTRL_DIV2	0x10
+#define     TVP3026_XCLKCTRL_DIV4	0x20
+#define     TVP3026_XCLKCTRL_DIV8	0x30
+#define     TVP3026_XCLKCTRL_DIV16	0x40
+#define     TVP3026_XCLKCTRL_DIV32	0x50
+#define     TVP3026_XCLKCTRL_DIV64	0x60
+#define     TVP3026_XCLKCTRL_CLKSTOPPED	0x70
+#define     TVP3026_XCLKCTRL_SRC_CLK0	0x00
+#define     TVP3026_XCLKCTRL_SRC_CLK1   0x01
+#define     TVP3026_XCLKCTRL_SRC_CLK2	0x02	/* CLK2 is TTL source*/
+#define     TVP3026_XCLKCTRL_SRC_NCLK2	0x03	/* not CLK2 is TTL source */
+#define     TVP3026_XCLKCTRL_SRC_ECLK2	0x04	/* CLK2 and not CLK2 is ECL source */
+#define     TVP3026_XCLKCTRL_SRC_PLL	0x05
+#define     TVP3026_XCLKCTRL_SRC_DIS	0x06	/* disable & poweroff internal clock */
+#define     TVP3026_XCLKCTRL_SRC_CLK0VGA 0x07
+#define TVP3026_XPALETTEPAGE	0x1C
+#define TVP3026_XGENCTRL	0x1D
+#define     TVP3026_XGENCTRL_HSYNC_POS	0x00
+#define     TVP3026_XGENCTRL_HSYNC_NEG	0x01
+#define     TVP3026_XGENCTRL_VSYNC_POS	0x00
+#define     TVP3026_XGENCTRL_VSYNC_NEG	0x02
+#define     TVP3026_XGENCTRL_LITTLE_ENDIAN 0x00
+#define     TVP3026_XGENCTRL_BIG_ENDIAN    0x08
+#define     TVP3026_XGENCTRL_BLACK_0IRE		0x00
+#define     TVP3026_XGENCTRL_BLACK_75IRE	0x10
+#define     TVP3026_XGENCTRL_NO_SYNC_ON_GREEN	0x00
+#define     TVP3026_XGENCTRL_SYNC_ON_GREEN	0x20
+#define     TVP3026_XGENCTRL_OVERSCAN_DIS	0x00
+#define     TVP3026_XGENCTRL_OVERSCAN_EN	0x40
+#define TVP3026_XMISCCTRL	0x1E
+#define     TVP3026_XMISCCTRL_DAC_PUP	0x00
+#define     TVP3026_XMISCCTRL_DAC_PDOWN	0x01
+#define     TVP3026_XMISCCTRL_DAC_EXT	0x00 /* or 8, bit 3 is ignored */
+#define     TVP3026_XMISCCTRL_DAC_6BIT	0x04
+#define     TVP3026_XMISCCTRL_DAC_8BIT	0x0C
+#define     TVP3026_XMISCCTRL_PSEL_DIS	0x00
+#define     TVP3026_XMISCCTRL_PSEL_EN	0x10
+#define     TVP3026_XMISCCTRL_PSEL_LOW	0x00 /* PSEL high selects directcolor */
+#define     TVP3026_XMISCCTRL_PSEL_HIGH 0x20 /* PSEL high selects truecolor or pseudocolor */
+#define TVP3026_XGENIOCTRL	0x2A
+#define TVP3026_XGENIODATA	0x2B
+#define TVP3026_XPLLADDR	0x2C
+#define     TVP3026_XPLLADDR_X(LOOP,MCLK,PIX) (((LOOP)<<4) | ((MCLK)<<2) | (PIX))
+#define     TVP3026_XPLLDATA_N		0x00
+#define     TVP3026_XPLLDATA_M		0x01
+#define     TVP3026_XPLLDATA_P		0x02
+#define     TVP3026_XPLLDATA_STAT	0x03
+#define TVP3026_XPIXPLLDATA	0x2D
+#define TVP3026_XMEMPLLDATA	0x2E
+#define TVP3026_XLOOPPLLDATA	0x2F
+#define TVP3026_XCOLKEYOVRMIN	0x30
+#define TVP3026_XCOLKEYOVRMAX	0x31
+#define TVP3026_XCOLKEYREDMIN	0x32
+#define TVP3026_XCOLKEYREDMAX	0x33
+#define TVP3026_XCOLKEYGREENMIN	0x34
+#define TVP3026_XCOLKEYGREENMAX	0x35
+#define TVP3026_XCOLKEYBLUEMIN	0x36
+#define TVP3026_XCOLKEYBLUEMAX	0x37
+#define TVP3026_XCOLKEYCTRL	0x38
+#define     TVP3026_XCOLKEYCTRL_OVR_EN	0x01
+#define     TVP3026_XCOLKEYCTRL_RED_EN	0x02
+#define     TVP3026_XCOLKEYCTRL_GREEN_EN 0x04
+#define     TVP3026_XCOLKEYCTRL_BLUE_EN	0x08
+#define     TVP3026_XCOLKEYCTRL_NEGATE	0x10
+#define     TVP3026_XCOLKEYCTRL_ZOOM1	0x00
+#define     TVP3026_XCOLKEYCTRL_ZOOM2	0x20
+#define     TVP3026_XCOLKEYCTRL_ZOOM4	0x40
+#define     TVP3026_XCOLKEYCTRL_ZOOM8	0x60
+#define     TVP3026_XCOLKEYCTRL_ZOOM16	0x80
+#define     TVP3026_XCOLKEYCTRL_ZOOM32	0xA0
+#define TVP3026_XMEMPLLCTRL	0x39
+#define     TVP3026_XMEMPLLCTRL_DIV(X)	(((X)-1)>>1)	/* 2,4,6,8,10,12,14,16, division applied to LOOP PLL after divide by 2^P */
+#define     TVP3026_XMEMPLLCTRL_STROBEMKC4	0x08
+#define     TVP3026_XMEMPLLCTRL_MCLK_DOTCLOCK	0x00	/* MKC4 */
+#define     TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL	0x10	/* MKC4 */
+#define     TVP3026_XMEMPLLCTRL_RCLK_PIXPLL	0x00
+#define     TVP3026_XMEMPLLCTRL_RCLK_LOOPPLL	0x20
+#define     TVP3026_XMEMPLLCTRL_RCLK_DOTDIVN	0x40	/* dot clock divided by loop pclk N prescaler */
+#define TVP3026_XSENSETEST	0x3A
+#define TVP3026_XTESTMODEDATA	0x3B
+#define TVP3026_XCRCREML	0x3C
+#define TVP3026_XCRCREMH	0x3D
+#define TVP3026_XCRCBITSEL	0x3E
+#define TVP3026_XID		0x3F
+
+static const unsigned char DACseq[] =
+{ TVP3026_XLATCHCTRL, TVP3026_XTRUECOLORCTRL,
+  TVP3026_XMUXCTRL, TVP3026_XCLKCTRL,
+  TVP3026_XPALETTEPAGE,
+  TVP3026_XGENCTRL,
+  TVP3026_XMISCCTRL,
+  TVP3026_XGENIOCTRL,
+  TVP3026_XGENIODATA,
+  TVP3026_XCOLKEYOVRMIN, TVP3026_XCOLKEYOVRMAX, TVP3026_XCOLKEYREDMIN, TVP3026_XCOLKEYREDMAX,
+  TVP3026_XCOLKEYGREENMIN, TVP3026_XCOLKEYGREENMAX, TVP3026_XCOLKEYBLUEMIN, TVP3026_XCOLKEYBLUEMAX,
+  TVP3026_XCOLKEYCTRL,
+  TVP3026_XMEMPLLCTRL, TVP3026_XSENSETEST, TVP3026_XCURCTRL };
+
+#define POS3026_XLATCHCTRL	0
+#define POS3026_XTRUECOLORCTRL	1
+#define POS3026_XMUXCTRL	2
+#define POS3026_XCLKCTRL	3
+#define POS3026_XGENCTRL	5
+#define POS3026_XMISCCTRL	6
+#define POS3026_XMEMPLLCTRL	18
+#define POS3026_XCURCTRL	20
+
+static const unsigned char MGADACbpp32[] =
+{ TVP3026_XLATCHCTRL_2_1, TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_8888,
+  0x00, TVP3026_XCLKCTRL_DIV1 | TVP3026_XCLKCTRL_SRC_PLL,
+  0x00,
+  TVP3026_XGENCTRL_HSYNC_POS | TVP3026_XGENCTRL_VSYNC_POS | TVP3026_XGENCTRL_LITTLE_ENDIAN | TVP3026_XGENCTRL_BLACK_0IRE | TVP3026_XGENCTRL_NO_SYNC_ON_GREEN | TVP3026_XGENCTRL_OVERSCAN_DIS,
+  TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_HIGH,
+  0x00,
+  0x1E,
+  0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF,
+  TVP3026_XCOLKEYCTRL_ZOOM1,
+  0x00, 0x00, TVP3026_XCURCTRL_DIS };
+
+static void matroxfb_ti3026_flashcursor(unsigned long ptr) {
+#define minfo ((struct matrox_fb_info*)ptr)
+	matroxfb_DAC_lock();
+	outTi3026(PMINFO TVP3026_XCURCTRL, inTi3026(PMINFO TVP3026_XCURCTRL) ^ TVP3026_XCURCTRL_DIS ^ TVP3026_XCURCTRL_XGA);
+	ACCESS_FBINFO(cursor.timer.expires) = jiffies + HZ/2;
+	add_timer(&ACCESS_FBINFO(cursor.timer));
+	matroxfb_DAC_unlock();
+#undef minfo
+}
+
+static void matroxfb_ti3026_createcursor(WPMINFO struct display* p) {
+	unsigned long flags;
+	u_int32_t xline;
+	unsigned int i;
+	unsigned int to;
+
+	if (ACCESS_FBINFO(currcon_display) != p)
+		return;
+
+	DBG("matroxfb_ti3026_createcursor");
+
+	matroxfb_createcursorshape(PMINFO p, p->var.vmode);
+
+	xline = (~0) << (32 - ACCESS_FBINFO(cursor.w));
+	matroxfb_DAC_lock_irqsave(flags);
+	mga_outb(M_RAMDAC_BASE+TVP3026_INDEX, 0);
+	to = ACCESS_FBINFO(cursor.u);
+	for (i = 0; i < to; i++) {
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+	}
+	to = ACCESS_FBINFO(cursor.d);
+	for (; i < to; i++) {
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, xline >> 24);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, xline >> 16);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, xline >> 8);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, xline);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+	}
+	for (; i < 64; i++) {
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
+	}
+	for (i = 0; i < 512; i++)
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0xFF);
+	matroxfb_DAC_unlock_irqrestore(flags);
+}
+
+static void matroxfb_ti3026_cursor(struct display* p, int mode, int x, int y) {
+	unsigned long flags;
+	MINFO_FROM_DISP(p);
+
+	DBG("matroxfb_ti3026_cursor")
+
+	if (ACCESS_FBINFO(currcon_display) != p)
+		return;
+
+	if (mode == CM_ERASE) {
+		if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
+			matroxfb_DAC_lock_irqsave(flags);
+			ACCESS_FBINFO(cursor.state) = CM_ERASE;
+			del_timer(&ACCESS_FBINFO(cursor.timer));
+			outTi3026(PMINFO TVP3026_XCURCTRL, ACCESS_FBINFO(currenthw->DACreg[POS3026_XCURCTRL]));
+			matroxfb_DAC_unlock_irqrestore(flags);
+		}
+		return;
+	}
+	if ((p->conp->vc_cursor_type & CUR_HWMASK) != ACCESS_FBINFO(cursor.type))
+		matroxfb_ti3026_createcursor(PMINFO p);
+	x *= fontwidth(p);
+	y *= fontheight(p);
+	y -= p->var.yoffset;
+	if (p->var.vmode & FB_VMODE_DOUBLE)
+		y *= 2;
+	matroxfb_DAC_lock_irqsave(flags);
+	if ((x != ACCESS_FBINFO(cursor.x)) || (y != ACCESS_FBINFO(cursor.y)) || ACCESS_FBINFO(cursor.redraw)) {
+		ACCESS_FBINFO(cursor.redraw) = 0;
+		ACCESS_FBINFO(cursor.x) = x;
+		ACCESS_FBINFO(cursor.y) = y;
+		x += 64;
+		y += 64;
+		outTi3026(PMINFO TVP3026_XCURCTRL, ACCESS_FBINFO(currenthw->DACreg[POS3026_XCURCTRL]));
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURPOSXL, x);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURPOSXH, x >> 8);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURPOSYL, y);
+		mga_outb(M_RAMDAC_BASE+TVP3026_CURPOSYH, y >> 8);
+	}
+	ACCESS_FBINFO(cursor.state) = CM_DRAW;
+	if (ACCESS_FBINFO(devflags.blink))
+		mod_timer(&ACCESS_FBINFO(cursor.timer), jiffies + HZ/2);
+	outTi3026(PMINFO TVP3026_XCURCTRL, ACCESS_FBINFO(currenthw->DACreg[POS3026_XCURCTRL]) | TVP3026_XCURCTRL_XGA);
+	matroxfb_DAC_unlock_irqrestore(flags);
+}
+
+static int matroxfb_ti3026_setfont(struct display* p, int width, int height) {
+
+	DBG("matrox_ti3026_setfont");
+
+	if (p && p->conp)
+		matroxfb_ti3026_createcursor(PMXINFO(p) p);
+	return 0;
+}
+
+static int matroxfb_ti3026_selhwcursor(WPMINFO struct display* p) {
+	ACCESS_FBINFO(dispsw.cursor) = matroxfb_ti3026_cursor;
+	ACCESS_FBINFO(dispsw.set_font) = matroxfb_ti3026_setfont;
+	return 0;
+}
+
+static int Ti3026_calcclock(CPMINFO unsigned int freq, unsigned int fmax, int* in, int* feed, int* post) {
+	unsigned int fvco;
+	unsigned int lin, lfeed, lpost;
+
+	DBG("Ti3026_calcclock")
+
+	fvco = PLL_calcclock(PMINFO freq, fmax, &lin, &lfeed, &lpost);
+	fvco >>= (*post = lpost);
+	*in = 64 - lin;
+	*feed = 64 - lfeed;
+	return fvco;
+}
+
+static int Ti3026_setpclk(CPMINFO struct matrox_hw_state* hw, int clk, struct display* p) {
+	unsigned int f_pll;
+	unsigned int pixfeed, pixin, pixpost;
+
+	DBG("Ti3026_setpclk")
+
+	f_pll = Ti3026_calcclock(PMINFO clk, ACCESS_FBINFO(max_pixel_clock), &pixin, &pixfeed, &pixpost);
+
+	hw->DACclk[0] = pixin | 0xC0;
+	hw->DACclk[1] = pixfeed;
+	hw->DACclk[2] = pixpost | 0xB0;
+
+	if (p->type == FB_TYPE_TEXT) {
+		hw->DACreg[POS3026_XMEMPLLCTRL] = TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_RCLK_PIXPLL;
+		hw->DACclk[3] = 0xFD;
+		hw->DACclk[4] = 0x3D;
+		hw->DACclk[5] = 0x70;
+	} else {
+		unsigned int loopfeed, loopin, looppost, loopdiv, z;
+		unsigned int Bpp;
+
+		Bpp = ACCESS_FBINFO(curr.final_bppShift);
+
+		if (p->var.bits_per_pixel == 24) {
+			loopfeed = 3;		/* set lm to any possible value */
+			loopin = 3 * 32 / Bpp;
+		} else {
+			loopfeed = 4;
+			loopin = 4 * 32 / Bpp;
+		}
+		z = (110000 * loopin) / (f_pll * loopfeed);
+		loopdiv = 0; /* div 2 */
+		if (z < 2)
+			looppost = 0;
+		else if (z < 4)
+			looppost = 1;
+		else if (z < 8)
+			looppost = 2;
+		else {
+			looppost = 3;
+			loopdiv = z/16;
+		}
+		if (p->var.bits_per_pixel == 24) {
+			hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0;
+			hw->DACclk[4] = (65 - loopfeed) | 0x80;
+			if (ACCESS_FBINFO(accel.ramdac_rev) > 0x20) {
+				if (isInterleave(MINFO))
+					hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_8_3;
+				else {
+					hw->DACclk[4] &= ~0xC0;
+					hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_4_3;
+				}
+			} else {
+				if (isInterleave(MINFO))
+					;	/* default... */
+				else {
+					hw->DACclk[4] ^= 0xC0;	/* change from 0x80 to 0x40 */
+					hw->DACreg[POS3026_XLATCHCTRL] = TVP3026A_XLATCHCTRL_4_3;
+				}
+			}
+			hw->DACclk[5] = looppost | 0xF8;
+			if (ACCESS_FBINFO(devflags.mga_24bpp_fix))
+				hw->DACclk[5] ^= 0x40;
+		} else {
+			hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0;
+			hw->DACclk[4] = 65 - loopfeed;
+			hw->DACclk[5] = looppost | 0xF0;
+		}
+		hw->DACreg[POS3026_XMEMPLLCTRL] = loopdiv | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_RCLK_LOOPPLL;
+	}
+	return 0;
+}
+
+static int Ti3026_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
+	u_int8_t muxctrl = isInterleave(MINFO) ? TVP3026_XMUXCTRL_MEMORY_64BIT : TVP3026_XMUXCTRL_MEMORY_32BIT;
+
+	DBG("Ti3026_init")
+
+	memcpy(hw->DACreg, MGADACbpp32, sizeof(hw->DACreg));
+	if (p->type == FB_TYPE_TEXT) {
+		hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_8_1;
+		hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
+		hw->DACreg[POS3026_XMUXCTRL] = TVP3026_XMUXCTRL_VGA;
+		hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL |
+					       TVP3026_XCLKCTRL_DIV4;
+		hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_6BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
+	} else {
+		switch (p->var.bits_per_pixel) {
+		case 4:	hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1;	/* or _8_1, they are same */
+			hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
+			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_4BIT;
+			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV8;
+			hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
+			break;
+		case 8: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_8_1;	/* or _4_1, they are same */
+			hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
+			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_8BIT;
+			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;
+			hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
+			break;
+		case 16:
+			/* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used everytime) */
+			hw->DACreg[POS3026_XTRUECOLORCTRL] = (p->var.green.length == 5)? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555 ) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565);
+			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT;
+			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2;
+			break;
+		case 24:
+			/* XLATCHCTRL is: for (A) use _4_3 (?_8_3 is same? TBD), for (B) it is set in setpclk */
+			hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_888;
+			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;
+			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;
+			break;
+		case 32:
+			/* XLATCHCTRL should be _2_1 / _1_1... Why is not? (_2_1 is used everytime) */
+			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;
+			break;
+		default:
+			return 1;	/* TODO: failed */
+		}
+	}
+	if (matroxfb_vgaHWinit(PMINFO hw, m, p)) return 1;
+
+	/* set SYNC */
+	hw->MiscOutReg = 0xCB;
+	if (m->sync & FB_SYNC_HOR_HIGH_ACT)
+		hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_HSYNC_NEG;
+	if (m->sync & FB_SYNC_VERT_HIGH_ACT)
+		hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_VSYNC_NEG;
+	if (m->sync & FB_SYNC_ON_GREEN)
+		hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_SYNC_ON_GREEN;
+
+	/* set DELAY */
+	if (ACCESS_FBINFO(video.len) < 0x400000)
+		hw->CRTCEXT[3] |= 0x08;
+	else if (ACCESS_FBINFO(video.len) > 0x400000)
+		hw->CRTCEXT[3] |= 0x10;
+
+	/* set HWCURSOR */
+	if (m->interlaced) {
+		hw->DACreg[POS3026_XCURCTRL] |= TVP3026_XCURCTRL_INTERLACED;
+	}
+	if (m->HTotal >= 1536)
+		hw->DACreg[POS3026_XCURCTRL] |= TVP3026_XCURCTRL_BLANK4096;
+
+	/* set interleaving */
+	hw->MXoptionReg &= ~0x00001000;
+	if ((p->type != FB_TYPE_TEXT) && isInterleave(MINFO)) hw->MXoptionReg |= 0x00001000;
+
+	/* set DAC */
+	Ti3026_setpclk(PMINFO hw, m->pixclock, p);
+	return 0;
+}
+
+static void ti3026_setMCLK(CPMINFO struct matrox_hw_state* hw, int fout){
+	unsigned int f_pll;
+	unsigned int pclk_m, pclk_n, pclk_p;
+	unsigned int mclk_m, mclk_n, mclk_p;
+	unsigned int rfhcnt, mclk_ctl;
+	int tmout;
+
+	DBG("ti3026_setMCLK")
+
+	f_pll = Ti3026_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &mclk_n, &mclk_m, &mclk_p);
+
+	/* save pclk */
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC);
+	pclk_n = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFD);
+	pclk_m = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE);
+	pclk_p = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
+
+	/* stop pclk */
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE);
+	outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00);
+
+	/* set pclk to new mclk */
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC);
+	outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_n | 0xC0);
+	outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_m);
+	outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_p | 0xB0);
+
+	/* wait for PLL to lock */
+	for (tmout = 500000; tmout; tmout--) {
+		if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40)
+			break;
+		udelay(10);
+	};
+	if (!tmout)
+		printk(KERN_ERR "matroxfb: Temporary pixel PLL not locked after 5 secs\n");
+
+	/* output pclk on mclk pin */
+	mclk_ctl = inTi3026(PMINFO TVP3026_XMEMPLLCTRL);
+	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, mclk_ctl & 0xE7);
+	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_STROBEMKC4);
+
+	/* stop MCLK */
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFB);
+	outTi3026(PMINFO TVP3026_XMEMPLLDATA, 0x00);
+
+	/* set mclk to new freq */
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0xF3);
+	outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_n | 0xC0);
+	outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_m);
+	outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_p | 0xB0);
+
+	/* wait for PLL to lock */
+	for (tmout = 500000; tmout; tmout--) {
+		if (inTi3026(PMINFO TVP3026_XMEMPLLDATA) & 0x40)
+			break;
+		udelay(10);
+	}
+	if (!tmout)
+		printk(KERN_ERR "matroxfb: Memory PLL not locked after 5 secs\n");
+
+	f_pll = f_pll * 333 / (10000 << mclk_p);
+	if (isMilleniumII(MINFO)) {
+		rfhcnt = (f_pll - 128) / 256;
+		if (rfhcnt > 15)
+			rfhcnt = 15;
+	} else {
+		rfhcnt = (f_pll - 64) / 128;
+		if (rfhcnt > 15)
+			rfhcnt = 0;
+	}
+	hw->MXoptionReg = (hw->MXoptionReg & ~0x000F0000) | (rfhcnt << 16);
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+
+	/* output MCLK to MCLK pin */
+	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);
+	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl       ) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_STROBEMKC4);
+
+	/* stop PCLK */
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE);
+	outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00);
+
+	/* restore pclk */
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC);
+	outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_n);
+	outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_m);
+	outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_p);
+
+	/* wait for PLL to lock */
+	for (tmout = 500000; tmout; tmout--) {
+		if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40)
+			break;
+		udelay(10);
+	}
+	if (!tmout)
+		printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
+}
+
+static void ti3026_ramdac_init(WPMINFO struct matrox_hw_state* hw){
+
+	DBG("ti3026_ramdac_init")
+
+	ACCESS_FBINFO(features.pll.vco_freq_min) = 110000;
+	ACCESS_FBINFO(features.pll.ref_freq)	 = 114545;
+	ACCESS_FBINFO(features.pll.feed_div_min) = 2;
+	ACCESS_FBINFO(features.pll.feed_div_max) = 24;
+	ACCESS_FBINFO(features.pll.in_div_min)	 = 2;
+	ACCESS_FBINFO(features.pll.in_div_max)	 = 63;
+	ACCESS_FBINFO(features.pll.post_shift_max) = 3;
+	if (ACCESS_FBINFO(devflags.noinit))
+		return;
+	ti3026_setMCLK(PMINFO hw, 60000);
+}
+
+static void Ti3026_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) {
+	int i;
+	CRITFLAGS
+
+	DBG("Ti3026_restore")
+
+#ifdef DEBUG
+	dprintk(KERN_INFO "EXTVGA regs: ");
+	for (i = 0; i < 6; i++)
+		dprintk("%02X:", hw->CRTCEXT[i]);
+	dprintk("\n");
+#endif
+
+	CRITBEGIN
+
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+
+	CRITEND
+
+	matroxfb_vgaHWrestore(PMINFO hw, oldhw);
+
+	CRITBEGIN
+
+	for (i = 0; i < 6; i++)
+		mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
+
+	for (i = 0; i < 21; i++) {
+		outTi3026(PMINFO DACseq[i], hw->DACreg[i]);
+	}
+	if (oldhw) {
+		outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
+		oldhw->DACclk[0] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
+		oldhw->DACclk[3] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
+		outTi3026(PMINFO TVP3026_XPLLADDR, 0x15);
+		oldhw->DACclk[1] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
+		oldhw->DACclk[4] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
+		outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
+		oldhw->DACclk[2] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
+		oldhw->DACclk[5] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
+	}
+	CRITEND
+	if (!oldhw || memcmp(hw->DACclk, oldhw->DACclk, 6)) {
+		/* agrhh... setting up PLL is very slow on Millennium... */
+		/* Mystique PLL is locked in few ms, but Millennium PLL lock takes about 0.15 s... */
+		/* Maybe even we should call schedule() ? */
+
+		CRITBEGIN
+		outTi3026(PMINFO TVP3026_XCLKCTRL, hw->DACreg[POS3026_XCLKCTRL]);
+		outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
+		outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0);
+		outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0);
+
+		outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
+		for (i = 0; i < 3; i++)
+			outTi3026(PMINFO TVP3026_XPIXPLLDATA, hw->DACclk[i]);
+		/* wait for PLL only if PLL clock requested (always for PowerMode, never for VGA) */
+		if (hw->MiscOutReg & 0x08) {
+			int tmout;
+			outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F);
+			for (tmout = 500000; tmout; --tmout) {
+				if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40)
+					break;
+				udelay(10);
+			}
+
+			CRITEND
+
+			if (!tmout)
+				printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
+			else
+				dprintk(KERN_INFO "PixelPLL: %d\n", 500000-tmout);
+			CRITBEGIN
+		}
+		outTi3026(PMINFO TVP3026_XMEMPLLCTRL, hw->DACreg[POS3026_XMEMPLLCTRL]);
+		outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
+		for (i = 3; i < 6; i++)
+			outTi3026(PMINFO TVP3026_XLOOPPLLDATA, hw->DACclk[i]);
+		CRITEND
+		if ((hw->MiscOutReg & 0x08) && ((hw->DACclk[5] & 0x80) == 0x80)) {
+			int tmout;
+
+			CRITBEGIN
+			outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F);
+			for (tmout = 500000; tmout; --tmout) {
+				if (inTi3026(PMINFO TVP3026_XLOOPPLLDATA) & 0x40)
+					break;
+				udelay(10);
+			}
+			CRITEND
+			if (!tmout)
+				printk(KERN_ERR "matroxfb: Loop PLL not locked after 5 secs\n");
+			else
+				dprintk(KERN_INFO "LoopPLL: %d\n", 500000-tmout);
+		}
+	}
+	matrox_init_putc(PMINFO p, matroxfb_ti3026_createcursor);
+
+#ifdef DEBUG
+	dprintk(KERN_DEBUG "3026DACregs ");
+	for (i = 0; i < 21; i++) {
+		dprintk("R%02X=%02X ", DACseq[i], hw->DACreg[i]);
+		if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
+	}
+	dprintk("\n" KERN_DEBUG "DACclk ");
+	for (i = 0; i < 6; i++)
+		dprintk("C%02X=%02X ", i, hw->DACclk[i]);
+	dprintk("\n");
+#endif
+}
+
+static void Ti3026_reset(WPMINFO struct matrox_hw_state* hw){
+
+	DBG("Ti3026_reset")
+
+	matroxfb_fastfont_init(MINFO);
+
+	ti3026_ramdac_init(PMINFO hw);
+}
+
+static int Ti3026_preinit(WPMINFO struct matrox_hw_state* hw){
+	static const int vxres_mill2[] = { 512,        640, 768,  800,  832,  960,
+					  1024, 1152, 1280,      1600, 1664, 1920,
+					  2048, 0};
+	static const int vxres_mill1[] = {             640, 768,  800,        960,
+					  1024, 1152, 1280,      1600,       1920,
+					  2048, 0};
+
+	DBG("Ti3026_preinit")
+
+	ACCESS_FBINFO(millenium) = 1;
+	ACCESS_FBINFO(milleniumII) = (ACCESS_FBINFO(pcidev)->device != PCI_DEVICE_ID_MATROX_MIL);
+	ACCESS_FBINFO(capable.cfb4) = 1;
+	ACCESS_FBINFO(capable.text) = 1; /* isMilleniumII(MINFO); */
+	ACCESS_FBINFO(capable.vxres) = isMilleniumII(MINFO)?vxres_mill2:vxres_mill1;
+	ACCESS_FBINFO(cursor.timer.function) = matroxfb_ti3026_flashcursor;
+
+	if (ACCESS_FBINFO(devflags.noinit))
+		return 0;
+	/* preserve VGA I/O, BIOS and PPC */
+	hw->MXoptionReg &= 0xC0000100;
+	hw->MXoptionReg |= 0x002C0000;
+	if (ACCESS_FBINFO(devflags.novga))
+		hw->MXoptionReg &= ~0x00000100;
+	if (ACCESS_FBINFO(devflags.nobios))
+		hw->MXoptionReg &= ~0x40000000;
+	if (ACCESS_FBINFO(devflags.nopciretry))
+		hw->MXoptionReg |=  0x20000000;
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+
+	ACCESS_FBINFO(accel.ramdac_rev) = inTi3026(PMINFO TVP3026_XSILICONREV);
+
+	outTi3026(PMINFO TVP3026_XCLKCTRL, TVP3026_XCLKCTRL_SRC_CLK0VGA | TVP3026_XCLKCTRL_CLKSTOPPED);
+	outTi3026(PMINFO TVP3026_XTRUECOLORCTRL, TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR);
+	outTi3026(PMINFO TVP3026_XMUXCTRL, TVP3026_XMUXCTRL_VGA);
+
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
+	outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0x00);
+	outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00);
+
+	mga_outb(M_MISC_REG, 0x67);
+
+	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, TVP3026_XMEMPLLCTRL_STROBEMKC4 | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);
+
+	mga_outl(M_RESET, 1);
+	udelay(250);
+	mga_outl(M_RESET, 0);
+	udelay(250);
+	mga_outl(M_MACCESS, 0x00008000);
+	udelay(10);
+	return 0;
+}
+
+struct matrox_switch matrox_millennium = {
+	Ti3026_preinit, Ti3026_reset, Ti3026_init, Ti3026_restore, matroxfb_ti3026_selhwcursor
+};
+EXPORT_SYMBOL(matrox_millennium);
+#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_Ti3026.h linux/drivers/video/matrox/matroxfb_Ti3026.h
--- v2.3.47/linux/drivers/video/matrox/matroxfb_Ti3026.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_Ti3026.h	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,13 @@
+#ifndef __MATROXFB_TI3026_H__
+#define __MATROXFB_TI3026_H__
+
+/* make checkconfig does not walk through whole include tree */
+#include <linux/config.h>
+
+#include "matroxfb_base.h"
+
+#ifdef CONFIG_FB_MATROX_MILLENIUM
+extern struct matrox_switch matrox_millennium;
+#endif
+
+#endif	/* __MATROXFB_TI3026_H__ */
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_accel.c linux/drivers/video/matrox/matroxfb_accel.c
--- v2.3.47/linux/drivers/video/matrox/matroxfb_accel.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_accel.c	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,1212 @@
+/*
+ *
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
+ *
+ * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>
+ *
+ * Version: 1.21 2000/01/09
+ *
+ * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
+ *
+ * Contributors: "menion?" <menion@mindless.com>
+ *                     Betatesting, fixes, ideas
+ *
+ *               "Kurt Garloff" <garloff@kg1.ping.de>
+ *                     Betatesting, fixes, ideas, videomodes, videomodes timmings
+ *
+ *               "Tom Rini" <trini@kernel.crashing.org>
+ *                     MTRR stuff, PPC cleanups, betatesting, fixes, ideas
+ *
+ *               "Bibek Sahu" <scorpio@dodds.net>
+ *                     Access device through readb|w|l and write b|w|l
+ *                     Extensive debugging stuff
+ *
+ *               "Daniel Haun" <haund@usa.net>
+ *                     Testing, hardware cursor fixes
+ *
+ *               "Scott Wood" <sawst46+@pitt.edu>
+ *                     Fixes
+ *
+ *               "Gerd Knorr" <kraxel@goldbach.isdn.cs.tu-berlin.de>
+ *                     Betatesting
+ *
+ *               "Kelly French" <targon@hazmat.com>
+ *               "Fernando Herrera" <fherrera@eurielec.etsit.upm.es>
+ *                     Betatesting, bug reporting
+ *
+ *               "Pablo Bianucci" <pbian@pccp.com.ar>
+ *                     Fixes, ideas, betatesting
+ *
+ *               "Inaky Perez Gonzalez" <inaky@peloncho.fis.ucm.es>
+ *                     Fixes, enhandcements, ideas, betatesting
+ *
+ *               "Ryuichi Oikawa" <roikawa@rr.iiij4u.or.jp>
+ *                     PPC betatesting, PPC support, backward compatibility
+ *
+ *               "Paul Womar" <Paul@pwomar.demon.co.uk>
+ *               "Owen Waller" <O.Waller@ee.qub.ac.uk>
+ *                     PPC betatesting
+ *
+ *               "Thomas Pornin" <pornin@bolet.ens.fr>
+ *                     Alpha betatesting
+ *
+ *               "Pieter van Leuven" <pvl@iae.nl>
+ *               "Ulf Jaenicke-Roessler" <ujr@physik.phy.tu-dresden.de>
+ *                     G100 testing
+ *
+ *               "H. Peter Arvin" <hpa@transmeta.com>
+ *                     Ideas
+ *
+ *               "Cort Dougan" <cort@cs.nmt.edu>
+ *                     CHRP fixes and PReP cleanup
+ *
+ *               "Mark Vojkovich" <mvojkovi@ucsd.edu>
+ *                     G400 support
+ *
+ * (following author is not in any relation with this code, but his code
+ *  is included in this driver)
+ *
+ * Based on framebuffer driver for VBE 2.0 compliant graphic boards
+ *     (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
+ *
+ * (following author is not in any relation with this code, but his ideas
+ *  were used when writting this driver)
+ *
+ *		 FreeVBE/AF (Matrox), "Shawn Hargreaves" <shawn@talula.demon.co.uk>
+ *
+ */
+
+#include "matroxfb_accel.h"
+#include "matroxfb_DAC1064.h"
+#include "matroxfb_Ti3026.h"
+#include "matroxfb_misc.h"
+
+#define curr_ydstorg(x)	ACCESS_FBINFO2(x, curr.ydstorg.pixels)
+
+#define mga_ydstlen(y,l) mga_outl(M_YDSTLEN | M_EXEC, ((y) << 16) | (l))
+
+void matrox_cfbX_init(WPMINFO struct display* p) {
+	u_int32_t maccess;
+	u_int32_t mpitch;
+	u_int32_t mopmode;
+
+	DBG("matrox_cfbX_init")
+
+	mpitch = p->var.xres_virtual;
+
+	if (p->type == FB_TYPE_TEXT) {
+		maccess = 0x00000000;
+		mpitch = (mpitch >> 4) | 0x8000; /* set something */
+		mopmode = M_OPMODE_8BPP;
+	} else {
+		switch (p->var.bits_per_pixel) {
+		case 4:		maccess = 0x00000000;	/* accelerate as 8bpp video */
+				mpitch = (mpitch >> 1) | 0x8000; /* disable linearization */
+				mopmode = M_OPMODE_4BPP;
+				break;
+		case 8:		maccess = 0x00000000;
+				mopmode = M_OPMODE_8BPP;
+				break;
+		case 16:	if (p->var.green.length == 5)
+					maccess = 0xC0000001;
+				else
+					maccess = 0x40000001;
+				mopmode = M_OPMODE_16BPP;
+				break;
+		case 24:	maccess = 0x00000003;
+				mopmode = M_OPMODE_24BPP;
+				break;
+		case 32:	maccess = 0x00000002;
+				mopmode = M_OPMODE_32BPP;
+				break;
+		default:	maccess = 0x00000000;
+				mopmode = 0x00000000;
+				break;	/* turn off acceleration!!! */
+		}
+	}
+	mga_fifo(8);
+	mga_outl(M_PITCH, mpitch);
+	mga_outl(M_YDSTORG, curr_ydstorg(MINFO));
+	if (ACCESS_FBINFO(capable.plnwt))
+		mga_outl(M_PLNWT, -1);
+	mga_outl(M_OPMODE, mopmode);
+	mga_outl(M_CXBNDRY, 0xFFFF0000);
+	mga_outl(M_YTOP, 0);
+	mga_outl(M_YBOT, 0x01FFFFFF);
+	mga_outl(M_MACCESS, maccess);
+	ACCESS_FBINFO(accel.m_dwg_rect) = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO;
+	if (isMilleniumII(MINFO)) ACCESS_FBINFO(accel.m_dwg_rect) |= M_DWG_TRANSC;
+	ACCESS_FBINFO(accel.m_opmode) = mopmode;
+}
+
+static void matrox_cfbX_bmove(struct display* p, int sy, int sx, int dy, int dx, int height, int width) {
+	int pixx = p->var.xres_virtual, start, end;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	DBG("matrox_cfbX_bmove")
+
+	CRITBEGIN
+
+	sx *= fontwidth(p);
+	dx *= fontwidth(p);
+	width *= fontwidth(p);
+	height *= fontheight(p);
+	sy *= fontheight(p);
+	dy *= fontheight(p);
+	if ((dy < sy) || ((dy == sy) && (dx <= sx))) {
+		mga_fifo(2);
+		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |
+			 M_DWG_BFCOL | M_DWG_REPLACE);
+		mga_outl(M_AR5, pixx);
+		width--;
+		start = sy*pixx+sx+curr_ydstorg(MINFO);
+		end = start+width;
+	} else {
+		mga_fifo(3);
+		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);
+		mga_outl(M_SGN, 5);
+		mga_outl(M_AR5, -pixx);
+		width--;
+		end = (sy+height-1)*pixx+sx+curr_ydstorg(MINFO);
+		start = end+width;
+		dy += height-1;
+	}
+	mga_fifo(4);
+	mga_outl(M_AR0, end);
+	mga_outl(M_AR3, start);
+	mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
+	mga_ydstlen(dy, height);
+	WaitTillIdle();
+
+	CRITEND
+}
+
+#ifdef FBCON_HAS_CFB4
+static void matrox_cfb4_bmove(struct display* p, int sy, int sx, int dy, int dx, int height, int width) {
+	int pixx, start, end;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+	/* both (sx or dx or width) and fontwidth() are odd, so their multiply is
+	   also odd, that means that we cannot use acceleration */
+
+	DBG("matrox_cfb4_bmove")
+
+	CRITBEGIN
+
+	if ((sx | dx | width) & fontwidth(p) & 1) {
+		fbcon_cfb4_bmove(p, sy, sx, dy, dx, height, width);
+		return;
+	}
+	sx *= fontwidth(p);
+	dx *= fontwidth(p);
+	width *= fontwidth(p);
+	height *= fontheight(p);
+	sy *= fontheight(p);
+	dy *= fontheight(p);
+	pixx = p->var.xres_virtual >> 1;
+	sx >>= 1;
+	dx >>= 1;
+	width >>= 1;
+	if ((dy < sy) || ((dy == sy) && (dx <= sx))) {
+		mga_fifo(2);
+		mga_outl(M_AR5, pixx);
+		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |
+			M_DWG_BFCOL | M_DWG_REPLACE);
+		width--;
+		start = sy*pixx+sx+curr_ydstorg(MINFO);
+		end = start+width;
+	} else {
+		mga_fifo(3);
+		mga_outl(M_SGN, 5);
+		mga_outl(M_AR5, -pixx);
+		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);
+		width--;
+		end = (sy+height-1)*pixx+sx+curr_ydstorg(MINFO);
+		start = end+width;
+		dy += height-1;
+	}
+	mga_fifo(5);
+	mga_outl(M_AR0, end);
+	mga_outl(M_AR3, start);
+	mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
+	mga_outl(M_YDST, dy*pixx >> 5);
+	mga_outl(M_LEN | M_EXEC, height);
+	WaitTillIdle();
+
+	CRITEND
+}
+#endif
+
+static void matroxfb_accel_clear(WPMINFO u_int32_t color, int sy, int sx, int height,
+		int width) {
+	CRITFLAGS
+
+	DBG("matroxfb_accel_clear")
+
+	CRITBEGIN
+
+	mga_fifo(5);
+	mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_REPLACE);
+	mga_outl(M_FCOL, color);
+	mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
+	mga_ydstlen(sy, height);
+	WaitTillIdle();
+
+	CRITEND
+}
+
+static void matrox_cfbX_clear(u_int32_t color, struct display* p, int sy, int sx, int height, int width) {
+
+	DBG("matrox_cfbX_clear")
+
+	matroxfb_accel_clear(PMXINFO(p) color, sy * fontheight(p), sx * fontwidth(p),
+			     height * fontheight(p), width * fontwidth(p));
+}
+
+#ifdef FBCON_HAS_CFB4
+static void matrox_cfb4_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) {
+	u_int32_t bgx;
+	int whattodo;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	DBG("matrox_cfb4_clear")
+
+	CRITBEGIN
+
+	whattodo = 0;
+	bgx = attr_bgcol_ec(p, conp);
+	bgx |= bgx << 4;
+	bgx |= bgx << 8;
+	bgx |= bgx << 16;
+	sy *= fontheight(p);
+	sx *= fontwidth(p);
+	height *= fontheight(p);
+	width *= fontwidth(p);
+	if (sx & 1) {
+		sx ++;
+		if (!width) return;
+		width --;
+		whattodo = 1;
+	}
+	if (width & 1) {
+		whattodo |= 2;
+	}
+	width >>= 1;
+	sx >>= 1;
+	if (width) {
+		mga_fifo(5);
+		mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_REPLACE2);
+		mga_outl(M_FCOL, bgx);
+		mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
+		mga_outl(M_YDST, sy * p->var.xres_virtual >> 6);
+		mga_outl(M_LEN | M_EXEC, height);
+		WaitTillIdle();
+	}
+	if (whattodo) {
+		u_int32_t step = p->var.xres_virtual >> 1;
+		vaddr_t vbase = ACCESS_FBINFO(video.vbase);
+		if (whattodo & 1) {
+			unsigned int uaddr = sy * step + sx - 1;
+			u_int32_t loop;
+			u_int8_t bgx2 = bgx & 0xF0;
+			for (loop = height; loop > 0; loop --) {
+				mga_writeb(vbase, uaddr, (mga_readb(vbase, uaddr) & 0x0F) | bgx2);
+				uaddr += step;
+			}
+		}
+		if (whattodo & 2) {
+			unsigned int uaddr = sy * step + sx + width;
+			u_int32_t loop;
+			u_int8_t bgx2 = bgx & 0x0F;
+			for (loop = height; loop > 0; loop --) {
+				mga_writeb(vbase, uaddr, (mga_readb(vbase, uaddr) & 0xF0) | bgx2);
+				uaddr += step;
+			}
+		}
+	}
+
+	CRITEND
+}
+#endif
+
+#ifdef FBCON_HAS_CFB8
+static void matrox_cfb8_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) {
+	u_int32_t bgx;
+
+	DBG("matrox_cfb8_clear")
+
+	bgx = attr_bgcol_ec(p, conp);
+	bgx |= bgx << 8;
+	bgx |= bgx << 16;
+	matrox_cfbX_clear(bgx, p, sy, sx, height, width);
+}
+#endif
+
+#ifdef FBCON_HAS_CFB16
+static void matrox_cfb16_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) {
+	u_int32_t bgx;
+
+	DBG("matrox_cfb16_clear")
+
+	bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+	matrox_cfbX_clear((bgx << 16) | bgx, p, sy, sx, height, width);
+}
+#endif
+
+#if defined(FBCON_HAS_CFB32) || defined(FBCON_HAS_CFB24)
+static void matrox_cfb32_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) {
+	u_int32_t bgx;
+
+	DBG("matrox_cfb32_clear")
+
+	bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+	matrox_cfbX_clear(bgx, p, sy, sx, height, width);
+}
+#endif
+
+static void matrox_cfbX_fastputc(u_int32_t fgx, u_int32_t bgx, struct display* p, int c, int yy, int xx) {
+	unsigned int charcell;
+	unsigned int ar3;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	charcell = fontwidth(p) * fontheight(p);
+	yy *= fontheight(p);
+	xx *= fontwidth(p);
+
+	CRITBEGIN
+
+	mga_fifo(8);
+	mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
+
+	mga_outl(M_FCOL, fgx);
+	mga_outl(M_BCOL, bgx);
+	mga_outl(M_FXBNDRY, ((xx + fontwidth(p) - 1) << 16) | xx);
+	ar3 = ACCESS_FBINFO(fastfont.mgabase) + (c & p->charmask) * charcell;
+	mga_outl(M_AR3, ar3);
+	mga_outl(M_AR0, (ar3 + charcell - 1) & 0x0003FFFF);
+	mga_ydstlen(yy, fontheight(p));
+	WaitTillIdle();
+
+	CRITEND
+}
+
+static void matrox_cfbX_putc(u_int32_t fgx, u_int32_t bgx, struct display* p, int c, int yy, int xx) {
+	u_int32_t ar0;
+	u_int32_t step;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	DBG_HEAVY("matrox_cfbX_putc");
+
+	yy *= fontheight(p);
+	xx *= fontwidth(p);
+
+	CRITBEGIN
+
+#ifdef __BIG_ENDIAN
+	WaitTillIdle();
+	mga_outl(M_OPMODE, M_OPMODE_8BPP);
+#else
+	mga_fifo(7);
+#endif
+	ar0 = fontwidth(p) - 1;
+	mga_outl(M_FXBNDRY, ((xx+ar0)<<16) | xx);
+	if (fontwidth(p) <= 8)
+		step = 1;
+	else if (fontwidth(p) <= 16)
+		step = 2;
+	else
+		step = 4;
+	if (fontwidth(p) == step << 3) {
+		size_t charcell = fontheight(p)*step;
+		/* TODO: Align charcell to 4B for BE */
+		mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
+		mga_outl(M_FCOL, fgx);
+		mga_outl(M_BCOL, bgx);
+		mga_outl(M_AR3, 0);
+		mga_outl(M_AR0, fontheight(p)*fontwidth(p)-1);
+		mga_ydstlen(yy, fontheight(p));
+		mga_memcpy_toio(ACCESS_FBINFO(mmio.vbase), 0, p->fontdata+(c&p->charmask)*charcell, charcell);
+	} else {
+		u8* chardata = p->fontdata+(c&p->charmask)*fontheight(p)*step;
+		int i;
+
+		mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_REPLACE);
+		mga_outl(M_FCOL, fgx);
+		mga_outl(M_BCOL, bgx);
+		mga_outl(M_AR5, 0);
+		mga_outl(M_AR3, 0);
+		mga_outl(M_AR0, ar0);
+		mga_ydstlen(yy, fontheight(p));
+
+		switch (step) {
+		case 1:
+			for (i = fontheight(p); i > 0; i--) {
+#ifdef __LITTLE_ENDIAN
+				mga_outl(0, *chardata++);
+#else
+				mga_outl(0, (*chardata++) << 24);
+#endif
+			}
+			break;
+		case 2:
+			for (i = fontheight(p); i > 0; i--) {
+#ifdef __LITTLE_ENDIAN
+				mga_outl(0, *(u_int16_t*)chardata);
+#else
+				mga_outl(0, (*(u_int16_t*)chardata) << 16);
+#endif
+				chardata += 2;
+			}
+			break;
+		case 4:
+			mga_memcpy_toio(ACCESS_FBINFO(mmio.vbase), 0, chardata, fontheight(p) * 4);
+			break;
+		}
+	}
+	WaitTillIdle();
+#ifdef __BIG_ENDIAN
+	mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
+#endif
+	CRITEND
+}
+
+#ifdef FBCON_HAS_CFB8
+static void matrox_cfb8_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
+	u_int32_t fgx, bgx;
+	MINFO_FROM_DISP(p);
+
+	DBG_HEAVY("matroxfb_cfb8_putc");
+
+	fgx = attr_fgcol(p, c);
+	bgx = attr_bgcol(p, c);
+	fgx |= (fgx << 8);
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 8);
+	bgx |= (bgx << 16);
+	ACCESS_FBINFO(curr.putc)(fgx, bgx, p, c, yy, xx);
+}
+#endif
+
+#ifdef FBCON_HAS_CFB16
+static void matrox_cfb16_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
+	u_int32_t fgx, bgx;
+	MINFO_FROM_DISP(p);
+
+	DBG_HEAVY("matroxfb_cfb16_putc");
+
+	fgx = ((u_int16_t*)p->dispsw_data)[attr_fgcol(p, c)];
+	bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol(p, c)];
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 16);
+	ACCESS_FBINFO(curr.putc)(fgx, bgx, p, c, yy, xx);
+}
+#endif
+
+#if defined(FBCON_HAS_CFB32) || defined(FBCON_HAS_CFB24)
+static void matrox_cfb32_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
+	u_int32_t fgx, bgx;
+	MINFO_FROM_DISP(p);
+
+	DBG_HEAVY("matroxfb_cfb32_putc");
+
+	fgx = ((u_int32_t*)p->dispsw_data)[attr_fgcol(p, c)];
+	bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol(p, c)];
+	ACCESS_FBINFO(curr.putc)(fgx, bgx, p, c, yy, xx);
+}
+#endif
+
+static void matrox_cfbX_fastputcs(u_int32_t fgx, u_int32_t bgx, struct display* p, const unsigned short* s, int count, int yy, int xx) {
+	unsigned int charcell;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	yy *= fontheight(p);
+	xx *= fontwidth(p);
+	charcell = fontwidth(p) * fontheight(p);
+
+	CRITBEGIN
+
+	mga_fifo(3);
+	mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
+	mga_outl(M_FCOL, fgx);
+	mga_outl(M_BCOL, bgx);
+	while (count--) {
+		u_int32_t ar3 = ACCESS_FBINFO(fastfont.mgabase) + (scr_readw(s++) & p->charmask)*charcell;
+
+		mga_fifo(4);
+		mga_outl(M_FXBNDRY, ((xx + fontwidth(p) - 1) << 16) | xx);
+		mga_outl(M_AR3, ar3);
+		mga_outl(M_AR0, (ar3 + charcell - 1) & 0x0003FFFF);
+		mga_ydstlen(yy, fontheight(p));
+		xx += fontwidth(p);
+	}
+	WaitTillIdle();
+
+	CRITEND
+}
+
+static void matrox_cfbX_putcs(u_int32_t fgx, u_int32_t bgx, struct display* p, const unsigned short* s, int count, int yy, int xx) {
+	u_int32_t step;
+	u_int32_t ydstlen;
+	u_int32_t xlen;
+	u_int32_t ar0;
+	u_int32_t charcell;
+	u_int32_t fxbndry;
+	vaddr_t mmio;
+	int easy;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	DBG_HEAVY("matroxfb_cfbX_putcs");
+
+	yy *= fontheight(p);
+	xx *= fontwidth(p);
+	if (fontwidth(p) <= 8)
+		step = 1;
+	else if (fontwidth(p) <= 16)
+		step = 2;
+	else
+		step = 4;
+	charcell = fontheight(p)*step;
+	xlen = (charcell + 3) & ~3;
+	ydstlen = (yy << 16) | fontheight(p);
+	if (fontwidth(p) == step << 3) {
+		ar0 = fontheight(p)*fontwidth(p) - 1;
+		easy = 1;
+	} else {
+		ar0 = fontwidth(p) - 1;
+		easy = 0;
+	}
+
+	CRITBEGIN
+
+#ifdef __BIG_ENDIAN
+	WaitTillIdle();
+	mga_outl(M_OPMODE, M_OPMODE_8BPP);
+#else
+	mga_fifo(3);
+#endif
+	if (easy)
+		mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
+	else
+		mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_REPLACE);
+	mga_outl(M_FCOL, fgx);
+	mga_outl(M_BCOL, bgx);
+	fxbndry = ((xx + fontwidth(p) - 1) << 16) | xx;
+	mmio = ACCESS_FBINFO(mmio.vbase);
+	while (count--) {
+		u_int8_t* chardata = p->fontdata + (scr_readw(s++) & p->charmask)*charcell;
+
+		mga_fifo(6);
+		mga_writel(mmio, M_FXBNDRY, fxbndry);
+		mga_writel(mmio, M_AR0, ar0);
+		mga_writel(mmio, M_AR3, 0);
+		if (easy) {
+			mga_writel(mmio, M_YDSTLEN | M_EXEC, ydstlen);
+			mga_memcpy_toio(mmio, 0, chardata, xlen);
+		} else {
+			mga_writel(mmio, M_AR5, 0);
+			mga_writel(mmio, M_YDSTLEN | M_EXEC, ydstlen);
+			switch (step) {
+				case 1:	{
+						u_int8_t* charend = chardata + charcell;
+						for (; chardata != charend; chardata++) {
+#ifdef __LITTLE_ENDIAN
+							mga_writel(mmio, 0, *chardata);
+#else
+							mga_writel(mmio, 0, (*chardata) << 24);
+#endif
+						}
+					}
+					break;
+				case 2:	{
+						u_int8_t* charend = chardata + charcell;
+						for (; chardata != charend; chardata += 2) {
+#ifdef __LITTLE_ENDIAN
+							mga_writel(mmio, 0, *(u_int16_t*)chardata);
+#else
+							mga_writel(mmio, 0, (*(u_int16_t*)chardata) << 16);
+#endif
+						}
+					}
+					break;
+				default:
+					mga_memcpy_toio(mmio, 0, chardata, charcell);
+					break;
+			}
+		}
+		fxbndry += fontwidth(p) + (fontwidth(p) << 16);
+	}
+	WaitTillIdle();
+#ifdef __BIG_ENDIAN
+	mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
+#endif
+	CRITEND
+}
+
+#ifdef FBCON_HAS_CFB8
+static void matrox_cfb8_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
+	u_int32_t fgx, bgx;
+	MINFO_FROM_DISP(p);
+
+	DBG_HEAVY("matroxfb_cfb8_putcs");
+
+	fgx = attr_fgcol(p, scr_readw(s));
+	bgx = attr_bgcol(p, scr_readw(s));
+	fgx |= (fgx << 8);
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 8);
+	bgx |= (bgx << 16);
+	ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
+}
+#endif
+
+#ifdef FBCON_HAS_CFB16
+static void matrox_cfb16_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
+	u_int32_t fgx, bgx;
+	MINFO_FROM_DISP(p);
+
+	DBG_HEAVY("matroxfb_cfb16_putcs");
+
+	fgx = ((u_int16_t*)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
+	bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 16);
+	ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
+}
+#endif
+
+#if defined(FBCON_HAS_CFB32) || defined(FBCON_HAS_CFB24)
+static void matrox_cfb32_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
+	u_int32_t fgx, bgx;
+	MINFO_FROM_DISP(p);
+
+	DBG_HEAVY("matroxfb_cfb32_putcs");
+
+	fgx = ((u_int32_t*)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
+	bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
+	ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
+}
+#endif
+
+#ifdef FBCON_HAS_CFB4
+static void matrox_cfb4_revc(struct display* p, int xx, int yy) {
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	DBG_LOOP("matroxfb_cfb4_revc");
+
+	if (fontwidth(p) & 1) {
+		fbcon_cfb4_revc(p, xx, yy);
+		return;
+	}
+	yy *= fontheight(p);
+	xx *= fontwidth(p);
+	xx |= (xx + fontwidth(p)) << 16;
+	xx >>= 1;
+
+	CRITBEGIN
+
+	mga_fifo(5);
+	mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
+	mga_outl(M_FCOL, 0xFFFFFFFF);
+	mga_outl(M_FXBNDRY, xx);
+	mga_outl(M_YDST, yy * p->var.xres_virtual >> 6);
+	mga_outl(M_LEN | M_EXEC, fontheight(p));
+	WaitTillIdle();
+
+	CRITEND
+}
+#endif
+
+#ifdef FBCON_HAS_CFB8
+static void matrox_cfb8_revc(struct display* p, int xx, int yy) {
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	DBG_LOOP("matrox_cfb8_revc")
+
+	yy *= fontheight(p);
+	xx *= fontwidth(p);
+
+	CRITBEGIN
+
+	mga_fifo(4);
+	mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
+	mga_outl(M_FCOL, 0x0F0F0F0F);
+	mga_outl(M_FXBNDRY, ((xx + fontwidth(p)) << 16) | xx);
+	mga_ydstlen(yy, fontheight(p));
+	WaitTillIdle();
+
+	CRITEND
+}
+#endif
+
+static void matrox_cfbX_revc(struct display* p, int xx, int yy) {
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	DBG_LOOP("matrox_cfbX_revc")
+
+	yy *= fontheight(p);
+	xx *= fontwidth(p);
+
+	CRITBEGIN
+
+	mga_fifo(4);
+	mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
+	mga_outl(M_FCOL, 0xFFFFFFFF);
+	mga_outl(M_FXBNDRY, ((xx + fontwidth(p)) << 16) | xx);
+	mga_ydstlen(yy, fontheight(p));
+	WaitTillIdle();
+
+	CRITEND
+}
+
+static void matrox_cfbX_clear_margins(struct vc_data* conp, struct display* p, int bottom_only) {
+	unsigned int bottom_height, right_width;
+	unsigned int bottom_start, right_start;
+	unsigned int cell_h, cell_w;
+
+	DBG("matrox_cfbX_clear_margins")
+
+	cell_w = fontwidth(p);
+	if (!cell_w) return;	/* PARANOID */
+	right_width = p->var.xres % cell_w;
+	right_start = p->var.xres - right_width;
+	if (!bottom_only && right_width) {
+		/* clear whole right margin, not only visible portion */
+		matroxfb_accel_clear(     PMXINFO(p)
+			     /* color */  0x00000000,
+			     /* y */      0,
+			     /* x */      p->var.xoffset + right_start,
+			     /* height */ p->var.yres_virtual,
+			     /* width */  right_width);
+	}
+	cell_h = fontheight(p);
+	if (!cell_h) return;	/* PARANOID */
+	bottom_height = p->var.yres % cell_h;
+	if (bottom_height) {
+		bottom_start = p->var.yres - bottom_height;
+		matroxfb_accel_clear(		  PMXINFO(p)
+				     /* color */  0x00000000,
+				     /* y */	  p->var.yoffset + bottom_start,
+				     /* x */	  p->var.xoffset,
+				     /* height */ bottom_height,
+				     /* width */  right_start);
+	}
+}
+
+static void matrox_text_setup(struct display* p) {
+	MINFO_FROM_DISP(p);
+
+	p->next_line = p->line_length ? p->line_length : ((p->var.xres_virtual / (fontwidth(p)?fontwidth(p):8)) * ACCESS_FBINFO(devflags.textstep));
+	p->next_plane = 0;
+}
+
+static void matrox_text_bmove(struct display* p, int sy, int sx, int dy, int dx,
+		int height, int width) {
+	unsigned int srcoff;
+	unsigned int dstoff;
+	unsigned int step;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	CRITBEGIN
+
+	step = ACCESS_FBINFO(devflags.textstep);
+	srcoff = (sy * p->next_line) + (sx * step);
+	dstoff = (dy * p->next_line) + (dx * step);
+	if (dstoff < srcoff) {
+		while (height > 0) {
+			int i;
+			for (i = width; i > 0; dstoff += step, srcoff += step, i--)
+				mga_writew(ACCESS_FBINFO(video.vbase), dstoff, mga_readw(ACCESS_FBINFO(video.vbase), srcoff));
+			height--;
+			dstoff += p->next_line - width * step;
+			srcoff += p->next_line - width * step;
+		}
+	} else {
+		unsigned int off;
+
+		off = (height - 1) * p->next_line + (width - 1) * step;
+		srcoff += off;
+		dstoff += off;
+		while (height > 0) {
+			int i;
+			for (i = width; i > 0; dstoff -= step, srcoff -= step, i--)
+				mga_writew(ACCESS_FBINFO(video.vbase), dstoff, mga_readw(ACCESS_FBINFO(video.vbase), srcoff));
+			dstoff -= p->next_line - width * step;
+			srcoff -= p->next_line - width * step;
+			height--;
+		}
+	}
+	CRITEND
+}
+
+static void matrox_text_clear(struct vc_data* conp, struct display* p, int sy, int sx,
+		int height, int width) {
+	unsigned int offs;
+	unsigned int val;
+	unsigned int step;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	step = ACCESS_FBINFO(devflags.textstep);
+	offs = sy * p->next_line + sx * step;
+	val = ntohs((attr_bgcol(p, conp->vc_video_erase_char) << 4) | attr_fgcol(p, conp->vc_video_erase_char) | (' ' << 8));
+
+	CRITBEGIN
+
+	while (height > 0) {
+		int i;
+		for (i = width; i > 0; offs += step, i--)
+			mga_writew(ACCESS_FBINFO(video.vbase), offs, val);
+		offs += p->next_line - width * step;
+		height--;
+	}
+	CRITEND
+}
+
+static void matrox_text_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
+	unsigned int offs;
+	unsigned int chr;
+	unsigned int step;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	step = ACCESS_FBINFO(devflags.textstep);
+	offs = yy * p->next_line + xx * step;
+	chr = attr_fgcol(p,c) | (attr_bgcol(p,c) << 4) | ((c & p->charmask) << 8);
+	if (chr & 0x10000) chr |= 0x08;
+
+	CRITBEGIN
+
+	mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(chr));
+
+	CRITEND
+}
+
+static void matrox_text_putcs(struct vc_data* conp, struct display* p, const unsigned short* s,
+		int count, int yy, int xx) {
+	unsigned int offs;
+	unsigned int attr;
+	unsigned int step;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	step = ACCESS_FBINFO(devflags.textstep);
+	offs = yy * p->next_line + xx * step;
+	attr = attr_fgcol(p, scr_readw(s)) | (attr_bgcol(p, scr_readw(s)) << 4);
+
+	CRITBEGIN
+
+	while (count-- > 0) {
+		unsigned int chr = ((scr_readw(s++)) & p->charmask) << 8;
+		if (chr & 0x10000) chr ^= 0x10008;
+		mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(attr|chr));
+		offs += step;
+	}
+
+	CRITEND
+}
+
+static void matrox_text_revc(struct display* p, int xx, int yy) {
+	unsigned int offs;
+	unsigned int step;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	step = ACCESS_FBINFO(devflags.textstep);
+	offs = yy * p->next_line + xx * step + 1;
+
+	CRITBEGIN
+
+	mga_writeb(ACCESS_FBINFO(video.vbase), offs, mga_readb(ACCESS_FBINFO(video.vbase), offs) ^ 0x77);
+
+	CRITEND
+}
+
+void matrox_text_createcursor(WPMINFO struct display* p) {
+	CRITFLAGS
+
+	if (ACCESS_FBINFO(currcon_display) != p)
+		return;
+
+	matroxfb_createcursorshape(PMINFO p, 0);
+
+	CRITBEGIN
+
+	mga_setr(M_CRTC_INDEX, 0x0A, ACCESS_FBINFO(cursor.u));
+	mga_setr(M_CRTC_INDEX, 0x0B, ACCESS_FBINFO(cursor.d) - 1);
+
+	CRITEND
+}
+
+static void matrox_text_cursor(struct display* p, int mode, int x, int y) {
+	unsigned int pos;
+	CRITFLAGS
+	MINFO_FROM_DISP(p);
+
+	if (ACCESS_FBINFO(currcon_display) != p)
+		return;
+
+	if (mode == CM_ERASE) {
+		if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
+
+			CRITBEGIN
+
+			mga_setr(M_CRTC_INDEX, 0x0A, 0x20);
+
+			CRITEND
+
+			ACCESS_FBINFO(cursor.state) = CM_ERASE;
+		}
+		return;
+	}
+	if ((p->conp->vc_cursor_type & CUR_HWMASK) != ACCESS_FBINFO(cursor.type))
+		matrox_text_createcursor(PMINFO p);
+
+	/* DO NOT CHECK cursor.x != x because of matroxfb_vgaHWinit moves cursor to 0,0 */
+	ACCESS_FBINFO(cursor.x) = x;
+	ACCESS_FBINFO(cursor.y) = y;
+	pos = p->next_line / ACCESS_FBINFO(devflags.textstep) * y + x;
+
+	CRITBEGIN
+
+	mga_setr(M_CRTC_INDEX, 0x0F, pos);
+	mga_setr(M_CRTC_INDEX, 0x0E, pos >> 8);
+
+	mga_setr(M_CRTC_INDEX, 0x0A, ACCESS_FBINFO(cursor.u));
+
+	CRITEND
+
+	ACCESS_FBINFO(cursor.state) = CM_DRAW;
+}
+
+void matrox_text_round(CPMINFO struct fb_var_screeninfo* var, struct display* p) {
+	unsigned hf;
+	unsigned vf;
+	unsigned vxres;
+	unsigned ych;
+
+	hf = fontwidth(p);
+	if (!hf) hf = 8;
+	/* do not touch xres */
+	vxres = (var->xres_virtual + hf - 1) / hf;
+	if (vxres >= 256)
+		vxres = 255;
+	if (vxres < 16)
+		vxres = 16;
+	vxres = (vxres + 1) & ~1;	/* must be even */
+	vf = fontheight(p);
+	if (!vf) vf = 16;
+	if (var->yres < var->yres_virtual) {
+		ych = ACCESS_FBINFO(devflags.textvram) / vxres;
+		var->yres_virtual = ych * vf;
+	} else
+		ych = var->yres_virtual / vf;
+	if (vxres * ych > ACCESS_FBINFO(devflags.textvram)) {
+		ych = ACCESS_FBINFO(devflags.textvram) / vxres;
+		var->yres_virtual = ych * vf;
+	}
+	var->xres_virtual = vxres * hf;
+}
+
+static int matrox_text_setfont(struct display* p, int width, int height) {
+	DBG("matrox_text_setfont");
+
+	if (p) {
+		MINFO_FROM_DISP(p);
+
+		matrox_text_round(PMINFO &p->var, p);
+		p->next_line = p->line_length = ((p->var.xres_virtual / (fontwidth(p)?fontwidth(p):8)) * ACCESS_FBINFO(devflags.textstep));
+
+		if (p->conp)
+			matrox_text_createcursor(PMINFO p);
+	}
+	return 0;
+}
+
+#define matrox_cfb16_revc matrox_cfbX_revc
+#define matrox_cfb24_revc matrox_cfbX_revc
+#define matrox_cfb32_revc matrox_cfbX_revc
+
+#define matrox_cfb24_clear matrox_cfb32_clear
+#define matrox_cfb24_putc matrox_cfb32_putc
+#define matrox_cfb24_putcs matrox_cfb32_putcs
+
+#ifdef FBCON_HAS_VGATEXT
+static struct display_switch matroxfb_text = {
+	matrox_text_setup,    matrox_text_bmove,  matrox_text_clear,
+	matrox_text_putc,     matrox_text_putcs,  matrox_text_revc,
+	matrox_text_cursor,   matrox_text_setfont, NULL,
+	FONTWIDTH(8)|FONTWIDTH(9)
+};
+#endif
+
+#ifdef FBCON_HAS_CFB4
+static struct display_switch matroxfb_cfb4 = {
+	fbcon_cfb4_setup,     matrox_cfb4_bmove,  matrox_cfb4_clear,
+	fbcon_cfb4_putc,      fbcon_cfb4_putcs,	  matrox_cfb4_revc,
+	NULL,		      NULL,		  NULL,
+	/* cursor... */       /* set_font... */
+	FONTWIDTH(8) /* fix, fix, fix it */
+};
+#endif
+
+#ifdef FBCON_HAS_CFB8
+static struct display_switch matroxfb_cfb8 = {
+	fbcon_cfb8_setup,     matrox_cfbX_bmove,  matrox_cfb8_clear,
+	matrox_cfb8_putc,     matrox_cfb8_putcs,  matrox_cfb8_revc,
+	NULL,		      NULL,		  matrox_cfbX_clear_margins,
+	~1 /* FONTWIDTHS */
+};
+#endif
+
+#ifdef FBCON_HAS_CFB16
+static struct display_switch matroxfb_cfb16 = {
+	fbcon_cfb16_setup,    matrox_cfbX_bmove,  matrox_cfb16_clear,
+	matrox_cfb16_putc,    matrox_cfb16_putcs, matrox_cfb16_revc,
+	NULL,		      NULL,		  matrox_cfbX_clear_margins,
+	~1 /* FONTWIDTHS */
+};
+#endif
+
+#ifdef FBCON_HAS_CFB24
+static struct display_switch matroxfb_cfb24 = {
+	fbcon_cfb24_setup,    matrox_cfbX_bmove,  matrox_cfb24_clear,
+	matrox_cfb24_putc,    matrox_cfb24_putcs, matrox_cfb24_revc,
+	NULL,		      NULL,		  matrox_cfbX_clear_margins,
+	~1 /* FONTWIDTHS */ /* TODO: and what about non-aligned access on BE? I think that there are no in my code */
+};
+#endif
+
+#ifdef FBCON_HAS_CFB32
+static struct display_switch matroxfb_cfb32 = {
+	fbcon_cfb32_setup,    matrox_cfbX_bmove,  matrox_cfb32_clear,
+	matrox_cfb32_putc,    matrox_cfb32_putcs, matrox_cfb32_revc,
+	NULL,		      NULL,		  matrox_cfbX_clear_margins,
+	~1 /* FONTWIDTHS */
+};
+#endif
+
+void initMatrox(WPMINFO struct display* p) {
+	struct display_switch *swtmp;
+
+	DBG("initMatrox")
+
+	if (ACCESS_FBINFO(currcon_display) != p)
+		return;
+	if (p->dispsw && p->conp)
+		fb_con.con_cursor(p->conp, CM_ERASE);
+	p->dispsw_data = NULL;
+	if ((p->var.accel_flags & FB_ACCELF_TEXT) != FB_ACCELF_TEXT) {
+		if (p->type == FB_TYPE_TEXT) {
+			swtmp = &matroxfb_text;
+		} else {
+			switch (p->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB4
+			case 4:
+				swtmp = &fbcon_cfb4;
+				break;
+#endif
+#ifdef FBCON_HAS_CFB8
+			case 8:
+				swtmp = &fbcon_cfb8;
+				break;
+#endif
+#ifdef FBCON_HAS_CFB16
+			case 16:
+				p->dispsw_data = &ACCESS_FBINFO(cmap.cfb16);
+				swtmp = &fbcon_cfb16;
+				break;
+#endif
+#ifdef FBCON_HAS_CFB24
+			case 24:
+				p->dispsw_data = &ACCESS_FBINFO(cmap.cfb24);
+				swtmp = &fbcon_cfb24;
+				break;
+#endif
+#ifdef FBCON_HAS_CFB32
+			case 32:
+				p->dispsw_data = &ACCESS_FBINFO(cmap.cfb32);
+				swtmp = &fbcon_cfb32;
+				break;
+#endif
+			default:
+				p->dispsw = &fbcon_dummy;
+				return;
+			}
+		}
+		dprintk(KERN_INFO "matroxfb: acceleration disabled\n");
+	} else if (p->type == FB_TYPE_TEXT) {
+		swtmp = &matroxfb_text;
+	} else {
+		switch (p->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB4
+		case 4:
+			swtmp = &matroxfb_cfb4;
+			break;
+#endif
+#ifdef FBCON_HAS_CFB8
+		case 8:
+			swtmp = &matroxfb_cfb8;
+			break;
+#endif
+#ifdef FBCON_HAS_CFB16
+		case 16:
+			p->dispsw_data = &ACCESS_FBINFO(cmap.cfb16);
+			swtmp = &matroxfb_cfb16;
+			break;
+#endif
+#ifdef FBCON_HAS_CFB24
+		case 24:
+			p->dispsw_data = &ACCESS_FBINFO(cmap.cfb24);
+			swtmp = &matroxfb_cfb24;
+			break;
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			p->dispsw_data = &ACCESS_FBINFO(cmap.cfb32);
+			swtmp = &matroxfb_cfb32;
+			break;
+#endif
+		default:
+			p->dispsw = &fbcon_dummy;
+			return;
+		}
+	}
+	memcpy(&ACCESS_FBINFO(dispsw), swtmp, sizeof(ACCESS_FBINFO(dispsw)));
+	p->dispsw = &ACCESS_FBINFO(dispsw);
+	if ((p->type != FB_TYPE_TEXT) && ACCESS_FBINFO(devflags.hwcursor)) {
+		ACCESS_FBINFO(hw_switch)->selhwcursor(PMINFO p);
+	}
+}
+
+void matrox_init_putc(WPMINFO struct display* p, void (*dac_createcursor)(WPMINFO struct display* p)) {
+	int i;
+
+	if (p && p->conp) {
+		if (p->type == FB_TYPE_TEXT) {
+			matrox_text_createcursor(PMINFO p);
+			matrox_text_loadfont(PMINFO p);
+			i = 0;
+		} else {
+			dac_createcursor(PMINFO p);
+			i = matroxfb_fastfont_tryset(PMINFO p);
+		}
+	} else
+		i = 0;
+	if (i) {
+		ACCESS_FBINFO(curr.putc) = matrox_cfbX_fastputc;
+		ACCESS_FBINFO(curr.putcs) = matrox_cfbX_fastputcs;
+	} else {
+		ACCESS_FBINFO(curr.putc) = matrox_cfbX_putc;
+		ACCESS_FBINFO(curr.putcs) = matrox_cfbX_putcs;
+	}
+}
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_accel.h linux/drivers/video/matrox/matroxfb_accel.h
--- v2.3.47/linux/drivers/video/matrox/matroxfb_accel.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_accel.h	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,12 @@
+#ifndef __MATROXFB_ACCEL_H__
+#define __MATROXFB_ACCEL_H__
+
+#include "matroxfb_base.h"
+
+void matrox_init_putc(WPMINFO struct display* p, void (*)(WPMINFO struct display *p));
+void matrox_cfbX_init(WPMINFO struct display* p);
+void matrox_text_createcursor(WPMINFO struct display* p);
+void matrox_text_round(CPMINFO struct fb_var_screeninfo* var, struct display* p);
+void initMatrox(WPMINFO struct display* p);
+
+#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_base.c linux/drivers/video/matrox/matroxfb_base.c
--- v2.3.47/linux/drivers/video/matrox/matroxfb_base.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_base.c	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,2544 @@
+/*
+ *
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
+ *
+ * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>
+ *
+ * Version: 1.21 1999/01/09
+ *
+ * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
+ *
+ * Contributors: "menion?" <menion@mindless.com>
+ *                     Betatesting, fixes, ideas
+ *
+ *               "Kurt Garloff" <garloff@kg1.ping.de>
+ *                     Betatesting, fixes, ideas, videomodes, videomodes timmings
+ *
+ *               "Tom Rini" <trini@kernel.crashing.org>
+ *                     MTRR stuff, PPC cleanups, betatesting, fixes, ideas
+ *
+ *               "Bibek Sahu" <scorpio@dodds.net>
+ *                     Access device through readb|w|l and write b|w|l
+ *                     Extensive debugging stuff
+ *
+ *               "Daniel Haun" <haund@usa.net>
+ *                     Testing, hardware cursor fixes
+ *
+ *               "Scott Wood" <sawst46+@pitt.edu>
+ *                     Fixes
+ *
+ *               "Gerd Knorr" <kraxel@goldbach.isdn.cs.tu-berlin.de>
+ *                     Betatesting
+ *
+ *               "Kelly French" <targon@hazmat.com>
+ *               "Fernando Herrera" <fherrera@eurielec.etsit.upm.es>
+ *                     Betatesting, bug reporting
+ *
+ *               "Pablo Bianucci" <pbian@pccp.com.ar>
+ *                     Fixes, ideas, betatesting
+ *
+ *               "Inaky Perez Gonzalez" <inaky@peloncho.fis.ucm.es>
+ *                     Fixes, enhandcements, ideas, betatesting
+ *
+ *               "Ryuichi Oikawa" <roikawa@rr.iiij4u.or.jp>
+ *                     PPC betatesting, PPC support, backward compatibility
+ *
+ *               "Paul Womar" <Paul@pwomar.demon.co.uk>
+ *               "Owen Waller" <O.Waller@ee.qub.ac.uk>
+ *                     PPC betatesting
+ *
+ *               "Thomas Pornin" <pornin@bolet.ens.fr>
+ *                     Alpha betatesting
+ *
+ *               "Pieter van Leuven" <pvl@iae.nl>
+ *               "Ulf Jaenicke-Roessler" <ujr@physik.phy.tu-dresden.de>
+ *                     G100 testing
+ *
+ *               "H. Peter Arvin" <hpa@transmeta.com>
+ *                     Ideas
+ *
+ *               "Cort Dougan" <cort@cs.nmt.edu>
+ *                     CHRP fixes and PReP cleanup
+ *
+ *               "Mark Vojkovich" <mvojkovi@ucsd.edu>
+ *                     G400 support
+ *
+ *               "Samuel Hocevar" <sam@via.ecp.fr>
+ *                     Fixes
+ *
+ *               "Anton Altaparmakov" <AntonA@bigfoot.com>
+ *                     G400 MAX/non-MAX distinction
+ *
+ * (following author is not in any relation with this code, but his code
+ *  is included in this driver)
+ *
+ * Based on framebuffer driver for VBE 2.0 compliant graphic boards
+ *     (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
+ *
+ * (following author is not in any relation with this code, but his ideas
+ *  were used when writting this driver)
+ *
+ *		 FreeVBE/AF (Matrox), "Shawn Hargreaves" <shawn@talula.demon.co.uk>
+ *
+ */
+
+/* make checkconfig does not check included files... */
+#include <linux/config.h>
+
+#include "matroxfb_base.h"
+#include "matroxfb_misc.h"
+#include "matroxfb_accel.h"
+#include "matroxfb_DAC1064.h"
+#include "matroxfb_Ti3026.h"
+#include "matroxfb_maven.h"
+#include "matroxfb_crtc2.h"
+#include <linux/matroxfb.h>
+#include <asm/uaccess.h>
+
+#if defined(CONFIG_FB_OF)
+unsigned char nvram_read_byte(int);
+int matrox_of_init(struct device_node *dp);
+static int default_vmode = VMODE_NVRAM;
+static int default_cmode = CMODE_NVRAM;
+#endif
+
+static void matroxfb_unregister_device(struct matrox_fb_info* minfo);
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * card parameters
+ */
+
+/* --------------------------------------------------------------------- */
+
+static struct fb_var_screeninfo vesafb_defined = {
+	640,480,640,480,/* W,H, W, H (virtual) load xres,xres_virtual*/
+	0,0,		/* virtual -> visible no offset */
+	8,		/* depth -> load bits_per_pixel */
+	0,		/* greyscale ? */
+	{0,0,0},	/* R */
+	{0,0,0},	/* G */
+	{0,0,0},	/* B */
+	{0,0,0},	/* transparency */
+	0,		/* standard pixel format */
+	FB_ACTIVATE_NOW,
+	-1,-1,
+	FB_ACCELF_TEXT,	/* accel flags */
+	39721L,48L,16L,33L,10L,
+	96L,2L,~0,	/* No sync info */
+	FB_VMODE_NONINTERLACED,
+	{0,0,0,0,0,0}
+};
+
+
+
+/* --------------------------------------------------------------------- */
+
+static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
+	unsigned int pos;
+	unsigned short p0, p1, p2;
+#ifdef CONFIG_FB_MATROX_32MB
+	unsigned int p3;
+#endif
+	struct display *disp;
+	CRITFLAGS
+
+	DBG("matrox_pan_var")
+
+	if (ACCESS_FBINFO(dead))
+		return;
+
+	disp = ACCESS_FBINFO(currcon_display);
+	if (disp->type == FB_TYPE_TEXT) {
+		pos = var->yoffset / fontheight(disp) * disp->next_line / ACCESS_FBINFO(devflags.textstep) + var->xoffset / (fontwidth(disp)?fontwidth(disp):8);
+	} else {
+		pos = (var->yoffset * var->xres_virtual + var->xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32;
+		pos += ACCESS_FBINFO(curr.ydstorg.chunks);
+	}
+	p0 = ACCESS_FBINFO(currenthw)->CRTC[0x0D] = pos & 0xFF;
+	p1 = ACCESS_FBINFO(currenthw)->CRTC[0x0C] = (pos & 0xFF00) >> 8;
+	p2 = ACCESS_FBINFO(currenthw)->CRTCEXT[0] = (ACCESS_FBINFO(currenthw)->CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
+#ifdef CONFIG_FB_MATROX_32MB
+	p3 = ACCESS_FBINFO(currenthw)->CRTCEXT[8] = pos >> 21;
+#endif
+
+	CRITBEGIN
+
+	mga_setr(M_CRTC_INDEX, 0x0D, p0);
+	mga_setr(M_CRTC_INDEX, 0x0C, p1);
+#ifdef CONFIG_FB_MATROX_32MB
+	if (ACCESS_FBINFO(devflags.support32MB))
+		mga_setr(M_EXTVGA_INDEX, 0x08, p3);
+#endif
+	mga_setr(M_EXTVGA_INDEX, 0x00, p2);
+
+	CRITEND
+}
+
+static void matroxfb_remove(WPMINFO int dummy) {
+	/* Currently we are holding big kernel lock on all dead & usecount updates.
+	 * Destroy everything after all users release it. Especially do not unregister
+	 * framebuffer and iounmap memory, neither fbmem nor fbcon-cfb* does not check
+	 * for device unplugged when in use.
+	 * In future we should point mmio.vbase & video.vbase somewhere where we can
+	 * write data without causing too much damage...
+	 */
+
+	ACCESS_FBINFO(dead) = 1;
+	if (ACCESS_FBINFO(usecount)) {
+		/* destroy it later */
+		return;
+	}
+	matroxfb_unregister_device(MINFO);
+	unregister_framebuffer(&ACCESS_FBINFO(fbcon));
+	del_timer(&ACCESS_FBINFO(cursor.timer));
+#ifdef CONFIG_MTRR
+	if (ACCESS_FBINFO(mtrr.vram_valid))
+		mtrr_del(ACCESS_FBINFO(mtrr.vram), ACCESS_FBINFO(video.base), ACCESS_FBINFO(video.len));
+#endif
+	mga_iounmap(ACCESS_FBINFO(mmio.vbase));
+	mga_iounmap(ACCESS_FBINFO(video.vbase));
+	release_mem_region(ACCESS_FBINFO(video.base), ACCESS_FBINFO(video.len_maximum));
+	release_mem_region(ACCESS_FBINFO(mmio.base), 16384);
+#ifdef CONFIG_FB_MATROX_MULTIHEAD
+	kfree_s(ACCESS_FBINFO(fbcon.disp), sizeof(struct display));
+	kfree_s(minfo, sizeof(struct matrox_fb_info));
+#endif
+}
+
+	/*
+	 * Open/Release the frame buffer device
+	 */
+
+static int matroxfb_open(struct fb_info *info, int user)
+{
+#define minfo ((struct matrox_fb_info*)info)
+	DBG_LOOP("matroxfb_open")
+
+	if (ACCESS_FBINFO(dead)) {
+		return -ENXIO;
+	}
+	MOD_INC_USE_COUNT;
+	ACCESS_FBINFO(usecount)++;
+#undef minfo
+	return(0);
+}
+
+static int matroxfb_release(struct fb_info *info, int user)
+{
+#define minfo ((struct matrox_fb_info*)info)
+	DBG_LOOP("matroxfb_release")
+
+	if (!(--ACCESS_FBINFO(usecount)) && ACCESS_FBINFO(dead)) {
+		matroxfb_remove(PMINFO 0);
+	}
+	MOD_DEC_USE_COUNT;
+#undef minfo
+	return(0);
+}
+
+static int matroxfb_pan_display(struct fb_var_screeninfo *var, int con,
+		struct fb_info* info) {
+#define minfo ((struct matrox_fb_info*)info)
+
+	DBG("matroxfb_pan_display")
+
+	if (var->vmode & FB_VMODE_YWRAP) {
+		if (var->yoffset < 0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset)
+			return -EINVAL;
+	} else {
+		if (var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual ||
+		    var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)
+			return -EINVAL;
+	}
+	if (con == ACCESS_FBINFO(currcon))
+		matrox_pan_var(PMINFO var);
+	fb_display[con].var.xoffset = var->xoffset;
+	fb_display[con].var.yoffset = var->yoffset;
+	if (var->vmode & FB_VMODE_YWRAP)
+		fb_display[con].var.vmode |= FB_VMODE_YWRAP;
+	else
+		fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
+	return 0;
+#undef minfo
+}
+
+static int matroxfb_updatevar(int con, struct fb_info *info)
+{
+#define minfo ((struct matrox_fb_info*)info)
+	DBG("matroxfb_updatevar");
+
+	matrox_pan_var(PMINFO &fb_display[con].var);
+	return 0;
+#undef minfo
+}
+
+static int matroxfb_get_final_bppShift(CPMINFO int bpp) {
+	int bppshft2;
+
+	DBG("matroxfb_get_final_bppShift")
+
+	bppshft2 = bpp;
+	if (!bppshft2) {
+		return 8;
+	}
+	if (isInterleave(MINFO))
+		bppshft2 >>= 1;
+	if (ACCESS_FBINFO(devflags.video64bits))
+		bppshft2 >>= 1;
+	return bppshft2;
+}
+
+static int matroxfb_test_and_set_rounding(CPMINFO int xres, int bpp) {
+	int over;
+	int rounding;
+
+	DBG("matroxfb_test_and_set_rounding")
+
+	switch (bpp) {
+		case 0:		return xres;
+		case 4:		rounding = 128;
+				break;
+		case 8:		rounding = 64;	/* doc says 64; 32 is OK for G400 */
+				break;
+		case 16:	rounding = 32;
+				break;
+		case 24:	rounding = 64;	/* doc says 64; 32 is OK for G400 */
+				break;
+		default:	rounding = 16;
+				/* on G400, 16 really does not work */
+				if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400)
+					rounding = 32;
+				break;
+	}
+	if (isInterleave(MINFO)) {
+		rounding *= 2;
+	}
+	over = xres % rounding;
+	if (over)
+		xres += rounding-over;
+	return xres;
+}
+
+static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) {
+	const int* width;
+	int xres_new;
+
+	DBG("matroxfb_pitch_adjust")
+
+	if (!bpp) return xres;
+
+	width = ACCESS_FBINFO(capable.vxres);
+
+	if (ACCESS_FBINFO(devflags.precise_width)) {
+		while (*width) {
+			if ((*width >= xres) && (matroxfb_test_and_set_rounding(PMINFO *width, bpp) == *width)) {
+				break;
+			}
+			width++;
+		}
+		xres_new = *width;
+	} else {
+		xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp);
+	}
+	if (!xres_new) return 0;
+	if (xres != xres_new) {
+		printk(KERN_INFO "matroxfb: cannot set xres to %d, rounded up to %d\n", xres, xres_new);
+	}
+	return xres_new;
+}
+
+static int matroxfb_get_cmap_len(struct fb_var_screeninfo *var) {
+
+	DBG("matroxfb_get_cmap_len")
+
+	switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_VGATEXT
+		case 0:
+			return 16;	/* pseudocolor... 16 entries HW palette */
+#endif
+#ifdef FBCON_HAS_CFB4
+		case 4:
+			return 16;	/* pseudocolor... 16 entries HW palette */
+#endif
+#ifdef FBCON_HAS_CFB8
+		case 8:
+			return 256;	/* pseudocolor... 256 entries HW palette */
+#endif
+#ifdef FBCON_HAS_CFB16
+		case 16:
+			return 16;	/* directcolor... 16 entries SW palette */
+					/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
+#endif
+#ifdef FBCON_HAS_CFB24
+		case 24:
+			return 16;	/* directcolor... 16 entries SW palette */
+					/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			return 16;	/* directcolor... 16 entries SW palette */
+					/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
+#endif
+	}
+	return 16;	/* return something reasonable... or panic()? */
+}
+
+static int matroxfb_decode_var(CPMINFO struct display* p, struct fb_var_screeninfo *var, int *visual, int *video_cmap_len, unsigned int* ydstorg) {
+	unsigned int vramlen;
+	unsigned int memlen;
+
+	DBG("matroxfb_decode_var")
+
+	switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_VGATEXT
+		case 0:	 if (!ACCESS_FBINFO(capable.text)) return -EINVAL;
+			 break;
+#endif
+#ifdef FBCON_HAS_CFB4
+		case 4:	 if (!ACCESS_FBINFO(capable.cfb4)) return -EINVAL;
+			 break;
+#endif
+#ifdef FBCON_HAS_CFB8
+		case 8:	 break;
+#endif
+#ifdef FBCON_HAS_CFB16
+		case 16: break;
+#endif
+#ifdef FBCON_HAS_CFB24
+		case 24: break;
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32: break;
+#endif
+		default: return -EINVAL;
+	}
+	*ydstorg = 0;
+	vramlen = ACCESS_FBINFO(video.len_usable);
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+	if (var->bits_per_pixel) {
+		var->xres_virtual = matroxfb_pitch_adjust(PMINFO var->xres_virtual, var->bits_per_pixel);
+		memlen = var->xres_virtual * var->bits_per_pixel * var->yres_virtual / 8;
+		if (memlen > vramlen) {
+			var->yres_virtual = vramlen * 8 / (var->xres_virtual * var->bits_per_pixel);
+			memlen = var->xres_virtual * var->bits_per_pixel * var->yres_virtual / 8;
+		}
+		/* There is hardware bug that no line can cross 4MB boundary */
+		/* give up for CFB24, it is impossible to easy workaround it */
+		/* for other try to do something */
+		if (!ACCESS_FBINFO(capable.cross4MB) && (memlen > 0x400000)) {
+			if (var->bits_per_pixel == 24) {
+				/* sorry */
+			} else {
+				unsigned int linelen;
+				unsigned int m1 = linelen = var->xres_virtual * var->bits_per_pixel / 8;
+				unsigned int m2 = PAGE_SIZE;	/* or 128 if you do not need PAGE ALIGNED address */
+				unsigned int max_yres;
+
+				while (m1) {
+					int t;
+
+					while (m2 >= m1) m2 -= m1;
+					t = m1;
+					m1 = m2;
+					m2 = t;
+				}
+				m2 = linelen * PAGE_SIZE / m2;
+				*ydstorg = m2 = 0x400000 % m2;
+				max_yres = (vramlen - m2) / linelen;
+				if (var->yres_virtual > max_yres)
+					var->yres_virtual = max_yres;
+			}
+		}
+	} else {
+		matrox_text_round(PMINFO var, p);
+#if 0
+/* we must limit pixclock by mclk...
+   Millennium I:    66 MHz = 15000
+   Millennium II:   61 MHz = 16300
+   Millennium G200: 83 MHz = 12000 */
+		if (var->pixclock < 15000)
+			var->pixclock = 15000;	/* limit for "normal" gclk & mclk */
+#endif
+	}
+	/* YDSTLEN contains only signed 16bit value */
+	if (var->yres_virtual > 32767)
+		var->yres_virtual = 32767;
+	/* we must round yres/xres down, we already rounded y/xres_virtual up
+	   if it was possible. We should return -EINVAL, but I disagree */
+	if (var->yres_virtual < var->yres)
+		var->yres = var->yres_virtual;
+	if (var->xres_virtual < var->xres)
+		var->xres = var->xres_virtual;
+	if (var->xoffset + var->xres > var->xres_virtual)
+		var->xoffset = var->xres_virtual - var->xres;
+	if (var->yoffset + var->yres > var->yres_virtual)
+		var->yoffset = var->yres_virtual - var->yres;
+
+	if (var->bits_per_pixel == 0) {
+		var->red.offset = 0;
+		var->red.length = 6;
+		var->green.offset = 0;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 6;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		*visual = MX_VISUAL_PSEUDOCOLOR;
+	} else if (var->bits_per_pixel == 4) {
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 0;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		*visual = MX_VISUAL_PSEUDOCOLOR;
+	} else if (var->bits_per_pixel <= 8) {
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 0;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		*visual = MX_VISUAL_PSEUDOCOLOR;
+	} else {
+		if (var->bits_per_pixel <= 16) {
+			if (var->green.length == 5) {
+				var->red.offset    = 10;
+				var->red.length    = 5;
+				var->green.offset  = 5;
+				var->green.length  = 5;
+				var->blue.offset   = 0;
+				var->blue.length   = 5;
+				var->transp.offset = 15;
+				var->transp.length = 1;
+			} else {
+				var->red.offset    = 11;
+				var->red.length    = 5;
+				var->green.offset  = 5;
+				var->green.length  = 6;
+				var->blue.offset   = 0;
+				var->blue.length   = 5;
+				var->transp.offset = 0;
+				var->transp.length = 0;
+			}
+		} else if (var->bits_per_pixel <= 24) {
+			var->red.offset    = 16;
+			var->red.length    = 8;
+			var->green.offset  = 8;
+			var->green.length  = 8;
+			var->blue.offset   = 0;
+			var->blue.length   = 8;
+			var->transp.offset = 0;
+			var->transp.length = 0;
+		} else {
+			var->red.offset    = 16;
+			var->red.length    = 8;
+			var->green.offset  = 8;
+			var->green.length  = 8;
+			var->blue.offset   = 0;
+			var->blue.length   = 8;
+			var->transp.offset = 24;
+			var->transp.length = 8;
+		}
+		dprintk("matroxfb: truecolor: "
+		       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
+		       var->transp.length,
+		       var->red.length,
+		       var->green.length,
+		       var->blue.length,
+		       var->transp.offset,
+		       var->red.offset,
+		       var->green.offset,
+		       var->blue.offset);
+		*visual = MX_VISUAL_DIRECTCOLOR;
+	}
+	*video_cmap_len = matroxfb_get_cmap_len(var);
+	dprintk(KERN_INFO "requested %d*%d/%dbpp (%d*%d)\n", var->xres, var->yres, var->bits_per_pixel,
+				var->xres_virtual, var->yres_virtual);
+	return 0;
+}
+
+static int matrox_setcolreg(unsigned regno, unsigned red, unsigned green,
+			    unsigned blue, unsigned transp,
+			    struct fb_info *fb_info)
+{
+	struct display* p;
+#ifdef CONFIG_FB_MATROX_MULTIHEAD
+	struct matrox_fb_info* minfo = (struct matrox_fb_info*)fb_info;
+#endif
+
+	DBG("matrox_setcolreg")
+
+	/*
+	 *  Set a single color register. The values supplied are
+	 *  already rounded down to the hardware's capabilities
+	 *  (according to the entries in the `var' structure). Return
+	 *  != 0 for invalid regno.
+	 */
+
+	if (regno >= ACCESS_FBINFO(curr.cmap_len))
+		return 1;
+
+	ACCESS_FBINFO(palette[regno].red)   = red;
+	ACCESS_FBINFO(palette[regno].green) = green;
+	ACCESS_FBINFO(palette[regno].blue)  = blue;
+	ACCESS_FBINFO(palette[regno].transp) = transp;
+
+	p = ACCESS_FBINFO(currcon_display);
+	if (p->var.grayscale) {
+		/* gray = 0.30*R + 0.59*G + 0.11*B */
+		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+	}
+
+	red = CNVT_TOHW(red, p->var.red.length);
+	green = CNVT_TOHW(green, p->var.green.length);
+	blue = CNVT_TOHW(blue, p->var.blue.length);
+	transp = CNVT_TOHW(transp, p->var.transp.length);
+
+	switch (p->var.bits_per_pixel) {
+#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB4) || defined(FBCON_HAS_VGATEXT)
+#ifdef FBCON_HAS_VGATEXT
+	case 0:
+#endif
+#ifdef FBCON_HAS_CFB4
+	case 4:
+#endif
+#ifdef FBCON_HAS_CFB8
+	case 8:
+#endif
+		mga_outb(M_DAC_REG, regno);
+		mga_outb(M_DAC_VAL, red);
+		mga_outb(M_DAC_VAL, green);
+		mga_outb(M_DAC_VAL, blue);
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		ACCESS_FBINFO(cmap.cfb16[regno]) =
+			(red << p->var.red.offset)     |
+			(green << p->var.green.offset) |
+			(blue << p->var.blue.offset)   |
+			(transp << p->var.transp.offset); /* for 1:5:5:5 */
+		break;
+#endif
+#ifdef FBCON_HAS_CFB24
+	case 24:
+		ACCESS_FBINFO(cmap.cfb24[regno]) =
+			(red   << p->var.red.offset)   |
+			(green << p->var.green.offset) |
+			(blue  << p->var.blue.offset);
+		break;
+#endif
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		ACCESS_FBINFO(cmap.cfb32[regno]) =
+			(red   << p->var.red.offset)   |
+			(green << p->var.green.offset) |
+			(blue  << p->var.blue.offset)  |
+			(transp << p->var.transp.offset);	/* 8:8:8:8 */
+		break;
+#endif
+	}
+	return 0;
+}
+
+static void do_install_cmap(WPMINFO struct display* dsp)
+{
+	DBG("do_install_cmap")
+
+	if (dsp->cmap.len)
+		fb_set_cmap(&dsp->cmap, 1, matrox_setcolreg, &ACCESS_FBINFO(fbcon));
+	else
+		fb_set_cmap(fb_default_cmap(ACCESS_FBINFO(curr.cmap_len)),
+			    1, matrox_setcolreg, &ACCESS_FBINFO(fbcon));
+}
+
+static int matroxfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info)
+{
+	struct display* p;
+	DBG("matroxfb_get_fix")
+
+#define minfo ((struct matrox_fb_info*)info)
+
+	if (ACCESS_FBINFO(dead)) {
+		return -ENXIO;
+	}
+
+	if (con >= 0)
+		p = fb_display + con;
+	else
+		p = ACCESS_FBINFO(fbcon.disp);
+
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id,"MATROX");
+
+	fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes);
+	fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes);
+	fix->type = p->type;
+	fix->type_aux = p->type_aux;
+	fix->visual = p->visual;
+	fix->xpanstep = 8; /* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */
+	fix->ypanstep = 1;
+	fix->ywrapstep = 0;
+	fix->line_length = p->line_length;
+	fix->mmio_start = ACCESS_FBINFO(mmio.base);
+	fix->mmio_len = ACCESS_FBINFO(mmio.len);
+	fix->accel = ACCESS_FBINFO(devflags.accelerator);
+	return 0;
+#undef minfo
+}
+
+static int matroxfb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
+{
+#define minfo ((struct matrox_fb_info*)info)
+	DBG("matroxfb_get_var")
+
+	if(con < 0)
+		*var=ACCESS_FBINFO(fbcon.disp)->var;
+	else
+		*var=fb_display[con].var;
+	return 0;
+#undef minfo
+}
+
+static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
+{
+#define minfo ((struct matrox_fb_info*)info)
+	int err;
+	int visual;
+	int cmap_len;
+	unsigned int ydstorg;
+	struct display* display;
+	int chgvar;
+
+	DBG("matroxfb_set_var")
+
+	if (ACCESS_FBINFO(dead)) {
+		return -ENXIO;
+	}
+
+	if (con >= 0)
+		display = fb_display + con;
+	else
+		display = ACCESS_FBINFO(fbcon.disp);
+	if ((err = matroxfb_decode_var(PMINFO display, var, &visual, &cmap_len, &ydstorg)) != 0)
+		return err;
+	switch (var->activate & FB_ACTIVATE_MASK) {
+		case FB_ACTIVATE_TEST:	return 0;
+		case FB_ACTIVATE_NXTOPEN:	/* ?? */
+		case FB_ACTIVATE_NOW:	break;	/* continue */
+		default:		return -EINVAL; /* unknown */
+	}
+	if (con >= 0) {
+		chgvar = ((display->var.xres != var->xres) ||
+		    (display->var.yres != var->yres) ||
+                    (display->var.xres_virtual != var->xres_virtual) ||
+		    (display->var.yres_virtual != var->yres_virtual) ||
+		    (display->var.bits_per_pixel != var->bits_per_pixel) ||
+		    memcmp(&display->var.red, &var->red, sizeof(var->red)) ||
+		    memcmp(&display->var.green, &var->green, sizeof(var->green)) ||
+		    memcmp(&display->var.blue, &var->blue, sizeof(var->blue)));
+	} else {
+		chgvar = 0;
+	}
+	display->var = *var;
+	/* cmap */
+	display->screen_base = vaddr_va(ACCESS_FBINFO(video.vbase)) + ydstorg;
+	display->visual = visual;
+	display->ypanstep = 1;
+	display->ywrapstep = 0;
+	if (var->bits_per_pixel) {
+		display->type = FB_TYPE_PACKED_PIXELS;
+		display->type_aux = 0;
+		display->next_line = display->line_length = (var->xres_virtual * var->bits_per_pixel) >> 3;
+	} else {
+		display->type = FB_TYPE_TEXT;
+		display->type_aux = ACCESS_FBINFO(devflags.text_type_aux);
+		display->next_line = display->line_length = (var->xres_virtual / (fontwidth(display)?fontwidth(display):8)) * ACCESS_FBINFO(devflags.textstep);
+	}
+	display->can_soft_blank = 1;
+	display->inverse = ACCESS_FBINFO(devflags.inverse);
+	/* conp, fb_info, vrows, cursor_x, cursor_y, fgcol, bgcol */
+	/* next_plane, fontdata, _font*, userfont */
+	initMatrox(PMINFO display);	/* dispsw */
+	/* dispsw, scrollmode, yscroll */
+	/* fgshift, bgshift, charmask */
+	if (chgvar && info && info->changevar)
+		info->changevar(con);
+	if (con == ACCESS_FBINFO(currcon)) {
+		unsigned int pos;
+
+		ACCESS_FBINFO(curr.cmap_len) = cmap_len;
+		if (display->type == FB_TYPE_TEXT) {
+			/* textmode must be in first megabyte, so no ydstorg allowed */
+			ACCESS_FBINFO(curr.ydstorg.bytes) = 0;
+			ACCESS_FBINFO(curr.ydstorg.chunks) = 0;
+			ACCESS_FBINFO(curr.ydstorg.pixels) = 0;
+		} else {
+			ydstorg += ACCESS_FBINFO(devflags.ydstorg);
+			ACCESS_FBINFO(curr.ydstorg.bytes) = ydstorg;
+			ACCESS_FBINFO(curr.ydstorg.chunks) = ydstorg >> (isInterleave(MINFO)?3:2);
+			if (var->bits_per_pixel == 4)
+				ACCESS_FBINFO(curr.ydstorg.pixels) = ydstorg;
+			else
+				ACCESS_FBINFO(curr.ydstorg.pixels) = (ydstorg * 8) / var->bits_per_pixel;
+		}
+		ACCESS_FBINFO(curr.final_bppShift) = matroxfb_get_final_bppShift(PMINFO var->bits_per_pixel);
+		if (visual == MX_VISUAL_PSEUDOCOLOR) {
+			int i;
+
+			for (i = 0; i < 16; i++) {
+				int j;
+
+				j = color_table[i];
+				ACCESS_FBINFO(palette[i].red)   = default_red[j];
+				ACCESS_FBINFO(palette[i].green) = default_grn[j];
+				ACCESS_FBINFO(palette[i].blue)  = default_blu[j];
+			}
+		}
+
+		{	struct my_timming mt;
+			struct matrox_hw_state* hw;
+			struct matrox_hw_state* ohw;
+
+			matroxfb_var2my(var, &mt);
+			/* CRTC1 delays */
+			switch (var->bits_per_pixel) {
+				case  0:	mt.delay = 31 + 0; break;
+				case 16:	mt.delay = 21 + 8; break;
+				case 24:	mt.delay = 17 + 8; break;
+				case 32:	mt.delay = 16 + 8; break;
+				default:	mt.delay = 31 + 8; break;
+			}
+
+			hw = ACCESS_FBINFO(newhw);
+			ohw = ACCESS_FBINFO(currenthw);
+
+			/* copy last setting... */
+			memcpy(hw, ohw, sizeof(*hw));
+
+			del_timer(&ACCESS_FBINFO(cursor.timer));
+			ACCESS_FBINFO(cursor.state) = CM_ERASE;
+
+			ACCESS_FBINFO(hw_switch->init(PMINFO hw, &mt, display));
+			if (display->type == FB_TYPE_TEXT) {
+				if (fontheight(display))
+					pos = var->yoffset / fontheight(display) * display->next_line / ACCESS_FBINFO(devflags.textstep) + var->xoffset / (fontwidth(display)?fontwidth(display):8);
+				else
+					pos = 0;
+			} else {
+				pos = (var->yoffset * var->xres_virtual + var->xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32;
+				pos += ACCESS_FBINFO(curr.ydstorg.chunks);
+			}
+
+			hw->CRTC[0x0D] = pos & 0xFF;
+			hw->CRTC[0x0C] = (pos & 0xFF00) >> 8;
+			hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
+			hw->CRTCEXT[8] = pos >> 21;
+			if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_PRIMARY) {
+				if (ACCESS_FBINFO(primout))
+					ACCESS_FBINFO(primout)->compute(MINFO, &mt, hw);
+			}
+			if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) {
+				down_read(&ACCESS_FBINFO(altout.lock));
+				if (ACCESS_FBINFO(altout.output))
+					ACCESS_FBINFO(altout.output)->compute(ACCESS_FBINFO(altout.device), &mt, hw);
+				up_read(&ACCESS_FBINFO(altout.lock));
+			}
+			ACCESS_FBINFO(hw_switch->restore(PMINFO hw, ohw, display));
+			if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_PRIMARY) {
+				if (ACCESS_FBINFO(primout))
+					ACCESS_FBINFO(primout)->program(MINFO, hw);
+			}
+			if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) {
+				down_read(&ACCESS_FBINFO(altout.lock));
+				if (ACCESS_FBINFO(altout.output))
+					ACCESS_FBINFO(altout.output)->program(ACCESS_FBINFO(altout.device), hw);
+				up_read(&ACCESS_FBINFO(altout.lock));
+			}
+			ACCESS_FBINFO(cursor.redraw) = 1;
+			ACCESS_FBINFO(currenthw) = hw;
+			ACCESS_FBINFO(newhw) = ohw;
+			if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_PRIMARY) {
+				if (ACCESS_FBINFO(primout))
+					ACCESS_FBINFO(primout)->start(MINFO);
+			}
+			if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) {
+				down_read(&ACCESS_FBINFO(altout.lock));
+				if (ACCESS_FBINFO(altout.output))
+					ACCESS_FBINFO(altout.output)->start(ACCESS_FBINFO(altout.device));
+				up_read(&ACCESS_FBINFO(altout.lock));
+			}
+			matrox_cfbX_init(PMINFO display);
+			do_install_cmap(PMINFO display);
+#if defined(CONFIG_FB_OF) && defined(CONFIG_FB_COMPAT_XPMAC)
+			if (console_fb_info == &ACCESS_FBINFO(fbcon)) {
+				int vmode, cmode;
+
+				display_info.width = var->xres;
+				display_info.height = var->yres;
+				display_info.depth = var->bits_per_pixel;
+				display_info.pitch = (var->xres_virtual)*(var->bits_per_pixel)/8;
+				if (mac_var_to_vmode(var, &vmode, &cmode))
+					display_info.mode = 0;
+				else
+					display_info.mode = vmode;
+				strcpy(display_info.name, ACCESS_FBINFO(matrox_name));
+				display_info.fb_address = ACCESS_FBINFO(video.base);
+				display_info.cmap_adr_address = 0;
+				display_info.cmap_data_address = 0;
+				display_info.disp_reg_address = ACCESS_FBINFO(mmio.base);
+			}
+#endif /* CONFIG_FB_OF && CONFIG_FB_COMPAT_XPMAC */
+		}
+	}
+	return 0;
+#undef minfo
+}
+
+static int matrox_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			    unsigned *blue, unsigned *transp,
+			    struct fb_info *info)
+{
+
+	DBG("matrox_getcolreg")
+
+#define minfo ((struct matrox_fb_info*)info)
+	/*
+	 *  Read a single color register and split it into colors/transparent.
+	 *  Return != 0 for invalid regno.
+	 */
+
+	if (regno >= ACCESS_FBINFO(curr.cmap_len))
+		return 1;
+
+	*red   = ACCESS_FBINFO(palette[regno].red);
+	*green = ACCESS_FBINFO(palette[regno].green);
+	*blue  = ACCESS_FBINFO(palette[regno].blue);
+	*transp = ACCESS_FBINFO(palette[regno].transp);
+	return 0;
+#undef minfo
+}
+
+static int matroxfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     struct fb_info *info)
+{
+#define minfo ((struct matrox_fb_info*)info)
+	struct display* dsp = (con < 0) ? ACCESS_FBINFO(fbcon.disp)
+					: fb_display + con;
+
+	DBG("matroxfb_get_cmap")
+
+	if (ACCESS_FBINFO(dead)) {
+		return -ENXIO;
+	}
+
+	if (con == ACCESS_FBINFO(currcon)) /* current console? */
+		return fb_get_cmap(cmap, kspc, matrox_getcolreg, info);
+	else if (dsp->cmap.len) /* non default colormap? */
+		fb_copy_cmap(&dsp->cmap, cmap, kspc ? 0 : 2);
+	else
+		fb_copy_cmap(fb_default_cmap(matroxfb_get_cmap_len(&dsp->var)),
+			     cmap, kspc ? 0 : 2);
+	return 0;
+#undef minfo
+}
+
+static int matroxfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     struct fb_info *info)
+{
+	unsigned int cmap_len;
+	struct display* dsp = (con < 0) ? info->disp : (fb_display + con);
+#define minfo ((struct matrox_fb_info*)info)
+
+	DBG("matroxfb_set_cmap")
+
+	if (ACCESS_FBINFO(dead)) {
+		return -ENXIO;
+	}
+
+	cmap_len = matroxfb_get_cmap_len(&dsp->var);
+	if (dsp->cmap.len != cmap_len) {
+		int err;
+
+		err = fb_alloc_cmap(&dsp->cmap, cmap_len, 0);
+		if (err)
+			return err;
+	}
+	if (con == ACCESS_FBINFO(currcon)) {			/* current console? */
+		return fb_set_cmap(cmap, kspc, matrox_setcolreg, info);
+	} else
+		fb_copy_cmap(cmap, &dsp->cmap, kspc ? 0 : 1);
+	return 0;
+#undef minfo
+}
+
+static int matroxfb_switch(int con, struct fb_info *info);
+
+static int matroxfb_get_vblank(CPMINFO struct fb_vblank *vblank)
+{
+	unsigned int sts1;
+
+	memset(vblank, 0, sizeof(*vblank));
+	vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC |
+			FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_HBLANK;
+	sts1 = mga_inb(M_INSTS1);
+	vblank->vcount = mga_inl(M_VCOUNT);
+	/* BTW, on my PIII/450 with G400, reading M_INSTS1
+	   byte makes this call about 12% slower (1.70 vs. 2.05 us
+	   per ioctl()) */
+	if (sts1 & 1)
+		vblank->flags |= FB_VBLANK_HBLANKING;
+	if (sts1 & 8)
+		vblank->flags |= FB_VBLANK_VSYNCING;
+	if (vblank->count >= ACCESS_FBINFO(currcon_display)->var.yres)
+		vblank->flags |= FB_VBLANK_VBLANKING;
+	vblank->hcount = 0;
+	vblank->count = 0;
+	return 0;
+}
+
+static int matroxfb_ioctl(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg, int con,
+			  struct fb_info *info)
+{
+#define minfo ((struct matrox_fb_info*)info)
+	DBG("matroxfb_ioctl")
+
+	if (ACCESS_FBINFO(dead)) {
+		return -ENXIO;
+	}
+
+	switch (cmd) {
+		case FBIOGET_VBLANK:
+			{
+				struct fb_vblank vblank;
+				int err;
+
+				err = matroxfb_get_vblank(PMINFO &vblank);
+				if (err)
+					return err;
+				copy_to_user_ret((struct fb_vblank*)arg, &vblank, sizeof(vblank), -EFAULT);
+				return 0;
+			}
+		case MATROXFB_SET_OUTPUT_MODE:
+			{
+				struct matroxioc_output_mode mom;
+				int val;
+
+				copy_from_user_ret(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom), -EFAULT);
+				if (mom.output >= sizeof(u_int32_t))
+					return -EINVAL;
+				switch (mom.output) {
+					case MATROXFB_OUTPUT_PRIMARY:
+						if (mom.mode != MATROXFB_OUTPUT_MODE_MONITOR)
+							return -EINVAL;
+						/* mode did not change... */
+						return 0;
+					case MATROXFB_OUTPUT_SECONDARY:
+						val = -EINVAL;
+						down_read(&ACCESS_FBINFO(altout.lock));
+						if (ACCESS_FBINFO(altout.output) && ACCESS_FBINFO(altout.device))
+							val = ACCESS_FBINFO(altout.output)->setmode(ACCESS_FBINFO(altout.device), mom.mode);
+						up_read(&ACCESS_FBINFO(altout.lock));
+						if (val != 1)
+							return val;
+						if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY)
+							matroxfb_switch(ACCESS_FBINFO(currcon), info);
+						if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
+							struct matroxfb_dh_fb_info* crtc2;
+
+							down_read(&ACCESS_FBINFO(crtc2.lock));
+							crtc2 = (struct matroxfb_dh_fb_info*)(ACCESS_FBINFO(crtc2.info));
+							if (crtc2)
+								crtc2->fbcon.switch_con(crtc2->currcon, &crtc2->fbcon);
+							up_read(&ACCESS_FBINFO(crtc2.lock));
+						}
+						return 0;
+					default:
+						return -EINVAL;
+				}
+				return 0;
+			}
+		case MATROXFB_GET_OUTPUT_MODE:
+			{
+				struct matroxioc_output_mode mom;
+				int val;
+
+				copy_from_user_ret(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom), -EFAULT);
+				if (mom.output >= sizeof(u_int32_t))
+					return -EINVAL;
+				switch (mom.output) {
+					case MATROXFB_OUTPUT_PRIMARY:
+						mom.mode = MATROXFB_OUTPUT_MODE_MONITOR;
+						break;
+					case MATROXFB_OUTPUT_SECONDARY:
+						val = -EINVAL;
+						down_read(&ACCESS_FBINFO(altout.lock));
+						if (ACCESS_FBINFO(altout.output) && ACCESS_FBINFO(altout.device))
+							val = ACCESS_FBINFO(altout.output)->getmode(ACCESS_FBINFO(altout.device), &mom.mode);
+						up_read(&ACCESS_FBINFO(altout.lock));
+						if (val)
+							return val;
+						break;
+					default:
+						return -EINVAL;
+				}
+				copy_to_user_ret((struct matroxioc_output_mode*)arg, &mom, sizeof(mom), -EFAULT);
+				return 0;
+			}
+		case MATROXFB_SET_OUTPUT_CONNECTION:
+			{
+				u_int32_t tmp;
+
+				copy_from_user_ret(&tmp, (u_int32_t*)arg, sizeof(tmp), -EFAULT);
+				if (tmp & ~ACCESS_FBINFO(output.all))
+					return -EINVAL;
+				if (tmp & ACCESS_FBINFO(output.sh))
+					return -EINVAL;
+				if (tmp == ACCESS_FBINFO(output.ph))
+					return 0;
+				ACCESS_FBINFO(output.ph) = tmp;
+				matroxfb_switch(ACCESS_FBINFO(currcon), info);
+				return 0;
+			}
+		case MATROXFB_GET_OUTPUT_CONNECTION:
+			{
+				put_user_ret(ACCESS_FBINFO(output.ph), (u_int32_t*)arg, -EFAULT);
+				return 0;
+			}
+		case MATROXFB_GET_AVAILABLE_OUTPUTS:
+			{
+				u_int32_t tmp;
+
+				tmp = ACCESS_FBINFO(output.all) & ~ACCESS_FBINFO(output.sh);
+				put_user_ret(tmp, (u_int32_t*)arg, -EFAULT);
+				return 0;
+			}
+		case MATROXFB_GET_ALL_OUTPUTS:
+			{
+				put_user_ret(ACCESS_FBINFO(output.all), (u_int32_t*)arg, -EFAULT);
+				return 0;
+			}
+	}
+	return -EINVAL;
+#undef minfo
+}
+
+static struct fb_ops matroxfb_ops = {
+	matroxfb_open,
+	matroxfb_release,
+	matroxfb_get_fix,
+	matroxfb_get_var,
+	matroxfb_set_var,
+	matroxfb_get_cmap,
+	matroxfb_set_cmap,
+	matroxfb_pan_display,
+	matroxfb_ioctl,
+	NULL,			/* mmap */
+	NULL,			/* rasterimg */
+};
+
+static int matroxfb_switch(int con, struct fb_info *info)
+{
+#define minfo ((struct matrox_fb_info*)info)
+	struct fb_cmap* cmap;
+	struct display *p;
+
+	DBG("matroxfb_switch");
+
+	if (ACCESS_FBINFO(currcon) >= 0) {
+		/* Do we have to save the colormap? */
+		cmap = &(ACCESS_FBINFO(currcon_display)->cmap);
+		dprintk(KERN_DEBUG "switch1: con = %d, cmap.len = %d\n", ACCESS_FBINFO(currcon), cmap->len);
+
+		if (cmap->len) {
+			dprintk(KERN_DEBUG "switch1a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp);
+			fb_get_cmap(cmap, 1, matrox_getcolreg, info);
+#ifdef DEBUG
+			if (cmap->red) {
+				dprintk(KERN_DEBUG "switch1r: %X\n", cmap->red[0]);
+			}
+#endif
+		}
+	}
+	ACCESS_FBINFO(currcon) = con;
+	if (con < 0)
+		p = ACCESS_FBINFO(fbcon.disp);
+	else
+		p = fb_display + con;
+	ACCESS_FBINFO(currcon_display) = p;
+	p->var.activate = FB_ACTIVATE_NOW;
+#ifdef DEBUG
+	cmap = &p->cmap;
+	dprintk(KERN_DEBUG "switch2: con = %d, cmap.len = %d\n", con, cmap->len);
+	dprintk(KERN_DEBUG "switch2a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp);
+	if (p->cmap.red) {
+		dprintk(KERN_DEBUG "switch2r: %X\n", cmap->red[0]);
+	}
+#endif
+	matroxfb_set_var(&p->var, con, info);
+#ifdef DEBUG
+	dprintk(KERN_DEBUG "switch3: con = %d, cmap.len = %d\n", con, cmap->len);
+	dprintk(KERN_DEBUG "switch3a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp);
+	if (p->cmap.red) {
+		dprintk(KERN_DEBUG "switch3r: %X\n", cmap->red[0]);
+	}
+#endif
+	return 0;
+#undef minfo
+}
+
+/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
+
+static void matroxfb_blank(int blank, struct fb_info *info)
+{
+#define minfo ((struct matrox_fb_info*)info)
+	int seq;
+	int crtc;
+	CRITFLAGS
+
+	DBG("matroxfb_blank")
+
+	if (ACCESS_FBINFO(dead))
+		return;
+
+	switch (blank) {
+		case 1:  seq = 0x20; crtc = 0x00; break; /* works ??? */
+		case 2:  seq = 0x20; crtc = 0x10; break;
+		case 3:  seq = 0x20; crtc = 0x20; break;
+		case 4:  seq = 0x20; crtc = 0x30; break;
+		default: seq = 0x00; crtc = 0x00; break;
+	}
+
+	CRITBEGIN
+
+	mga_outb(M_SEQ_INDEX, 1);
+	mga_outb(M_SEQ_DATA, (mga_inb(M_SEQ_DATA) & ~0x20) | seq);
+	mga_outb(M_EXTVGA_INDEX, 1);
+	mga_outb(M_EXTVGA_DATA, (mga_inb(M_EXTVGA_DATA) & ~0x30) | crtc);
+
+	CRITEND
+
+#undef minfo
+}
+
+#define RSDepth(X)	(((X) >> 8) & 0x0F)
+#define RS8bpp		0x1
+#define RS15bpp		0x2
+#define RS16bpp		0x3
+#define RS32bpp		0x4
+#define RS4bpp		0x5
+#define RS24bpp		0x6
+#define RSText		0x7
+#define RSText8		0x8
+/* 9-F */
+static struct { struct fb_bitfield red, green, blue, transp; int bits_per_pixel; } colors[] = {
+	{ {  0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, {  0, 0, 0},  8 },
+	{ { 10, 5, 0}, { 5, 5, 0}, { 0, 5, 0}, { 15, 1, 0}, 16 },
+	{ { 11, 5, 0}, { 5, 6, 0}, { 0, 5, 0}, {  0, 0, 0}, 16 },
+	{ { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 24, 8, 0}, 32 },
+	{ {  0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, {  0, 0, 0},  4 },
+	{ { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, {  0, 0, 0}, 24 },
+	{ {  0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, {  0, 0, 0},  0 },	/* textmode with (default) VGA8x16 */
+	{ {  0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, {  0, 0, 0},  0 },	/* textmode hardwired to VGA8x8 */
+};
+
+/* initialized by setup, see explanation at end of file (search for MODULE_PARM_DESC) */
+static unsigned int mem = 0;		/* "matrox:mem:xxxxxM" */
+static int option_precise_width = 1;	/* cannot be changed, option_precise_width==0 must imply noaccel */
+static int inv24 = 0;			/* "matrox:inv24" */
+static int cross4MB = -1;		/* "matrox:cross4MB" */
+static int disabled = 0;		/* "matrox:disabled" */
+static int noaccel = 0;			/* "matrox:noaccel" */
+static int nopan = 0;			/* "matrox:nopan" */
+static int no_pci_retry = 0;		/* "matrox:nopciretry" */
+static int novga = 0;			/* "matrox:novga" */
+static int nobios = 0;			/* "matrox:nobios" */
+static int noinit = 1;			/* "matrox:init" */
+static int inverse = 0;			/* "matrox:inverse" */
+static int hwcursor = 1;		/* "matrox:nohwcursor" */
+static int blink = 1;			/* "matrox:noblink" */
+static int sgram = 0;			/* "matrox:sgram" */
+#ifdef CONFIG_MTRR
+static int mtrr = 1;			/* "matrox:nomtrr" */
+#endif
+static int grayscale = 0;		/* "matrox:grayscale" */
+static unsigned int fastfont = 0;	/* "matrox:fastfont:xxxxx" */
+static int dev = -1;			/* "matrox:dev:xxxxx" */
+static unsigned int vesa = ~0;		/* "matrox:vesa:xxxxx" */
+static int depth = -1;			/* "matrox:depth:xxxxx" */
+static unsigned int xres = 0;		/* "matrox:xres:xxxxx" */
+static unsigned int yres = 0;		/* "matrox:yres:xxxxx" */
+static unsigned int upper = ~0;		/* "matrox:upper:xxxxx" */
+static unsigned int lower = ~0;		/* "matrox:lower:xxxxx" */
+static unsigned int vslen = 0;		/* "matrox:vslen:xxxxx" */
+static unsigned int left = ~0;		/* "matrox:left:xxxxx" */
+static unsigned int right = ~0;		/* "matrox:right:xxxxx" */
+static unsigned int hslen = 0;		/* "matrox:hslen:xxxxx" */
+static unsigned int pixclock = 0;	/* "matrox:pixclock:xxxxx" */
+static int sync = -1;			/* "matrox:sync:xxxxx" */
+static unsigned int fv = 0;		/* "matrox:fv:xxxxx" */
+static unsigned int fh = 0;		/* "matrox:fh:xxxxxk" */
+static unsigned int maxclk = 0;		/* "matrox:maxclk:xxxxM" */
+static char fontname[64];		/* "matrox:font:xxxxx" */
+
+#ifndef MODULE
+static char videomode[64];		/* "matrox:mode:xxxxx" or "matrox:xxxxx" */
+#endif
+
+static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSize){
+	vaddr_t vm;
+	unsigned int offs;
+	unsigned int offs2;
+	unsigned char store;
+	unsigned char bytes[32];
+	unsigned char* tmp;
+
+	DBG("matroxfb_getmemory")
+
+	vm = ACCESS_FBINFO(video.vbase);
+	maxSize &= ~0x1FFFFF;	/* must be X*2MB (really it must be 2 or X*4MB) */
+	/* at least 2MB */
+	if (maxSize < 0x0200000) return 0;
+	if (maxSize > 0x2000000) maxSize = 0x2000000;
+
+	mga_outb(M_EXTVGA_INDEX, 0x03);
+	mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) | 0x80);
+
+	store = mga_readb(vm, 0x1234);
+	tmp = bytes;
+	for (offs = 0x100000; offs < maxSize; offs += 0x200000)
+		*tmp++ = mga_readb(vm, offs);
+	for (offs = 0x100000; offs < maxSize; offs += 0x200000)
+		mga_writeb(vm, offs, 0x02);
+	if (ACCESS_FBINFO(features.accel.has_cacheflush))
+		mga_outb(M_CACHEFLUSH, 0x00);
+	else
+		mga_writeb(vm, 0x1234, 0x99);
+	for (offs = 0x100000; offs < maxSize; offs += 0x200000) {
+		if (mga_readb(vm, offs) != 0x02)
+			break;
+		mga_writeb(vm, offs, mga_readb(vm, offs) - 0x02);
+		if (mga_readb(vm, offs))
+			break;
+	}
+	tmp = bytes;
+	for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000)
+		mga_writeb(vm, offs2, *tmp++);
+	mga_writeb(vm, 0x1234, store);
+
+	mga_outb(M_EXTVGA_INDEX, 0x03);
+	mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) & ~0x80);
+
+	*realSize = offs - 0x100000;
+#ifdef CONFIG_FB_MATROX_MILLENIUM
+	ACCESS_FBINFO(interleave) = !(!isMillenium(MINFO) || ((offs - 0x100000) & 0x3FFFFF));
+#endif
+	return 1;
+}
+
+struct video_board {
+	int maxvram;
+	int maxdisplayable;
+	int accelID;
+	struct matrox_switch* lowlevel;
+		 };
+#ifdef CONFIG_FB_MATROX_MILLENIUM
+static struct video_board vbMillennium		= {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA2064W,	&matrox_millennium};
+static struct video_board vbMillennium2		= {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W,	&matrox_millennium};
+static struct video_board vbMillennium2A	= {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W_AGP,	&matrox_millennium};
+#endif	/* CONFIG_FB_MATROX_MILLENIUM */
+#ifdef CONFIG_FB_MATROX_MYSTIQUE
+static struct video_board vbMystique		= {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA1064SG,	&matrox_mystique};
+#endif	/* CONFIG_FB_MATROX_MYSTIQUE */
+#ifdef CONFIG_FB_MATROX_G100
+static struct video_board vbG100		= {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100,	&matrox_G100};
+static struct video_board vbG200		= {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200,	&matrox_G100};
+#ifdef CONFIG_FB_MATROX_32MB
+/* from doc it looks like that accelerator can draw only to low 16MB :-( Direct accesses & displaying are OK for
+   whole 32MB */
+static struct video_board vbG400		= {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400,	&matrox_G100};
+#else
+static struct video_board vbG400		= {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400,	&matrox_G100};
+#endif
+#endif
+
+#define DEVF_VIDEO64BIT		0x0001
+#define	DEVF_SWAPS		0x0002
+#define DEVF_MILLENNIUM		0x0004
+#define	DEVF_MILLENNIUM2	0x0008
+#define DEVF_CROSS4MB		0x0010
+#define DEVF_TEXT4B		0x0020
+#define DEVF_DDC_8_2		0x0040
+#define DEVF_DMA		0x0080
+#define DEVF_SUPPORT32MB	0x0100
+#define DEVF_ANY_VXRES		0x0200
+#define DEVF_TEXT16B		0x0400
+#define DEVF_CRTC2		0x0800
+#define DEVF_MAVEN_CAPABLE	0x1000
+
+#define DEVF_GCORE	(DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2)
+#define DEVF_G100	(DEVF_GCORE) /* no doc, no vxres... */
+#define DEVF_G200	(DEVF_GCORE | DEVF_ANY_VXRES | DEVF_MAVEN_CAPABLE)
+#define DEVF_G400	(DEVF_GCORE | DEVF_ANY_VXRES | DEVF_MAVEN_CAPABLE | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2)
+
+static struct board {
+	unsigned short vendor, device, rev, svid, sid;
+	unsigned int flags;
+	unsigned int maxclk;
+	struct video_board* base;
+	const char* name;
+		} dev_list[] = {
+#ifdef CONFIG_FB_MATROX_MILLENIUM
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL,	0xFF,
+		0,			0,
+		DEVF_MILLENNIUM | DEVF_TEXT4B,
+		230000,
+		&vbMillennium,
+		"Millennium (PCI)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL_2,	0xFF,
+		0,			0,
+		DEVF_MILLENNIUM | DEVF_MILLENNIUM2 | DEVF_SWAPS,
+		220000,
+		&vbMillennium2,
+		"Millennium II (PCI)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL_2_AGP,	0xFF,
+		0,			0,
+		DEVF_MILLENNIUM | DEVF_MILLENNIUM2 | DEVF_SWAPS,
+		250000,
+		&vbMillennium2A,
+		"Millennium II (AGP)"},
+#endif
+#ifdef CONFIG_FB_MATROX_MYSTIQUE
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MYS,	0x02,
+		0,			0,
+		DEVF_VIDEO64BIT,
+		180000,
+		&vbMystique,
+		"Mystique (PCI)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MYS,	0xFF,
+		0,			0,
+		DEVF_VIDEO64BIT | DEVF_SWAPS,
+		220000,
+		&vbMystique,
+		"Mystique 220 (PCI)"},
+#endif
+#ifdef CONFIG_FB_MATROX_G100
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100,	0xFF,
+		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MGA_G100_PCI,
+		DEVF_G100,
+		230000,
+		&vbG100,
+		"MGA-G100 (PCI)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100,	0xFF,
+		0,			0,
+		DEVF_G100,
+		230000,
+		&vbG100,
+		"unknown G100 (PCI)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
+		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_GENERIC,
+		DEVF_G100,
+		230000,
+		&vbG100,
+		"MGA-G100 (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
+		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MGA_G100_AGP,
+		DEVF_G100,
+		230000,
+		&vbG100,
+		"MGA-G100 (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
+		PCI_SS_VENDOR_ID_SIEMENS_NIXDORF,	PCI_SS_ID_SIEMENS_MGA_G100_AGP,
+		DEVF_G100,
+		230000,
+		&vbG100,
+		"MGA-G100 (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
+		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP,
+		DEVF_G100,
+		230000,
+		&vbG100,
+		"Productiva G100 (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
+		0,			0,
+		DEVF_G100,
+		230000,
+		&vbG100,
+		"unknown G100 (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_PCI,	0xFF,
+		0,			0,
+		DEVF_G200,
+		250000,
+		&vbG200,
+		"unknown G200 (PCI)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
+		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_GENERIC,
+		DEVF_G200,
+		220000,
+		&vbG200,
+		"MGA-G200 (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
+		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MYSTIQUE_G200_AGP,
+		DEVF_G200,
+		230000,
+		&vbG200,
+		"Mystique G200 (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
+		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MILLENIUM_G200_AGP,
+		DEVF_G200,
+		250000,
+		&vbG200,
+		"Millennium G200 (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
+		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MARVEL_G200_AGP,
+		DEVF_G200,
+		230000,
+		&vbG200,
+		"Marvel G200 (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
+		PCI_SS_VENDOR_ID_SIEMENS_NIXDORF,	PCI_SS_ID_SIEMENS_MGA_G200_AGP,
+		DEVF_G200,
+		230000,
+		&vbG200,
+		"MGA-G200 (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
+		0,			0,
+		DEVF_G200,
+		230000,
+		&vbG200,
+		"unknown G200 (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G400_AGP,	0xFF,
+		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MILLENNIUM_G400_MAX_AGP,
+		DEVF_G400,
+		360000,
+		&vbG400,
+		"Millennium G400 MAX (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G400_AGP,	0xFF,
+		0,			0,
+		DEVF_G400,
+		300000,
+		&vbG400,
+		"unknown G400 (AGP)"},
+#endif
+	{0,			0,				0xFF,
+		0,			0,
+		0,
+		0,
+		NULL,
+		NULL}};
+
+#ifndef MODULE
+static struct fb_videomode defaultmode = {
+	/* 640x480 @ 60Hz, 31.5 kHz */
+	NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
+	0, FB_VMODE_NONINTERLACED
+};
+#endif /* !MODULE */
+
+static int hotplug = 0;
+
+static int initMatrox2(WPMINFO struct display* d, struct board* b){
+	unsigned long ctrlptr_phys = 0;
+	unsigned long video_base_phys = 0;
+	unsigned int memsize;
+	struct matrox_hw_state* hw = ACCESS_FBINFO(currenthw);
+	int err;
+
+	DBG("initMatrox2")
+
+	/* set default values... */
+	vesafb_defined.accel_flags = FB_ACCELF_TEXT;
+
+	ACCESS_FBINFO(hw_switch) = b->base->lowlevel;
+	ACCESS_FBINFO(devflags.accelerator) = b->base->accelID;
+	ACCESS_FBINFO(max_pixel_clock) = b->maxclk;
+
+	printk(KERN_INFO "matroxfb: Matrox %s detected\n", b->name);
+	ACCESS_FBINFO(capable.plnwt) = 1;
+	ACCESS_FBINFO(devflags.video64bits) = b->flags & DEVF_VIDEO64BIT;
+	if (b->flags & DEVF_TEXT4B) {
+		ACCESS_FBINFO(devflags.vgastep) = 4;
+		ACCESS_FBINFO(devflags.textmode) = 4;
+		ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP16;
+	} else if (b->flags & DEVF_TEXT16B) {
+		ACCESS_FBINFO(devflags.vgastep) = 16;
+		ACCESS_FBINFO(devflags.textmode) = 1;
+		ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP16;
+	} else {
+		ACCESS_FBINFO(devflags.vgastep) = 8;
+		ACCESS_FBINFO(devflags.textmode) = 1;
+		ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP8;
+	}
+#ifdef CONFIG_FB_MATROX_32MB
+	ACCESS_FBINFO(devflags.support32MB) = b->flags & DEVF_SUPPORT32MB;
+#endif
+	ACCESS_FBINFO(devflags.precise_width) = !(b->flags & DEVF_ANY_VXRES);
+	ACCESS_FBINFO(devflags.crtc2) = b->flags & DEVF_CRTC2;
+	ACCESS_FBINFO(devflags.maven_capable) = b->flags & DEVF_MAVEN_CAPABLE;
+	ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode);
+	ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode);
+
+	if (ACCESS_FBINFO(capable.cross4MB) < 0)
+		ACCESS_FBINFO(capable.cross4MB) = b->flags & DEVF_CROSS4MB;
+	if (b->flags & DEVF_SWAPS) {
+		ctrlptr_phys = ACCESS_FBINFO(pcidev)->resource[1].start;
+		video_base_phys = ACCESS_FBINFO(pcidev)->resource[0].start;
+	} else {
+		ctrlptr_phys = ACCESS_FBINFO(pcidev)->resource[0].start;
+		video_base_phys = ACCESS_FBINFO(pcidev)->resource[1].start;
+	}
+	err = -EINVAL;
+	if (!ctrlptr_phys) {
+		printk(KERN_ERR "matroxfb: control registers are not available, matroxfb disabled\n");
+		goto fail;
+	}
+	if (!video_base_phys) {
+		printk(KERN_ERR "matroxfb: video RAM is not available in PCI address space, matroxfb disabled\n");
+		goto fail;
+	}
+	memsize = b->base->maxvram;
+	if (!request_mem_region(ctrlptr_phys, 16384, "matroxfb MMIO")) {
+		goto fail;
+	}
+	if (!request_mem_region(video_base_phys, memsize, "matroxfb FB")) {
+		goto failCtrlMR;
+	}
+	ACCESS_FBINFO(video.len_maximum) = memsize;
+	/* convert mem (autodetect k, M) */
+	if (mem < 1024) mem *= 1024;
+	if (mem < 0x00100000) mem *= 1024;
+
+	if (mem && (mem < memsize))
+		memsize = mem;
+	err = -ENOMEM;
+	if (mga_ioremap(ctrlptr_phys, 16384, MGA_IOREMAP_MMIO, &ACCESS_FBINFO(mmio.vbase))) {
+		printk(KERN_ERR "matroxfb: cannot ioremap(%lX, 16384), matroxfb disabled\n", ctrlptr_phys);
+		goto failVideoMR;
+	}
+	ACCESS_FBINFO(mmio.base) = ctrlptr_phys;
+	ACCESS_FBINFO(mmio.len) = 16384;
+	ACCESS_FBINFO(video.base) = video_base_phys;
+	if (mga_ioremap(video_base_phys, memsize, MGA_IOREMAP_FB, &ACCESS_FBINFO(video.vbase))) {
+		printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n",
+			video_base_phys, memsize);
+		goto failCtrlIO;
+	}
+	{
+		u_int32_t cmd;
+		u_int32_t mga_option;
+
+		pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, &mga_option);
+		pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd);
+		mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */
+		mga_option |= MX_OPTION_BSWAP;
+                /* disable palette snooping */
+                cmd &= ~PCI_COMMAND_VGA_PALETTE;
+		if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, NULL)) {
+			if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) {
+				printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n");
+			}
+			mga_option |= 0x20000000;
+			ACCESS_FBINFO(devflags.nopciretry) = 1;
+		}
+		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, cmd);
+		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mga_option);
+		hw->MXoptionReg = mga_option;
+
+		/* select non-DMA memory for PCI_MGA_DATA, otherwise dump of PCI cfg space can lock PCI bus */
+		/* maybe preinit() candidate, but it is same... for all devices... at this time... */
+		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MGA_INDEX, 0x00003C00);
+	}
+
+	err = -ENXIO;
+	if (ACCESS_FBINFO(hw_switch)->preinit(PMINFO hw)) {
+		goto failVideoIO;
+	}
+
+	err = -ENOMEM;
+	if (!matroxfb_getmemory(PMINFO memsize, &ACCESS_FBINFO(video.len)) || !ACCESS_FBINFO(video.len)) {
+		printk(KERN_ERR "matroxfb: cannot determine memory size\n");
+		goto failVideoIO;
+	}
+	ACCESS_FBINFO(devflags.ydstorg) = 0;
+
+	ACCESS_FBINFO(currcon) = -1;
+	ACCESS_FBINFO(currcon_display) = d;
+	mga_iounmap(ACCESS_FBINFO(video.vbase));
+	ACCESS_FBINFO(video.base) = video_base_phys;
+	if (mga_ioremap(video_base_phys, ACCESS_FBINFO(video.len), MGA_IOREMAP_FB, &ACCESS_FBINFO(video.vbase))) {
+		printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n",
+			video_base_phys, ACCESS_FBINFO(video.len));
+		goto failCtrlIO;
+	}
+	ACCESS_FBINFO(video.len_usable) = ACCESS_FBINFO(video.len);
+	if (ACCESS_FBINFO(video.len_usable) > b->base->maxdisplayable)
+		ACCESS_FBINFO(video.len_usable) = b->base->maxdisplayable;
+#ifdef CONFIG_MTRR
+	if (mtrr) {
+		ACCESS_FBINFO(mtrr.vram) = mtrr_add(video_base_phys, ACCESS_FBINFO(video.len), MTRR_TYPE_WRCOMB, 1);
+		ACCESS_FBINFO(mtrr.vram_valid) = 1;
+		printk(KERN_INFO "matroxfb: MTRR's turned on\n");
+	}
+#endif	/* CONFIG_MTRR */
+
+	if (!ACCESS_FBINFO(devflags.novga))
+		request_region(0x3C0, 32, "matrox");
+	ACCESS_FBINFO(hw_switch->reset(PMINFO hw));
+
+	ACCESS_FBINFO(fbcon.monspecs.hfmin) = 0;
+	ACCESS_FBINFO(fbcon.monspecs.hfmax) = fh;
+	ACCESS_FBINFO(fbcon.monspecs.vfmin) = 0;
+	ACCESS_FBINFO(fbcon.monspecs.vfmax) = fv;
+	ACCESS_FBINFO(fbcon.monspecs.dpms) = 0;	/* TBD */
+
+	/* static settings */
+	if ((depth == RSText8) && (!*ACCESS_FBINFO(fbcon.fontname))) {
+		strcpy(ACCESS_FBINFO(fbcon.fontname), "VGA8x8");
+	}
+	vesafb_defined.red = colors[depth-1].red;
+	vesafb_defined.green = colors[depth-1].green;
+	vesafb_defined.blue = colors[depth-1].blue;
+	vesafb_defined.bits_per_pixel = colors[depth-1].bits_per_pixel;
+	vesafb_defined.grayscale = grayscale;
+	vesafb_defined.vmode = 0;
+	if (noaccel)
+		vesafb_defined.accel_flags &= ~FB_ACCELF_TEXT;
+
+	strcpy(ACCESS_FBINFO(fbcon.modename), "MATROX VGA");
+	ACCESS_FBINFO(fbcon.changevar) = NULL;
+	ACCESS_FBINFO(fbcon.node) = -1;
+	ACCESS_FBINFO(fbcon.fbops) = &matroxfb_ops;
+	ACCESS_FBINFO(fbcon.disp) = d;
+	ACCESS_FBINFO(fbcon.switch_con) = &matroxfb_switch;
+	ACCESS_FBINFO(fbcon.updatevar) = &matroxfb_updatevar;
+	ACCESS_FBINFO(fbcon.blank) = &matroxfb_blank;
+	/* after __init time we are like module... no logo */
+	ACCESS_FBINFO(fbcon.flags) = hotplug ? FBINFO_FLAG_MODULE : FBINFO_FLAG_DEFAULT;
+	ACCESS_FBINFO(video.len_usable) &= PAGE_MASK;
+
+#ifndef MODULE
+	/* mode database is marked __init!!! */
+	if (!hotplug) {
+		fb_find_mode(&vesafb_defined, &ACCESS_FBINFO(fbcon), videomode[0]?videomode:NULL,
+			NULL, 0, &defaultmode, vesafb_defined.bits_per_pixel);
+	}
+#endif /* !MODULE */
+
+	/* mode modifiers */
+	if (hslen)
+		vesafb_defined.hsync_len = hslen;
+	if (vslen)
+		vesafb_defined.vsync_len = vslen;
+	if (left != ~0)
+		vesafb_defined.left_margin = left;
+	if (right != ~0)
+		vesafb_defined.right_margin = right;
+	if (upper != ~0)
+		vesafb_defined.upper_margin = upper;
+	if (lower != ~0)
+		vesafb_defined.lower_margin = lower;
+	if (xres)
+		vesafb_defined.xres = xres;
+	if (yres)
+		vesafb_defined.yres = yres;
+	if (sync != -1)
+		vesafb_defined.sync = sync;
+	else if (vesafb_defined.sync == ~0) {
+		vesafb_defined.sync = 0;
+		if (yres < 400)
+			vesafb_defined.sync |= FB_SYNC_HOR_HIGH_ACT;
+		else if (yres < 480)
+			vesafb_defined.sync |= FB_SYNC_VERT_HIGH_ACT;
+	}
+
+	/* fv, fh, maxclk limits was specified */
+	{
+		unsigned int tmp;
+
+		if (fv) {
+			tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres
+			          + vesafb_defined.lower_margin + vesafb_defined.vsync_len);
+			if ((tmp < fh) || (fh == 0)) fh = tmp;
+		}
+		if (fh) {
+			tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres
+			          + vesafb_defined.right_margin + vesafb_defined.hsync_len);
+			if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp;
+		}
+		maxclk = (maxclk + 499) / 500;
+		if (maxclk) {
+			tmp = (2000000000 + maxclk) / maxclk;
+			if (tmp > pixclock) pixclock = tmp;
+		}
+	}
+	if (pixclock) {
+		if (pixclock < 2000)		/* > 500MHz */
+			pixclock = 4000;	/* 250MHz */
+		if (pixclock > 1000000)
+			pixclock = 1000000;	/* 1MHz */
+		vesafb_defined.pixclock = pixclock;
+	}
+
+	/* FIXME: Where to move this?! */
+#if defined(CONFIG_FB_OF)
+#if defined(CONFIG_FB_COMPAT_XPMAC)
+	strcpy(ACCESS_FBINFO(matrox_name), "MTRX,");	/* OpenFirmware naming convension */
+	strncat(ACCESS_FBINFO(matrox_name), b->name, 26);
+	if (!console_fb_info)
+		console_fb_info = &ACCESS_FBINFO(fbcon);
+#endif
+	if ((xres <= 640) && (yres <= 480)) {
+		struct fb_var_screeninfo var;
+		if (default_vmode == VMODE_NVRAM) {
+			default_vmode = nvram_read_byte(NV_VMODE);
+			if (default_vmode <= 0 || default_vmode > VMODE_MAX)
+				default_vmode = VMODE_CHOOSE;
+		}
+		if (default_vmode <= 0 || default_vmode > VMODE_MAX)
+			default_vmode = VMODE_640_480_60;
+		if (default_cmode == CMODE_NVRAM)
+			default_cmode = nvram_read_byte(NV_CMODE);
+		if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
+			default_cmode = CMODE_8;
+		if (!mac_vmode_to_var(default_vmode, default_cmode, &var)) {
+			var.accel_flags = vesafb_defined.accel_flags;
+			var.xoffset = var.yoffset = 0;
+			vesafb_defined = var; /* Note: mac_vmode_to_var() doesnot set all parameters */
+		}
+	}
+#endif
+	vesafb_defined.xres_virtual = vesafb_defined.xres;
+	if (nopan) {
+		vesafb_defined.yres_virtual = vesafb_defined.yres;
+	} else {
+		vesafb_defined.yres_virtual = 65536; /* large enough to be INF, but small enough
+							to yres_virtual * xres_virtual < 2^32 */
+	}
+	err = -EINVAL;
+	if (matroxfb_set_var(&vesafb_defined, -2, &ACCESS_FBINFO(fbcon))) {
+		printk(KERN_ERR "matroxfb: cannot set required parameters\n");
+		goto failVideoIO;
+	}
+
+	printk(KERN_INFO "matroxfb: %dx%dx%dbpp (virtual: %dx%d)\n",
+		vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel,
+		vesafb_defined.xres_virtual, vesafb_defined.yres_virtual);
+	printk(KERN_INFO "matroxfb: framebuffer at 0x%lX, mapped to 0x%p, size %d\n",
+		ACCESS_FBINFO(video.base), vaddr_va(ACCESS_FBINFO(video.vbase)), ACCESS_FBINFO(video.len));
+
+/* We do not have to set currcon to 0... register_framebuffer do it for us on first console
+ * and we do not want currcon == 0 for subsequent framebuffers */
+
+	if (register_framebuffer(&ACCESS_FBINFO(fbcon)) < 0) {
+		goto failVideoIO;
+	}
+	printk("fb%d: %s frame buffer device\n",
+	       GET_FB_IDX(ACCESS_FBINFO(fbcon.node)), ACCESS_FBINFO(fbcon.modename));
+	if (ACCESS_FBINFO(currcon) < 0) {
+		/* there is no console on this fb... but we have to initialize hardware
+		 * until someone tells me what is proper thing to do */
+		printk(KERN_INFO "fb%d: initializing hardware\n",
+			GET_FB_IDX(ACCESS_FBINFO(fbcon.node)));
+		matroxfb_set_var(&vesafb_defined, -1, &ACCESS_FBINFO(fbcon));
+	}
+	return 0;
+failVideoIO:;
+	mga_iounmap(ACCESS_FBINFO(video.vbase));
+failCtrlIO:;
+	mga_iounmap(ACCESS_FBINFO(mmio.vbase));
+failVideoMR:;
+	release_mem_region(video_base_phys, ACCESS_FBINFO(video.len_maximum));
+failCtrlMR:;
+	release_mem_region(ctrlptr_phys, 16384);
+fail:;
+	return err;
+}
+
+LIST_HEAD(matroxfb_list);
+LIST_HEAD(matroxfb_driver_list);
+
+#define matroxfb_l(x) list_entry(x, struct matrox_fb_info, next_fb)
+#define matroxfb_driver_l(x) list_entry(x, struct matroxfb_driver, node)
+int matroxfb_register_driver(struct matroxfb_driver* drv) {
+	struct matrox_fb_info* minfo;
+
+	list_add(&drv->node, &matroxfb_driver_list);
+	for (minfo = matroxfb_l(matroxfb_list.next);
+	     minfo != matroxfb_l(&matroxfb_list);
+	     minfo = matroxfb_l(minfo->next_fb.next)) {
+		void* p;
+
+		if (minfo->drivers_count == MATROXFB_MAX_FB_DRIVERS)
+			continue;
+		p = drv->probe(minfo);
+		if (p) {
+			minfo->drivers_data[minfo->drivers_count] = p;
+			minfo->drivers[minfo->drivers_count++] = drv;
+		}
+	}
+	return 0;
+}
+
+void matroxfb_unregister_driver(struct matroxfb_driver* drv) {
+	struct matrox_fb_info* minfo;
+
+	list_del(&drv->node);
+	for (minfo = matroxfb_l(matroxfb_list.next);
+	     minfo != matroxfb_l(&matroxfb_list);
+	     minfo = matroxfb_l(minfo->next_fb.next)) {
+		int i;
+
+		for (i = 0; i < minfo->drivers_count; ) {
+			if (minfo->drivers[i] == drv) {
+				if (drv && drv->remove)
+					drv->remove(minfo, minfo->drivers_data[i]);
+				minfo->drivers[i] = minfo->drivers[--minfo->drivers_count];
+				minfo->drivers_data[i] = minfo->drivers_data[minfo->drivers_count];
+			} else
+				i++;
+		}
+	}
+}
+
+static void matroxfb_register_device(struct matrox_fb_info* minfo) {
+	struct matroxfb_driver* drv;
+	int i = 0;
+	list_add(&ACCESS_FBINFO(next_fb), &matroxfb_list);
+	for (drv = matroxfb_driver_l(matroxfb_driver_list.next);
+	     drv != matroxfb_driver_l(&matroxfb_driver_list);
+	     drv = matroxfb_driver_l(drv->node.next)) {
+		if (drv && drv->probe) {
+			void *p = drv->probe(minfo);
+			if (p) {
+				minfo->drivers_data[i] = p;
+				minfo->drivers[i++] = drv;
+				if (i == MATROXFB_MAX_FB_DRIVERS)
+					break;
+			}
+		}
+	}
+	minfo->drivers_count = i;
+}
+
+static void matroxfb_unregister_device(struct matrox_fb_info* minfo) {
+	int i;
+
+	list_del(&ACCESS_FBINFO(next_fb));
+	for (i = 0; i < minfo->drivers_count; i++) {
+		struct matroxfb_driver* drv = minfo->drivers[i];
+
+		if (drv && drv->remove)
+			drv->remove(minfo, minfo->drivers_data[i]);
+	}
+}
+
+static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dummy) {
+	struct board* b;
+	u_int8_t rev;
+	u_int16_t svid;
+	u_int16_t sid;
+	struct matrox_fb_info* minfo;
+	struct display* d;
+	int err;
+#ifndef CONFIG_FB_MATROX_MULTIHEAD
+	static int registered = 0;
+#endif
+	DBG("matroxfb_probe")
+
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
+	svid = pdev->subsystem_vendor;
+	sid = pdev->subsystem_device;
+	for (b = dev_list; b->vendor; b++) {
+		if ((b->vendor != pdev->vendor) || (b->device != pdev->device) || (b->rev < rev)) continue;
+		if (b->svid)
+			if ((b->svid != svid) || (b->sid != sid)) continue;
+		break;
+	}
+	/* not match... */
+	if (!b->vendor)
+		return -1;
+	if (dev > 0) {
+		/* not requested one... */
+		dev--;
+		return -1;
+	}
+	if (pci_enable_device(pdev)) {
+		return -1;
+	}
+
+#ifdef CONFIG_FB_MATROX_MULTIHEAD
+	minfo = (struct matrox_fb_info*)kmalloc(sizeof(*minfo), GFP_KERNEL);
+	if (!minfo)
+		return -1;
+	d = (struct display*)kmalloc(sizeof(*d), GFP_KERNEL);
+	if (!d) {
+		kfree(minfo);
+		return -1;
+	}
+#else
+	if (registered)	/* singlehead driver... */
+		return -1;
+	minfo = &matroxfb_global_mxinfo;
+	d = &global_disp;
+#endif
+	memset(MINFO, 0, sizeof(*MINFO));
+	memset(d, 0, sizeof(*d));
+
+	ACCESS_FBINFO(currenthw) = &ACCESS_FBINFO(hw1);
+	ACCESS_FBINFO(newhw) = &ACCESS_FBINFO(hw2);
+	ACCESS_FBINFO(pcidev) = pdev;
+	ACCESS_FBINFO(dead) = 0;
+	ACCESS_FBINFO(usecount) = 0;
+	pdev->driver_data = MINFO;
+	/* CMDLINE */
+	memcpy(ACCESS_FBINFO(fbcon.fontname), fontname, sizeof(ACCESS_FBINFO(fbcon.fontname)));
+	/* DEVFLAGS */
+	ACCESS_FBINFO(devflags.inverse) = inverse;
+	ACCESS_FBINFO(devflags.novga) = novga;
+	ACCESS_FBINFO(devflags.nobios) = nobios;
+	ACCESS_FBINFO(devflags.noinit) = noinit;
+	ACCESS_FBINFO(devflags.nopciretry) = no_pci_retry;
+	ACCESS_FBINFO(devflags.mga_24bpp_fix) = inv24;
+	ACCESS_FBINFO(devflags.precise_width) = option_precise_width;
+	ACCESS_FBINFO(devflags.hwcursor) = hwcursor;
+	ACCESS_FBINFO(devflags.blink) = blink;
+	ACCESS_FBINFO(devflags.sgram) = sgram;
+	ACCESS_FBINFO(capable.cross4MB) = cross4MB;
+
+	ACCESS_FBINFO(fastfont.size) = fastfont;
+
+	ACCESS_FBINFO(cursor.state) = CM_ERASE;
+	ACCESS_FBINFO(cursor.timer.prev) = ACCESS_FBINFO(cursor.timer.next) = NULL;
+	ACCESS_FBINFO(cursor.timer.data) = (unsigned long)MINFO;
+	spin_lock_init(&ACCESS_FBINFO(lock.DAC));
+	spin_lock_init(&ACCESS_FBINFO(lock.accel));
+	init_rwsem(&ACCESS_FBINFO(crtc2.lock));
+	init_rwsem(&ACCESS_FBINFO(altout.lock));
+
+	ACCESS_FBINFO(output.all) = MATROXFB_OUTPUT_CONN_PRIMARY;
+	ACCESS_FBINFO(output.ph) = MATROXFB_OUTPUT_CONN_PRIMARY;
+	ACCESS_FBINFO(output.sh) = 0;
+
+	/* subsequent heads always needs initialization and must not enable BIOS */
+	noinit = 0;
+	nobios = 1;
+	novga = 1;
+
+	err = initMatrox2(PMINFO d, b);
+	if (!err) {
+		matroxfb_register_device(MINFO);
+		return 0;
+	}
+#ifdef CONFIG_FB_MATROX_MULTIHEAD
+	kfree(d);
+	kfree(minfo);
+#endif
+	return -1;
+}
+
+static void pci_remove_matrox(struct pci_dev* pdev) {
+	struct matrox_fb_info* minfo;
+
+	minfo = pdev->driver_data;
+	matroxfb_remove(PMINFO 1);
+}
+
+static struct pci_driver matroxfb_driver = {
+	name:	"matroxfb",
+	probe:	matroxfb_probe,
+	remove:	pci_remove_matrox,
+};
+
+/* **************************** init-time only **************************** */
+
+#define RSResolution(X)	((X) & 0x0F)
+#define RS640x400	1
+#define RS640x480	2
+#define RS800x600	3
+#define RS1024x768	4
+#define RS1280x1024	5
+#define RS1600x1200	6
+#define RS768x576	7
+#define RS960x720	8
+#define RS1152x864	9
+#define RS1408x1056	10
+#define RS640x350	11
+#define RS1056x344	12	/* 132 x 43 text */
+#define RS1056x400	13	/* 132 x 50 text */
+#define RS1056x480	14	/* 132 x 60 text */
+#define RSNoxNo		15
+/* 10-FF */
+static struct { int xres, yres, left, right, upper, lower, hslen, vslen, vfreq; } timmings[] __initdata = {
+	{  640,  400,  48, 16, 39,  8,  96, 2, 70 },
+	{  640,  480,  48, 16, 33, 10,  96, 2, 60 },
+	{  800,  600, 144, 24, 28,  8, 112, 6, 60 },
+	{ 1024,  768, 160, 32, 30,  4, 128, 4, 60 },
+	{ 1280, 1024, 224, 32, 32,  4, 136, 4, 60 },
+	{ 1600, 1200, 272, 48, 32,  5, 152, 5, 60 },
+	{  768,  576, 144, 16, 28,  6, 112, 4, 60 },
+	{  960,  720, 144, 24, 28,  8, 112, 4, 60 },
+	{ 1152,  864, 192, 32, 30,  4, 128, 4, 60 },
+	{ 1408, 1056, 256, 40, 32,  5, 144, 5, 60 },
+	{  640,  350,  48, 16, 39,  8,  96, 2, 70 },
+	{ 1056,  344,  96, 24, 59, 44, 160, 2, 70 },
+	{ 1056,  400,  96, 24, 39,  8, 160, 2, 70 },
+	{ 1056,  480,  96, 24, 36, 12, 160, 3, 60 },
+	{    0,    0,  ~0, ~0, ~0, ~0,   0, 0,  0 }
+};
+
+#define RSCreate(X,Y)	((X) | ((Y) << 8))
+static struct { unsigned int vesa; unsigned int info; } *RSptr, vesamap[] __initdata = {
+/* default must be first */
+#ifdef FBCON_HAS_CFB8
+	{    ~0, RSCreate(RSNoxNo,     RS8bpp ) },
+	{ 0x101, RSCreate(RS640x480,   RS8bpp ) },
+	{ 0x100, RSCreate(RS640x400,   RS8bpp ) },
+	{ 0x180, RSCreate(RS768x576,   RS8bpp ) },
+	{ 0x103, RSCreate(RS800x600,   RS8bpp ) },
+	{ 0x188, RSCreate(RS960x720,   RS8bpp ) },
+	{ 0x105, RSCreate(RS1024x768,  RS8bpp ) },
+	{ 0x190, RSCreate(RS1152x864,  RS8bpp ) },
+	{ 0x107, RSCreate(RS1280x1024, RS8bpp ) },
+	{ 0x198, RSCreate(RS1408x1056, RS8bpp ) },
+	{ 0x11C, RSCreate(RS1600x1200, RS8bpp ) },
+#endif
+#ifdef FBCON_HAS_CFB16
+	{    ~0, RSCreate(RSNoxNo,     RS15bpp) },
+	{ 0x110, RSCreate(RS640x480,   RS15bpp) },
+	{ 0x181, RSCreate(RS768x576,   RS15bpp) },
+	{ 0x113, RSCreate(RS800x600,   RS15bpp) },
+	{ 0x189, RSCreate(RS960x720,   RS15bpp) },
+	{ 0x116, RSCreate(RS1024x768,  RS15bpp) },
+	{ 0x191, RSCreate(RS1152x864,  RS15bpp) },
+	{ 0x119, RSCreate(RS1280x1024, RS15bpp) },
+	{ 0x199, RSCreate(RS1408x1056, RS15bpp) },
+	{ 0x11D, RSCreate(RS1600x1200, RS15bpp) },
+	{ 0x111, RSCreate(RS640x480,   RS16bpp) },
+	{ 0x182, RSCreate(RS768x576,   RS16bpp) },
+	{ 0x114, RSCreate(RS800x600,   RS16bpp) },
+	{ 0x18A, RSCreate(RS960x720,   RS16bpp) },
+	{ 0x117, RSCreate(RS1024x768,  RS16bpp) },
+	{ 0x192, RSCreate(RS1152x864,  RS16bpp) },
+	{ 0x11A, RSCreate(RS1280x1024, RS16bpp) },
+	{ 0x19A, RSCreate(RS1408x1056, RS16bpp) },
+	{ 0x11E, RSCreate(RS1600x1200, RS16bpp) },
+#endif
+#ifdef FBCON_HAS_CFB24
+	{    ~0, RSCreate(RSNoxNo,     RS24bpp) },
+	{ 0x1B2, RSCreate(RS640x480,   RS24bpp) },
+	{ 0x184, RSCreate(RS768x576,   RS24bpp) },
+	{ 0x1B5, RSCreate(RS800x600,   RS24bpp) },
+	{ 0x18C, RSCreate(RS960x720,   RS24bpp) },
+	{ 0x1B8, RSCreate(RS1024x768,  RS24bpp) },
+	{ 0x194, RSCreate(RS1152x864,  RS24bpp) },
+	{ 0x1BB, RSCreate(RS1280x1024, RS24bpp) },
+	{ 0x19C, RSCreate(RS1408x1056, RS24bpp) },
+	{ 0x1BF, RSCreate(RS1600x1200, RS24bpp) },
+#endif
+#ifdef FBCON_HAS_CFB32
+	{    ~0, RSCreate(RSNoxNo,     RS32bpp) },
+	{ 0x112, RSCreate(RS640x480,   RS32bpp) },
+	{ 0x183, RSCreate(RS768x576,   RS32bpp) },
+	{ 0x115, RSCreate(RS800x600,   RS32bpp) },
+	{ 0x18B, RSCreate(RS960x720,   RS32bpp) },
+	{ 0x118, RSCreate(RS1024x768,  RS32bpp) },
+	{ 0x193, RSCreate(RS1152x864,  RS32bpp) },
+	{ 0x11B, RSCreate(RS1280x1024, RS32bpp) },
+	{ 0x19B, RSCreate(RS1408x1056, RS32bpp) },
+	{ 0x11F, RSCreate(RS1600x1200, RS32bpp) },
+#endif
+#ifdef FBCON_HAS_VGATEXT
+	{    ~0, RSCreate(RSNoxNo,     RSText ) },
+	{ 0x002, RSCreate(RS640x400,   RSText ) },	/* 80x25 */
+	{ 0x003, RSCreate(RS640x400,   RSText ) },	/* 80x25 */
+	{ 0x007, RSCreate(RS640x400,   RSText ) },	/* 80x25 */
+	{ 0x1C0, RSCreate(RS640x400,   RSText8) },	/* 80x50 */
+	{ 0x108, RSCreate(RS640x480,   RSText8) },	/* 80x60 */
+	{ 0x109, RSCreate(RS1056x400,  RSText ) },	/* 132x25 */
+	{ 0x10A, RSCreate(RS1056x344,  RSText8) },	/* 132x43 */
+	{ 0x10B, RSCreate(RS1056x400,  RSText8) },	/* 132x50 */
+	{ 0x10C, RSCreate(RS1056x480,  RSText8) },	/* 132x60 */
+#endif
+#ifdef FBCON_HAS_CFB4
+	{    ~0, RSCreate(RSNoxNo,     RS4bpp ) },
+	{ 0x010, RSCreate(RS640x350,   RS4bpp ) },
+	{ 0x012, RSCreate(RS640x480,   RS4bpp ) },
+	{ 0x102, RSCreate(RS800x600,   RS4bpp ) },
+	{ 0x104, RSCreate(RS1024x768,  RS4bpp ) },
+	{ 0x106, RSCreate(RS1280x1024, RS4bpp ) },
+#endif
+	{     0, 0				}};
+
+static void __init matroxfb_init_params(void) {
+	/* fh from kHz to Hz */
+	if (fh < 1000)
+		fh *= 1000;	/* 1kHz minimum */
+	/* maxclk */
+	if (maxclk < 1000) maxclk *= 1000;	/* kHz -> Hz, MHz -> kHz */
+	if (maxclk < 1000000) maxclk *= 1000;	/* kHz -> Hz, 1MHz minimum */
+	/* fix VESA number */
+	if (vesa != ~0)
+		vesa &= 0x1DFF;		/* mask out clearscreen, acceleration and so on */
+
+	/* static settings */
+	for (RSptr = vesamap; RSptr->vesa; RSptr++) {
+		if (RSptr->vesa == vesa) break;
+	}
+	if (!RSptr->vesa) {
+		printk(KERN_ERR "Invalid vesa mode 0x%04X\n", vesa);
+		RSptr = vesamap;
+	}
+	{
+		int res = RSResolution(RSptr->info)-1;
+		if (left == ~0)
+			left = timmings[res].left;
+		if (!xres)
+			xres = timmings[res].xres;
+		if (right == ~0)
+			right = timmings[res].right;
+		if (!hslen)
+			hslen = timmings[res].hslen;
+		if (upper == ~0)
+			upper = timmings[res].upper;
+		if (!yres)
+			yres = timmings[res].yres;
+		if (lower == ~0)
+			lower = timmings[res].lower;
+		if (!vslen)
+			vslen = timmings[res].vslen;
+		if (!(fv||fh||maxclk||pixclock))
+			fv = timmings[res].vfreq;
+		if (depth == -1)
+			depth = RSDepth(RSptr->info);
+	}
+}
+
+static void __init matrox_init(void) {
+	matroxfb_init_params();
+	pci_register_driver(&matroxfb_driver);
+	dev = -1;	/* accept all new devices... */
+}
+
+/* **************************** exit-time only **************************** */
+
+static void __exit matrox_done(void) {
+	pci_unregister_driver(&matroxfb_driver);
+}
+
+#ifndef MODULE
+
+/* ************************* init in-kernel code ************************** */
+
+int __init matroxfb_setup(char *options) {
+	char *this_opt;
+
+	DBG("matroxfb_setup")
+
+	fontname[0] = '\0';
+
+	if (!options || !*options)
+		return 0;
+
+	for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
+		if (!*this_opt) continue;
+
+		dprintk("matroxfb_setup: option %s\n", this_opt);
+
+		if (!strncmp(this_opt, "dev:", 4))
+			dev = simple_strtoul(this_opt+4, NULL, 0);
+		else if (!strncmp(this_opt, "depth:", 6)) {
+			switch (simple_strtoul(this_opt+6, NULL, 0)) {
+				case 0: depth = RSText; break;
+				case 4: depth = RS4bpp; break;
+				case 8: depth = RS8bpp; break;
+				case 15:depth = RS15bpp; break;
+				case 16:depth = RS16bpp; break;
+				case 24:depth = RS24bpp; break;
+				case 32:depth = RS32bpp; break;
+				default:
+					printk(KERN_ERR "matroxfb: unsupported color depth\n");
+			}
+		} else if (!strncmp(this_opt, "xres:", 5))
+			xres = simple_strtoul(this_opt+5, NULL, 0);
+		else if (!strncmp(this_opt, "yres:", 5))
+			yres = simple_strtoul(this_opt+5, NULL, 0);
+		else if (!strncmp(this_opt, "vslen:", 6))
+			vslen = simple_strtoul(this_opt+6, NULL, 0);
+		else if (!strncmp(this_opt, "hslen:", 6))
+			hslen = simple_strtoul(this_opt+6, NULL, 0);
+		else if (!strncmp(this_opt, "left:", 5))
+			left = simple_strtoul(this_opt+5, NULL, 0);
+		else if (!strncmp(this_opt, "right:", 6))
+			right = simple_strtoul(this_opt+6, NULL, 0);
+		else if (!strncmp(this_opt, "upper:", 6))
+			upper = simple_strtoul(this_opt+6, NULL, 0);
+		else if (!strncmp(this_opt, "lower:", 6))
+			lower = simple_strtoul(this_opt+6, NULL, 0);
+		else if (!strncmp(this_opt, "pixclock:", 9))
+			pixclock = simple_strtoul(this_opt+9, NULL, 0);
+		else if (!strncmp(this_opt, "sync:", 5))
+			sync = simple_strtoul(this_opt+5, NULL, 0);
+		else if (!strncmp(this_opt, "vesa:", 5))
+			vesa = simple_strtoul(this_opt+5, NULL, 0);
+		else if (!strncmp(this_opt, "font:", 5))
+			strncpy(fontname, this_opt+5, sizeof(fontname)-1);
+		else if (!strncmp(this_opt, "maxclk:", 7))
+			maxclk = simple_strtoul(this_opt+7, NULL, 0);
+		else if (!strncmp(this_opt, "fh:", 3))
+			fh = simple_strtoul(this_opt+3, NULL, 0);
+		else if (!strncmp(this_opt, "fv:", 3))
+			fv = simple_strtoul(this_opt+3, NULL, 0);
+		else if (!strncmp(this_opt, "mem:", 4))
+			mem = simple_strtoul(this_opt+4, NULL, 0);
+		else if (!strncmp(this_opt, "mode:", 5))
+			strncpy(videomode, this_opt+5, sizeof(videomode)-1);
+#ifdef CONFIG_FB_OF
+		else if (!strncmp(this_opt, "vmode:", 6)) {
+			unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
+			if (vmode > 0 && vmode <= VMODE_MAX)
+				default_vmode = vmode;
+		} else if (!strncmp(this_opt, "cmode:", 6)) {
+			unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
+			switch (cmode) {
+				case 0:
+				case 8:
+					default_cmode = CMODE_8;
+					break;
+				case 15:
+				case 16:
+					default_cmode = CMODE_16;
+					break;
+				case 24:
+				case 32:
+					default_cmode = CMODE_32;
+					break;
+			}
+		}
+#endif
+		else if (!strncmp(this_opt, "fastfont:", 9))
+			fastfont = simple_strtoul(this_opt+9, NULL, 0);
+		else if (!strcmp(this_opt, "nofastfont"))	/* fastfont:N and nofastfont (nofastfont = fastfont:0) */
+			fastfont = 0;
+		else if (!strcmp(this_opt, "disabled"))	/* nodisabled does not exist */
+			disabled = 1;
+		else if (!strcmp(this_opt, "enabled"))	/* noenabled does not exist */
+			disabled = 0;
+		else if (!strcmp(this_opt, "sgram"))	/* nosgram == sdram */
+			sgram = 1;
+		else if (!strcmp(this_opt, "sdram"))
+			sgram = 0;
+		else {
+			int value = 1;
+
+			if (!strncmp(this_opt, "no", 2)) {
+				value = 0;
+				this_opt += 2;
+			}
+			if (! strcmp(this_opt, "inverse"))
+				inverse = value;
+			else if (!strcmp(this_opt, "accel"))
+				noaccel = !value;
+			else if (!strcmp(this_opt, "pan"))
+				nopan = !value;
+			else if (!strcmp(this_opt, "pciretry"))
+				no_pci_retry = !value;
+			else if (!strcmp(this_opt, "vga"))
+				novga = !value;
+			else if (!strcmp(this_opt, "bios"))
+				nobios = !value;
+			else if (!strcmp(this_opt, "init"))
+				noinit = !value;
+#ifdef CONFIG_MTRR
+			else if (!strcmp(this_opt, "mtrr"))
+				mtrr = value;
+#endif
+			else if (!strcmp(this_opt, "inv24"))
+				inv24 = value;
+			else if (!strcmp(this_opt, "cross4MB"))
+				cross4MB = value;
+			else if (!strcmp(this_opt, "hwcursor"))
+				hwcursor = value;
+			else if (!strcmp(this_opt, "blink"))
+				blink = value;
+			else if (!strcmp(this_opt, "grayscale"))
+				grayscale = value;
+			else {
+				strncpy(videomode, this_opt, sizeof(videomode)-1);
+			}
+		}
+	}
+	return 0;
+}
+
+static int __init initialized = 0;
+
+int __init matroxfb_init(void)
+{
+	DBG("matroxfb_init")
+
+	if (disabled)
+		return -ENXIO;
+	if (!initialized) {
+		initialized = 1;
+		matrox_init();
+	}
+	/* never return failure, user can hotplug matrox later... */
+	return 0;
+}
+
+#if defined(CONFIG_FB_OF)
+int __init matrox_of_init(struct device_node *dp){
+	DBG("matrox_of_init");
+
+	if (disabled)
+		return -ENXIO;
+	if (!initialized) {
+		initialized = 1;
+		matrox_init();
+	}
+	/* failure? */
+	return 0;
+}
+#endif	/* CONFIG_FB_OF */
+
+#else
+
+/* *************************** init module code **************************** */
+
+MODULE_AUTHOR("(c) 1998,1999 Petr Vandrovec <vandrove@vc.cvut.cz>");
+MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400");
+MODULE_PARM(mem, "i");
+MODULE_PARM_DESC(mem, "Size of available memory in MB, KB or B (2,4,8,12,16MB, default=autodetect)");
+MODULE_PARM(disabled, "i");
+MODULE_PARM_DESC(disabled, "Disabled (0 or 1=disabled) (default=0)");
+MODULE_PARM(noaccel, "i");
+MODULE_PARM_DESC(noaccel, "Do not use accelerating engine (0 or 1=disabled) (default=0)");
+MODULE_PARM(nopan, "i");
+MODULE_PARM_DESC(nopan, "Disable pan on startup (0 or 1=disabled) (default=0)");
+MODULE_PARM(no_pci_retry, "i");
+MODULE_PARM_DESC(no_pci_retry, "PCI retries enabled (0 or 1=disabled) (default=0)");
+MODULE_PARM(novga, "i");
+MODULE_PARM_DESC(novga, "VGA I/O (0x3C0-0x3DF) disabled (0 or 1=disabled) (default=0)");
+MODULE_PARM(nobios, "i");
+MODULE_PARM_DESC(nobios, "Disables ROM BIOS (0 or 1=disabled) (default=do not change BIOS state)");
+MODULE_PARM(noinit, "i");
+MODULE_PARM_DESC(noinit, "Disables W/SG/SD-RAM and bus interface initialization (0 or 1=do not initialize) (default=0)");
+MODULE_PARM(mtrr, "i");
+MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)");
+MODULE_PARM(sgram, "i");
+MODULE_PARM_DESC(sgram, "Indicates that G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
+MODULE_PARM(inv24, "i");
+MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)");
+MODULE_PARM(inverse, "i");
+MODULE_PARM_DESC(inverse, "Inverse (0 or 1) (default=0)");
+#ifdef CONFIG_FB_MATROX_MULTIHEAD
+MODULE_PARM(dev, "i");
+MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=all working)");
+#else
+MODULE_PARM(dev, "i");
+MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=first working)");
+#endif
+MODULE_PARM(vesa, "i");
+MODULE_PARM_DESC(vesa, "Startup videomode (0x000-0x1FF) (default=0x101)");
+MODULE_PARM(xres, "i");
+MODULE_PARM_DESC(xres, "Horizontal resolution (px), overrides xres from vesa (default=vesa)");
+MODULE_PARM(yres, "i");
+MODULE_PARM_DESC(yres, "Vertical resolution (scans), overrides yres from vesa (default=vesa)");
+MODULE_PARM(upper, "i");
+MODULE_PARM_DESC(upper, "Upper blank space (scans), overrides upper from vesa (default=vesa)");
+MODULE_PARM(lower, "i");
+MODULE_PARM_DESC(lower, "Lower blank space (scans), overrides lower from vesa (default=vesa)");
+MODULE_PARM(vslen, "i");
+MODULE_PARM_DESC(vslen, "Vertical sync length (scans), overrides lower from vesa (default=vesa)");
+MODULE_PARM(left, "i");
+MODULE_PARM_DESC(left, "Left blank space (px), overrides left from vesa (default=vesa)");
+MODULE_PARM(right, "i");
+MODULE_PARM_DESC(right, "Right blank space (px), overrides right from vesa (default=vesa)");
+MODULE_PARM(hslen, "i");
+MODULE_PARM_DESC(hslen, "Horizontal sync length (px), overrides hslen from vesa (default=vesa)");
+MODULE_PARM(pixclock, "i");
+MODULE_PARM_DESC(pixclock, "Pixelclock (ns), overrides pixclock from vesa (default=vesa)");
+MODULE_PARM(sync, "i");
+MODULE_PARM_DESC(sync, "Sync polarity, overrides sync from vesa (default=vesa)");
+MODULE_PARM(depth, "i");
+MODULE_PARM_DESC(depth, "Color depth (0=text,8,15,16,24,32) (default=vesa)");
+MODULE_PARM(maxclk, "i");
+MODULE_PARM_DESC(maxclk, "Startup maximal clock, 0-999MHz, 1000-999999kHz, 1000000-INF Hz");
+MODULE_PARM(fh, "i");
+MODULE_PARM_DESC(fh, "Startup horizontal frequency, 0-999kHz, 1000-INF Hz");
+MODULE_PARM(fv, "i");
+MODULE_PARM_DESC(fv, "Startup vertical frequency, 0-INF Hz\n"
+"You should specify \"fv:max_monitor_vsync,fh:max_monitor_hsync,maxclk:max_monitor_dotclock\"\n");
+MODULE_PARM(hwcursor, "i");
+MODULE_PARM_DESC(hwcursor, "Enables hardware cursor (0 or 1) (default=0)");
+MODULE_PARM(blink, "i");
+MODULE_PARM_DESC(blink, "Enables hardware cursor blinking (0 or 1) (default=1)");
+MODULE_PARM(fastfont, "i");
+MODULE_PARM_DESC(fastfont, "Specifies, how much memory should be used for font data (0, 1024-65536 are reasonable) (default=0)");
+MODULE_PARM(grayscale, "i");
+MODULE_PARM_DESC(grayscale, "Sets display into grayscale. Works perfectly with paletized videomode (4, 8bpp), some limitations apply to 16, 24 and 32bpp videomodes (default=nograyscale)");
+MODULE_PARM(cross4MB, "i");
+MODULE_PARM_DESC(cross4MB, "Specifies that 4MB boundary can be in middle of line. (default=autodetected)");
+#ifdef CONFIG_FB_OF
+MODULE_PARM(vmode, "i");
+MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)");
+MODULE_PARM(cmode, "i");
+MODULE_PARM_DESC(cmode, "Specify the video depth that should be used (8bit default)");
+#endif
+
+int __init init_module(void){
+
+	DBG("init_module")
+
+	if (disabled)
+		return -ENXIO;
+
+	if (depth == 0)
+		depth = RSText;
+	else if (depth == 4)
+		depth = RS4bpp;
+	else if (depth == 8)
+		depth = RS8bpp;
+	else if (depth == 15)
+		depth = RS15bpp;
+	else if (depth == 16)
+		depth = RS16bpp;
+	else if (depth == 24)
+		depth = RS24bpp;
+	else if (depth == 32)
+		depth = RS32bpp;
+	else if (depth != -1) {
+		printk(KERN_ERR "matroxfb: depth %d is not supported, using default\n", depth);
+		depth = -1;
+	}
+	matrox_init();
+	/* never return failure; user can hotplug matrox later... */
+	return 0;
+}
+#endif	/* MODULE */
+
+module_exit(matrox_done);
+EXPORT_SYMBOL(matroxfb_register_driver);
+EXPORT_SYMBOL(matroxfb_unregister_driver);
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_base.h linux/drivers/video/matrox/matroxfb_base.h
--- v2.3.47/linux/drivers/video/matrox/matroxfb_base.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_base.h	Thu Feb 24 10:11:24 2000
@@ -0,0 +1,825 @@
+/*
+ *
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
+ *
+ * (c) 1998,1999 Petr Vandrovec <vandrove@vc.cvut.cz>
+ *
+ */
+#ifndef __MATROXFB_H__
+#define __MATROXFB_H__
+
+/* general, but fairly heavy, debugging */
+#undef MATROXFB_DEBUG
+
+/* heavy debugging: */
+/* -- logs putc[s], so everytime a char is displayed, it's logged */
+#undef MATROXFB_DEBUG_HEAVY
+
+/* This one _could_ cause infinite loops */
+/* It _does_ cause lots and lots of messages during idle loops */
+#undef MATROXFB_DEBUG_LOOP
+
+/* Debug register calls, too? */
+#undef MATROXFB_DEBUG_REG
+
+/* Guard accelerator accesses with spin_lock_irqsave... */
+#undef MATROXFB_USE_SPINLOCKS
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/selection.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/unaligned.h>
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+
+#if defined(CONFIG_FB_OF)
+#if defined(CONFIG_FB_COMPAT_XPMAC)
+#include <asm/vc_ioctl.h>
+#endif
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <video/macmodes.h>
+#endif
+
+/* always compile support for 32MB... It cost almost nothing */
+#define CONFIG_FB_MATROX_32MB
+
+#define FBCON_HAS_VGATEXT
+
+#ifdef MATROXFB_DEBUG
+
+#define DEBUG
+#define DBG(x)		printk(KERN_DEBUG "matroxfb: %s\n", (x));
+
+#ifdef MATROXFB_DEBUG_HEAVY
+#define DBG_HEAVY(x)	DBG(x)
+#else /* MATROXFB_DEBUG_HEAVY */
+#define DBG_HEAVY(x)	/* DBG_HEAVY */
+#endif /* MATROXFB_DEBUG_HEAVY */
+
+#ifdef MATROXFB_DEBUG_LOOP
+#define DBG_LOOP(x)	DBG(x)
+#else /* MATROXFB_DEBUG_LOOP */
+#define DBG_LOOP(x)	/* DBG_LOOP */
+#endif /* MATROXFB_DEBUG_LOOP */
+
+#ifdef MATROXFB_DEBUG_REG
+#define DBG_REG(x)	DBG(x)
+#else /* MATROXFB_DEBUG_REG */
+#define DBG_REG(x)	/* DBG_REG */
+#endif /* MATROXFB_DEBUG_REG */
+
+#else /* MATROXFB_DEBUG */
+
+#define DBG(x)		/* DBG */
+#define DBG_HEAVY(x)	/* DBG_HEAVY */
+#define DBG_REG(x)	/* DBG_REG */
+#define DBG_LOOP(x)	/* DBG_LOOP */
+
+#endif /* MATROXFB_DEBUG */
+
+#ifndef __i386__
+#ifndef ioremap_nocache
+#define ioremap_nocache(X,Y) ioremap(X,Y)
+#endif
+#endif
+
+#if defined(__alpha__) || defined(__m68k__)
+#define READx_WORKS
+#define MEMCPYTOIO_WORKS
+#else
+#define READx_FAILS
+/* recheck __ppc__, maybe that __ppc__ needs MEMCPYTOIO_WRITEL */
+/* I benchmarked PII/350MHz with G200... MEMCPY, MEMCPYTOIO and WRITEL are on same speed ( <2% diff) */
+/* so that means that G200 speed (or AGP speed?) is our limit... I do not have benchmark to test, how */
+/* much of PCI bandwidth is used during transfers... */
+#if defined(__i386__)
+#define MEMCPYTOIO_MEMCPY
+#else
+#define MEMCPYTOIO_WRITEL
+#endif
+#endif
+
+#ifdef __sparc__
+#error "Sorry, I have no idea how to do this on sparc... There is mapioaddr... With bus_type parameter..."
+#endif
+
+#if defined(__m68k__)
+#define MAP_BUSTOVIRT
+#else
+#define MAP_IOREMAP
+#endif
+
+#ifdef DEBUG
+#define dprintk(X...)	printk(X)
+#else
+#define dprintk(X...)
+#endif
+
+#ifndef PCI_SS_VENDOR_ID_SIEMENS_NIXDORF
+#define PCI_SS_VENDOR_ID_SIEMENS_NIXDORF	0x110A
+#endif
+#ifndef PCI_SS_VENDOR_ID_MATROX
+#define PCI_SS_VENDOR_ID_MATROX		PCI_VENDOR_ID_MATROX
+#endif
+#ifndef PCI_DEVICE_ID_MATROX_G200_PCI
+#define PCI_DEVICE_ID_MATROX_G200_PCI	0x0520
+#endif
+#ifndef PCI_DEVICE_ID_MATROX_G200_AGP
+#define PCI_DEVICE_ID_MATROX_G200_AGP	0x0521
+#endif
+#ifndef PCI_DEVICE_ID_MATROX_G100
+#define PCI_DEVICE_ID_MATROX_G100	0x1000
+#endif
+#ifndef PCI_DEVICE_ID_MATROX_G100_AGP
+#define PCI_DEVICE_ID_MATROX_G100_AGP	0x1001
+#endif
+#ifndef PCI_DEVICE_ID_MATROX_G400_AGP
+#define PCI_DEVICE_ID_MATROX_G400_AGP	0x0525
+#endif
+
+#ifndef PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP
+#define PCI_SS_ID_MATROX_GENERIC		0xFF00
+#define PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP	0xFF01
+#define PCI_SS_ID_MATROX_MYSTIQUE_G200_AGP	0xFF02
+#define PCI_SS_ID_MATROX_MILLENIUM_G200_AGP	0xFF03
+#define PCI_SS_ID_MATROX_MARVEL_G200_AGP	0xFF04
+#define PCI_SS_ID_MATROX_MGA_G100_PCI		0xFF05
+#define PCI_SS_ID_MATROX_MGA_G100_AGP		0x1001
+#define PCI_SS_ID_MATROX_MILLENNIUM_G400_MAX_AGP	0x2179
+#define PCI_SS_ID_SIEMENS_MGA_G100_AGP		0x001E /* 30 */
+#define PCI_SS_ID_SIEMENS_MGA_G200_AGP		0x0032 /* 50 */
+#endif
+
+#define MX_VISUAL_TRUECOLOR	FB_VISUAL_DIRECTCOLOR
+#define MX_VISUAL_DIRECTCOLOR	FB_VISUAL_TRUECOLOR
+#define MX_VISUAL_PSEUDOCOLOR	FB_VISUAL_PSEUDOCOLOR
+
+#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
+
+/* G100, G200 and Mystique have (almost) same DAC */
+#undef NEED_DAC1064
+#if defined(CONFIG_FB_MATROX_MYSTIQUE) || defined(CONFIG_FB_MATROX_G100)
+#define NEED_DAC1064 1
+#endif
+
+typedef struct {
+	u_int8_t*	vaddr;
+} vaddr_t;
+
+#ifdef READx_WORKS
+static inline unsigned int mga_readb(vaddr_t va, unsigned int offs) {
+	return readb(va.vaddr + offs);
+}
+
+static inline unsigned int mga_readw(vaddr_t va, unsigned int offs) {
+	return readw(va.vaddr + offs);
+}
+
+static inline u_int32_t mga_readl(vaddr_t va, unsigned int offs) {
+	return readl(va.vaddr + offs);
+}
+
+static inline void mga_writeb(vaddr_t va, unsigned int offs, u_int8_t value) {
+	writeb(value, va.vaddr + offs);
+}
+
+static inline void mga_writew(vaddr_t va, unsigned int offs, u_int16_t value) {
+	writew(value, va.vaddr + offs);
+}
+
+static inline void mga_writel(vaddr_t va, unsigned int offs, u_int32_t value) {
+	writel(value, va.vaddr + offs);
+}
+#else
+static inline unsigned int mga_readb(vaddr_t va, unsigned int offs) {
+	return *(volatile u_int8_t*)(va.vaddr + offs);
+}
+
+static inline unsigned int mga_readw(vaddr_t va, unsigned int offs) {
+	return *(volatile u_int16_t*)(va.vaddr + offs);
+}
+
+static inline u_int32_t mga_readl(vaddr_t va, unsigned int offs) {
+	return *(volatile u_int32_t*)(va.vaddr + offs);
+}
+
+static inline void mga_writeb(vaddr_t va, unsigned int offs, u_int8_t value) {
+	*(volatile u_int8_t*)(va.vaddr + offs) = value;
+}
+
+static inline void mga_writew(vaddr_t va, unsigned int offs, u_int16_t value) {
+	*(volatile u_int16_t*)(va.vaddr + offs) = value;
+}
+
+static inline void mga_writel(vaddr_t va, unsigned int offs, u_int32_t value) {
+	*(volatile u_int32_t*)(va.vaddr + offs) = value;
+}
+#endif
+
+static inline void mga_memcpy_toio(vaddr_t va, unsigned int offs, const void* src, int len) {
+#ifdef MEMCPYTOIO_WORKS
+	memcpy_toio(va.vaddr + offs, src, len);
+#elif defined(MEMCPYTOIO_WRITEL)
+#define srcd ((const u_int32_t*)src)
+	if (offs & 3) {
+		while (len >= 4) {
+			mga_writel(va, offs, get_unaligned(srcd++));
+			offs += 4;
+			len -= 4;
+		}
+	} else {
+		while (len >= 4) {
+			mga_writel(va, offs, *srcd++);
+			offs += 4;
+			len -= 4;
+		}
+	}
+#undef srcd
+	if (len) {
+		u_int32_t tmp;
+
+		memcpy(&tmp, src, len);
+		mga_writel(va, offs, tmp);
+	}
+#elif defined(MEMCPYTOIO_MEMCPY)
+	memcpy(va.vaddr + offs, src, len);
+#else
+#error "Sorry, do not know how to write block of data to device"
+#endif
+}
+
+static inline void vaddr_add(vaddr_t* va, unsigned long offs) {
+	va->vaddr += offs;
+}
+
+static inline void* vaddr_va(vaddr_t va) {
+	return va.vaddr;
+}
+
+#define MGA_IOREMAP_NORMAL	0
+#define MGA_IOREMAP_NOCACHE	1
+
+#define MGA_IOREMAP_FB		MGA_IOREMAP_NOCACHE
+#define MGA_IOREMAP_MMIO	MGA_IOREMAP_NOCACHE
+static inline int mga_ioremap(unsigned long phys, unsigned long size, int flags, vaddr_t* virt) {
+#ifdef MAP_IOREMAP
+	if (flags & MGA_IOREMAP_NOCACHE)
+		virt->vaddr = ioremap_nocache(phys, size);
+	else
+		virt->vaddr = ioremap(phys, size);
+#else
+#ifdef MAP_BUSTOVIRT
+	virt->vaddr = bus_to_virt(phys);
+#else
+#error "Your architecture does not have neither ioremap nor bus_to_virt... Giving up"
+#endif
+#endif
+	return (virt->vaddr == 0); /* 0, !0... 0, error_code in future */
+}
+
+static inline void mga_iounmap(vaddr_t va) {
+#ifdef MAP_IOREMAP
+	iounmap(va.vaddr);
+#endif
+}
+
+struct my_timming {
+	unsigned int pixclock;
+	unsigned int HDisplay;
+	unsigned int HSyncStart;
+	unsigned int HSyncEnd;
+	unsigned int HTotal;
+	unsigned int VDisplay;
+	unsigned int VSyncStart;
+	unsigned int VSyncEnd;
+	unsigned int VTotal;
+	unsigned int sync;
+	int	     dblscan;
+	int	     interlaced;
+	unsigned int delay;	/* CRTC delay */
+};
+
+struct matrox_pll_features {
+	unsigned int	vco_freq_min;
+	unsigned int	ref_freq;
+	unsigned int	feed_div_min;
+	unsigned int	feed_div_max;
+	unsigned int	in_div_min;
+	unsigned int	in_div_max;
+	unsigned int	post_shift_max;
+};
+
+struct matroxfb_par
+{
+	unsigned int	final_bppShift;
+	unsigned int	cmap_len;
+	struct {
+		unsigned int bytes;
+		unsigned int pixels;
+		unsigned int chunks;
+		      } ydstorg;
+	void		(*putc)(u_int32_t, u_int32_t, struct display*, int, int, int);
+	void		(*putcs)(u_int32_t, u_int32_t, struct display*, const unsigned short*, int, int, int);
+};
+
+struct matrox_fb_info;
+
+struct matrox_DAC1064_features {
+	u_int8_t	xvrefctrl;
+	u_int8_t	xmiscctrl;
+	unsigned int	cursorimage;
+};
+
+struct matrox_accel_features {
+	int		has_cacheflush;
+};
+
+/* current hardware status */
+struct mavenregs {
+	u_int8_t regs[256];
+	int	 mode;
+	int	 vlines;
+	int	 xtal;
+	int	 fv;
+
+	u_int16_t htotal;
+	u_int16_t hcorr;
+};
+
+struct matrox_hw_state {
+	u_int32_t	MXoptionReg;
+	unsigned char	DACclk[6];
+	unsigned char	DACreg[64];
+	unsigned char	MiscOutReg;
+	unsigned char	DACpal[768];
+	unsigned char	CRTC[25];
+	unsigned char	CRTCEXT[9];
+	unsigned char	SEQ[5];
+	/* unused for MGA mode, but who knows... */
+	unsigned char	GCTL[9];
+	/* unused for MGA mode, but who knows... */
+	unsigned char	ATTR[21];
+
+	/* TVOut only */
+	struct mavenregs	maven;
+
+	/* CRTC2 only */
+	/* u_int32_t	TBD */
+};
+
+struct matrox_accel_data {
+#ifdef CONFIG_FB_MATROX_MILLENIUM
+	unsigned char	ramdac_rev;
+#endif
+	u_int32_t	m_dwg_rect;
+	u_int32_t	m_opmode;
+};
+
+struct matrox_altout {
+	int		(*compute)(void* altout_dev, struct my_timming* input, struct matrox_hw_state* state);
+	int		(*program)(void* altout_dev, const struct matrox_hw_state* state);
+	int		(*start)(void* altout_dev);
+	void		(*incuse)(void* altout_dev);
+	void		(*decuse)(void* altout_dev);
+	int		(*setmode)(void* altout_dev, u_int32_t mode);
+	int		(*getmode)(void* altout_dev, u_int32_t* mode);
+};
+
+struct matrox_switch;
+struct matroxfb_driver;
+
+struct matrox_fb_info {
+	/* fb_info must be first */
+	struct fb_info		fbcon;
+
+	struct list_head	next_fb;
+
+	int			dead;
+	unsigned int		usecount;
+
+	struct matroxfb_par	curr;
+	struct matrox_hw_state	hw1;
+	struct matrox_hw_state	hw2;
+	struct matrox_hw_state*	newhw;
+	struct matrox_hw_state*	currenthw;
+
+	struct matrox_accel_data accel;
+
+	struct pci_dev*		pcidev;
+
+	struct {
+		u_int32_t	all;
+		u_int32_t	ph;
+		u_int32_t	sh;
+			      } output;
+	struct matrox_altout*	primout;
+	struct {
+	struct fb_info*		info;
+	struct rw_semaphore	lock;
+			      } crtc2;
+	struct {
+	struct matrox_altout*	output;
+	void*			device;
+	struct rw_semaphore	lock;
+			      } altout;
+
+#define MATROXFB_MAX_FB_DRIVERS		5
+	struct matroxfb_driver* (drivers[MATROXFB_MAX_FB_DRIVERS]);
+	void*			(drivers_data[MATROXFB_MAX_FB_DRIVERS]);
+	unsigned int		drivers_count;
+
+	struct {
+	unsigned long	base;	/* physical */
+	vaddr_t		vbase;	/* CPU view */
+	unsigned int	len;
+	unsigned int	len_usable;
+	unsigned int	len_maximum;
+		      } video;
+
+	struct {
+	unsigned long	base;	/* physical */
+	vaddr_t		vbase;	/* CPU view */
+	unsigned int	len;
+		      } mmio;
+
+	unsigned int	max_pixel_clock;
+
+	struct matrox_switch*	hw_switch;
+	int		currcon;
+	struct display*	currcon_display;
+
+	struct {
+		struct matrox_pll_features pll;
+		struct matrox_DAC1064_features DAC1064;
+		struct matrox_accel_features accel;
+			      } features;
+	struct {
+		spinlock_t	DAC;
+		spinlock_t	accel;
+			      } lock;
+
+	int			interleave;
+	int			millenium;
+	int			milleniumII;
+	struct {
+		int		cfb4;
+		const int*	vxres;
+		int		cross4MB;
+		int		text;
+		int		plnwt;
+			      } capable;
+	struct {
+		unsigned int	size;
+		unsigned int	mgabase;
+		vaddr_t		vbase;
+			      } fastfont;
+#ifdef CONFIG_MTRR
+	struct {
+		int		vram;
+		int		vram_valid;
+			      } mtrr;
+#endif
+	struct {
+		int		precise_width;
+		int		mga_24bpp_fix;
+		int		novga;
+		int		nobios;
+		int		nopciretry;
+		int		noinit;
+		int		inverse;
+		int		hwcursor;
+		int		blink;
+		int		sgram;
+#ifdef CONFIG_FB_MATROX_32MB
+		int		support32MB;
+#endif
+
+		int		accelerator;
+		int		text_type_aux;
+		int		video64bits;
+		int		crtc2;
+		int		maven_capable;
+		unsigned int	vgastep;
+		unsigned int	textmode;
+		unsigned int	textstep;
+		unsigned int	textvram;	/* character cells */
+		unsigned int	ydstorg;	/* offset in bytes from video start to usable memory */
+						/* 0 except for 6MB Millenium */
+			      } devflags;
+	struct display_switch	dispsw;
+	struct {
+		int		x;
+		int		y;
+		unsigned int	w;
+		unsigned int	u;
+		unsigned int	d;
+		unsigned int	type;
+		int		state;
+		int		redraw;
+		struct timer_list timer;
+			      } cursor;
+	struct { unsigned red, green, blue, transp; } palette[256];
+#if defined(CONFIG_FB_OF) && defined(CONFIG_FB_COMPAT_XPMAC)
+	char	matrox_name[32];
+#endif
+/* These ifdefs must be last! They differ for module & non-module compiles */
+#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
+	union {
+#ifdef FBCON_HAS_CFB16
+		u_int16_t	cfb16[16];
+#endif
+#ifdef FBCON_HAS_CFB24
+		u_int32_t	cfb24[16];
+#endif
+#ifdef FBCON_HAS_CFB32
+		u_int32_t	cfb32[16];
+#endif
+	} cmap;
+#endif
+};
+
+#ifdef CONFIG_FB_MATROX_MULTIHEAD
+#define ACCESS_FBINFO2(info, x) (info->x)
+#define ACCESS_FBINFO(x) ACCESS_FBINFO2(minfo,x)
+
+#define MINFO minfo
+
+#define WPMINFO2 struct matrox_fb_info* minfo
+#define WPMINFO  WPMINFO2 ,
+#define CPMINFO2 const struct matrox_fb_info* minfo
+#define CPMINFO	 CPMINFO2 ,
+#define PMINFO2  minfo
+#define PMINFO   PMINFO2 ,
+
+static inline struct matrox_fb_info* mxinfo(const struct display* p) {
+	return (struct matrox_fb_info*)p->fb_info;
+}
+
+#define PMXINFO(p)	   mxinfo(p),
+#define MINFO_FROM(x)	   struct matrox_fb_info* minfo = x
+#define MINFO_FROM_DISP(x) MINFO_FROM(mxinfo(x))
+
+#else
+
+extern struct matrox_fb_info matroxfb_global_mxinfo;
+struct display global_disp;
+
+#define ACCESS_FBINFO(x) (matroxfb_global_mxinfo.x)
+#define ACCESS_FBINFO2(info, x) (matroxfb_global_mxinfo.x)
+
+#define MINFO (&matroxfb_global_mxinfo)
+
+#define WPMINFO2 void
+#define WPMINFO
+#define CPMINFO2 void
+#define CPMINFO
+#define PMINFO2
+#define PMINFO
+
+#if 0
+static inline struct matrox_fb_info* mxinfo(const struct display* p) {
+	return &matroxfb_global_mxinfo;
+}
+#endif
+
+#define PMXINFO(p)
+#define MINFO_FROM(x)
+#define MINFO_FROM_DISP(x)
+
+#endif
+
+struct matrox_switch {
+	int	(*preinit)(WPMINFO struct matrox_hw_state*);
+	void	(*reset)(WPMINFO struct matrox_hw_state*);
+	int	(*init)(CPMINFO struct matrox_hw_state*, struct my_timming*, struct display*);
+	void	(*restore)(WPMINFO struct matrox_hw_state*, struct matrox_hw_state*, struct display*);
+	int	(*selhwcursor)(WPMINFO struct display*);
+};
+
+struct matroxfb_driver {
+	struct list_head	node;
+	char*			name;
+	void*			(*probe)(struct matrox_fb_info* info);
+	void			(*remove)(struct matrox_fb_info* info, void* data);
+};
+
+int matroxfb_register_driver(struct matroxfb_driver* drv);
+void matroxfb_unregister_driver(struct matroxfb_driver* drv);
+
+#define PCI_OPTION_REG	0x40
+#define PCI_MGA_INDEX	0x44
+#define PCI_MGA_DATA	0x48
+
+#define M_DWGCTL	0x1C00
+#define M_MACCESS	0x1C04
+#define M_CTLWTST	0x1C08
+
+#define M_PLNWT		0x1C1C
+
+#define M_BCOL		0x1C20
+#define M_FCOL		0x1C24
+
+#define M_SGN		0x1C58
+#define M_LEN		0x1C5C
+#define M_AR0		0x1C60
+#define M_AR1		0x1C64
+#define M_AR2		0x1C68
+#define M_AR3		0x1C6C
+#define M_AR4		0x1C70
+#define M_AR5		0x1C74
+#define M_AR6		0x1C78
+
+#define M_CXBNDRY	0x1C80
+#define M_FXBNDRY	0x1C84
+#define M_YDSTLEN	0x1C88
+#define M_PITCH		0x1C8C
+#define M_YDST		0x1C90
+#define M_YDSTORG	0x1C94
+#define M_YTOP		0x1C98
+#define M_YBOT		0x1C9C
+
+/* mystique only */
+#define M_CACHEFLUSH	0x1FFF
+
+#define M_EXEC		0x0100
+
+#define M_DWG_TRAP	0x04
+#define M_DWG_BITBLT	0x08
+#define M_DWG_ILOAD	0x09
+
+#define M_DWG_LINEAR	0x0080
+#define M_DWG_SOLID	0x0800
+#define M_DWG_ARZERO	0x1000
+#define M_DWG_SGNZERO	0x2000
+#define M_DWG_SHIFTZERO	0x4000
+
+#define M_DWG_REPLACE	0x000C0000
+#define M_DWG_REPLACE2	(M_DWG_REPLACE | 0x40)
+#define M_DWG_XOR	0x00060010
+
+#define M_DWG_BFCOL	0x04000000
+#define M_DWG_BMONOWF	0x08000000
+
+#define M_DWG_TRANSC	0x40000000
+
+#define M_FIFOSTATUS	0x1E10
+#define M_STATUS	0x1E14
+
+#define M_IEN		0x1E1C
+
+#define M_VCOUNT	0x1E20
+
+#define M_RESET		0x1E40
+
+#define M_AGP2PLL	0x1E4C
+
+#define M_OPMODE	0x1E54
+#define     M_OPMODE_DMA_GEN_WRITE	0x00
+#define     M_OPMODE_DMA_BLIT		0x04
+#define     M_OPMODE_DMA_VECTOR_WRITE	0x08
+#define     M_OPMODE_DMA_LE		0x0000		/* little endian - no transformation */
+#define     M_OPMODE_DMA_BE_8BPP	0x0000
+#define     M_OPMODE_DMA_BE_16BPP	0x0100
+#define     M_OPMODE_DMA_BE_32BPP	0x0200
+#define     M_OPMODE_DIR_LE		0x000000	/* little endian - no transformation */
+#define     M_OPMODE_DIR_BE_8BPP	0x000000
+#define     M_OPMODE_DIR_BE_16BPP	0x010000
+#define     M_OPMODE_DIR_BE_32BPP	0x020000
+
+#define M_ATTR_INDEX	0x1FC0
+#define M_ATTR_DATA	0x1FC1
+
+#define M_MISC_REG	0x1FC2
+#define M_3C2_RD	0x1FC2
+
+#define M_SEQ_INDEX	0x1FC4
+#define M_SEQ_DATA	0x1FC5
+
+#define M_MISC_REG_READ	0x1FCC
+
+#define M_GRAPHICS_INDEX 0x1FCE
+#define M_GRAPHICS_DATA	0x1FCF
+
+#define M_CRTC_INDEX	0x1FD4
+
+#define M_ATTR_RESET	0x1FDA
+#define M_3DA_WR	0x1FDA
+#define M_INSTS1	0x1FDA
+
+#define M_EXTVGA_INDEX	0x1FDE
+#define M_EXTVGA_DATA	0x1FDF
+
+/* G200 only */
+#define M_SRCORG	0x2CB4
+
+#define M_RAMDAC_BASE	0x3C00
+
+/* fortunately, same on TVP3026 and MGA1064 */
+#define M_DAC_REG	(M_RAMDAC_BASE+0)
+#define M_DAC_VAL	(M_RAMDAC_BASE+1)
+#define M_PALETTE_MASK	(M_RAMDAC_BASE+2)
+
+#define M_X_INDEX	0x00
+#define M_X_DATAREG	0x0A
+
+#define DAC_XGENIOCTRL		0x2A
+#define DAC_XGENIODATA		0x2B
+
+#ifdef __LITTLE_ENDIAN
+#define MX_OPTION_BSWAP		0x00000000
+
+#define M_OPMODE_4BPP	(M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT)
+#define M_OPMODE_8BPP	(M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT)
+#define M_OPMODE_16BPP	(M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT)
+#define M_OPMODE_24BPP	(M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT)
+#define M_OPMODE_32BPP	(M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT)
+#else
+#ifdef __BIG_ENDIAN
+#define MX_OPTION_BSWAP		0x80000000
+
+#define M_OPMODE_4BPP	(M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT)	/* TODO */
+#define M_OPMODE_8BPP	(M_OPMODE_DMA_BE_8BPP  | M_OPMODE_DIR_BE_8BPP  | M_OPMODE_DMA_BLIT)
+#define M_OPMODE_16BPP	(M_OPMODE_DMA_BE_16BPP | M_OPMODE_DIR_BE_16BPP | M_OPMODE_DMA_BLIT)
+#define M_OPMODE_24BPP	(M_OPMODE_DMA_BE_8BPP | M_OPMODE_DIR_BE_8BPP | M_OPMODE_DMA_BLIT)	/* TODO, ?32 */
+#define M_OPMODE_32BPP	(M_OPMODE_DMA_BE_32BPP | M_OPMODE_DIR_BE_32BPP | M_OPMODE_DMA_BLIT)
+#else
+#error "Byte ordering have to be defined. Cannot continue."
+#endif
+#endif
+
+#define mga_inb(addr)	mga_readb(ACCESS_FBINFO(mmio.vbase), (addr))
+#define mga_inl(addr)	mga_readl(ACCESS_FBINFO(mmio.vbase), (addr))
+#define mga_outb(addr,val) mga_writeb(ACCESS_FBINFO(mmio.vbase), (addr), (val))
+#define mga_outw(addr,val) mga_writew(ACCESS_FBINFO(mmio.vbase), (addr), (val))
+#define mga_outl(addr,val) mga_writel(ACCESS_FBINFO(mmio.vbase), (addr), (val))
+#define mga_readr(port,idx) (mga_outb((port),(idx)), mga_inb((port)+1))
+#ifdef __LITTLE_ENDIAN
+#define mga_setr(addr,port,val) mga_outw(addr, ((val)<<8) | (port))
+#else
+#define mga_setr(addr,port,val) do { mga_outb(addr, port); mga_outb((addr)+1, val); } while (0)
+#endif
+
+#ifdef __LITTLE_ENDIAN
+#define mga_fifo(n)	do {} while (mga_inb(M_FIFOSTATUS) < (n))
+#else
+#define mga_fifo(n)	do {} while ((mga_inl(M_FIFOSTATUS) & 0xFF) < (n))
+#endif
+
+#define WaitTillIdle()	do {} while (mga_inl(M_STATUS) & 0x10000)
+
+/* code speedup */
+#ifdef CONFIG_FB_MATROX_MILLENIUM
+#define isInterleave(x)	 (x->interleave)
+#define isMillenium(x)	 (x->millenium)
+#define isMilleniumII(x) (x->milleniumII)
+#else
+#define isInterleave(x)  (0)
+#define isMillenium(x)	 (0)
+#define isMilleniumII(x) (0)
+#endif
+
+#define matroxfb_DAC_lock()                   spin_lock(&ACCESS_FBINFO(lock.DAC))
+#define matroxfb_DAC_unlock()                 spin_unlock(&ACCESS_FBINFO(lock.DAC))
+#define matroxfb_DAC_lock_irqsave(flags)      spin_lock_irqsave(&ACCESS_FBINFO(lock.DAC),flags)
+#define matroxfb_DAC_unlock_irqrestore(flags) spin_unlock_irqrestore(&ACCESS_FBINFO(lock.DAC),flags)
+extern void matroxfb_DAC_out(CPMINFO int reg, int val);
+extern int matroxfb_DAC_in(CPMINFO int reg);
+extern struct list_head matroxfb_list;
+extern void matroxfb_var2my(struct fb_var_screeninfo* fvsi, struct my_timming* mt);
+
+#ifdef MATROXFB_USE_SPINLOCKS
+#define CRITBEGIN  spin_lock_irqsave(&ACCESS_FBINFO(lock.accel), critflags);
+#define CRITEND	   spin_unlock_irqrestore(&ACCESS_FBINFO(lock.accel), critflags);
+#define CRITFLAGS  unsigned long critflags;
+#else
+#define CRITBEGIN
+#define CRITEND
+#define CRITFLAGS
+#endif
+
+#endif	/* __MATROXFB_H__ */
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_crtc2.c linux/drivers/video/matrox/matroxfb_crtc2.c
--- v2.3.47/linux/drivers/video/matrox/matroxfb_crtc2.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_crtc2.c	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,788 @@
+#include "matroxfb_maven.h"
+#include "matroxfb_crtc2.h"
+#include "matroxfb_misc.h"
+#include "matroxfb_DAC1064.h"
+#include <linux/matroxfb.h>
+#include <asm/uaccess.h>
+
+/* **************************************************** */
+
+static int mem = 8192;
+
+MODULE_PARM(mem, "i");
+MODULE_PARM_DESC(mem, "Memory size reserved for dualhead (default=8MB)");
+
+/* **************************************************** */
+
+static int matroxfb_dh_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+		unsigned *blue, unsigned *transp, struct fb_info* info) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	if (regno > 16)
+		return 1;
+	*red = m2info->palette[regno].red;
+	*blue = m2info->palette[regno].blue;
+	*green = m2info->palette[regno].green;
+	*transp = m2info->palette[regno].transp;
+	return 0;
+#undef m2info
+}
+
+static int matroxfb_dh_setcolreg(unsigned regno, unsigned red, unsigned green,
+		unsigned blue, unsigned transp, struct fb_info* info) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	struct display* p;
+
+	if (regno > 16)
+		return 1;
+	m2info->palette[regno].red = red;
+	m2info->palette[regno].blue = blue;
+	m2info->palette[regno].green = green;
+	m2info->palette[regno].transp = transp;
+	p = m2info->currcon_display;
+	if (p->var.grayscale) {
+		/* gray = 0.30*R + 0.59*G + 0.11*B */
+		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+	}
+	red = CNVT_TOHW(red, p->var.red.length);
+	green = CNVT_TOHW(green, p->var.green.length);
+	blue = CNVT_TOHW(blue, p->var.blue.length);
+	transp = CNVT_TOHW(transp, p->var.transp.length);
+
+	switch (p->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB16
+		case 16:
+			m2info->cmap.cfb16[regno] =
+				(red << p->var.red.offset)     |
+				(green << p->var.green.offset) |
+				(blue << p->var.blue.offset)   |
+				(transp << p->var.transp.offset);
+			break;
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			m2info->cmap.cfb32[regno] =
+				(red << p->var.red.offset)     |
+				(green << p->var.green.offset) |
+				(blue << p->var.blue.offset)   |
+				(transp << p->var.transp.offset);
+			break;
+#endif
+	}
+	return 0;
+#undef m2info
+}
+
+static void do_install_cmap(struct matroxfb_dh_fb_info* m2info, struct display* p) {
+	if (p->cmap.len)
+		fb_set_cmap(&p->cmap, 1, matroxfb_dh_setcolreg, &m2info->fbcon);
+	else
+		fb_set_cmap(fb_default_cmap(16), 1, matroxfb_dh_setcolreg, &m2info->fbcon);
+}
+
+static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
+		struct my_timming* mt,
+		struct display* p,
+		int mode,
+		unsigned int pos) {
+	u_int32_t tmp;
+	struct matrox_fb_info* minfo = m2info->primary_dev;
+
+	switch (mode) {
+		case 15:
+			tmp = 0x00200000;
+			break;
+		case 16:
+			tmp = 0x00400000;
+			break;
+/*		case 32: */
+		default:
+			tmp = 0x00800000;
+			break;
+	}
+
+	if (ACCESS_FBINFO(output.sh)) {
+		tmp |= 0x00000001;	/* enable CRTC2 */
+
+		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
+			tmp |= 0x00000002; /* source from VDOCLK */
+			tmp |= 0xC0000000; /* enable vvidrst & hvidrst */
+			/* MGA TVO is our clock source */
+		} else if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {
+			tmp |= 0x00000004; /* source from pixclock */
+			/* PIXPLL is our clock source */
+		}
+
+		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY)
+			tmp |= 0x00100000;	/* connect CRTC2 to DAC */
+	}
+	mga_outl(0x3C10, tmp | 0x10000000);	/* depth and so on... 0x10000000 is VIDRST polarity */
+	mga_outl(0x3C14, ((mt->HDisplay - 8) << 16) | (mt->HTotal - 8));
+	mga_outl(0x3C18, ((mt->HSyncEnd - 8) << 16) | (mt->HSyncStart - 8));
+	mga_outl(0x3C1C, ((mt->VDisplay - 1) << 16) | (mt->VTotal - 1));
+	mga_outl(0x3C20, ((mt->VSyncEnd - 1) << 16) | (mt->VSyncStart - 1));
+	mga_outl(0x3C24, ((mt->VSyncStart) << 16) | (mt->HSyncStart));	/* preload */
+	mga_outl(0x3C28, pos);		/* vmemory start */
+	mga_outl(0x3C40, p->var.xres_virtual * (p->var.bits_per_pixel >> 3));
+	tmp = 0x0FFF0000;		/* line compare */
+	if (mt->sync & FB_SYNC_HOR_HIGH_ACT)
+		tmp |= 0x00000100;
+	if (mt->sync & FB_SYNC_VERT_HIGH_ACT)
+		tmp |= 0x00000200;
+	mga_outl(0x3C44, tmp);
+	mga_outl(0x3C4C, 0);		/* data control */
+}
+
+static void matroxfb_dh_cfbX_init(struct matroxfb_dh_fb_info* m2info,
+		struct display* p) {
+	/* no acceleration for secondary head... */
+}
+
+static void matroxfb_dh_pan_var(struct matroxfb_dh_fb_info* m2info,
+		struct fb_var_screeninfo* var) {
+	unsigned int pos;
+
+#define minfo (m2info->primary_dev)
+	pos = (var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel >> 3;
+	pos += m2info->video.offbase;
+	mga_outl(0x3C28, pos);
+#undef minfo
+}
+
+static int matroxfb_dh_decode_var(struct matroxfb_dh_fb_info* m2info,
+		struct display* p,
+		struct fb_var_screeninfo* var,
+		int *visual,
+		int *video_cmap_len,
+		int *mode) {
+	unsigned int mask;
+	unsigned int memlen;
+	unsigned int vramlen;
+
+	switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_CFB16
+		case 16:	mask = 0x1F;
+				break;
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32:	mask = 0x0F;
+				break;
+#endif
+		default:	return -EINVAL;
+	}
+	vramlen = m2info->video.len_usable;
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+	var->xres_virtual = (var->xres_virtual + mask) & ~mask;
+	if (var->yres_virtual > 32767)
+		return -EINVAL;
+	memlen = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel >> 3);
+	if (memlen > vramlen)
+		return -EINVAL;
+	if (var->xoffset + var->xres > var->xres_virtual)
+		var->xoffset = var->xres_virtual - var->xres;
+	if (var->yoffset + var->yres > var->yres_virtual)
+		var->yoffset = var->yres_virtual - var->yres;
+
+	var->xres &= ~7;
+	var->left_margin &= ~7;
+	var->right_margin &= ~7;
+	var->hsync_len &= ~7;
+
+	*mode = var->bits_per_pixel;
+	if (var->bits_per_pixel == 16) {
+		if (var->green.length == 5) {
+			var->red.offset = 10;
+			var->red.length = 5;
+			var->green.offset = 5;
+			var->green.length = 5;
+			var->blue.offset = 0;
+			var->blue.length = 5;
+			var->transp.offset = 15;
+			var->transp.length = 1;
+			*mode = 15;
+		} else {
+			var->red.offset = 11;
+			var->red.length = 5;
+			var->green.offset = 5;
+			var->green.length = 6;
+			var->blue.offset = 0;
+			var->blue.length = 5;
+			var->transp.offset = 0;
+			var->transp.length = 0;
+		}
+	} else {
+			var->red.offset = 16;
+			var->red.length = 8;
+			var->green.offset = 8;
+			var->green.length = 8;
+			var->blue.offset = 0;
+			var->blue.length = 8;
+			var->transp.offset = 24;
+			var->transp.length = 8;
+	}
+	*visual = FB_VISUAL_TRUECOLOR;
+	*video_cmap_len = 16;
+	return 0;
+}
+
+static void initMatroxDH(struct matroxfb_dh_fb_info* m2info, struct display* p) {
+	switch (p->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB16
+		case 16:
+			p->dispsw_data = m2info->cmap.cfb16;
+			p->dispsw = &fbcon_cfb16;
+			break;
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			p->dispsw_data = m2info->cmap.cfb32;
+			p->dispsw = &fbcon_cfb32;
+			break;
+#endif
+		default:
+			p->dispsw_data = NULL;
+			p->dispsw = &fbcon_dummy;
+			break;
+	}
+}
+
+static int matroxfb_dh_open(struct fb_info* info, int user) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	struct matrox_fb_info* minfo = m2info->primary_dev;
+	MOD_INC_USE_COUNT;
+
+	if (minfo) {
+		if (ACCESS_FBINFO(dead)) {
+			return -ENXIO;
+		}
+	}
+	return 0;
+#undef m2info
+}
+
+static int matroxfb_dh_release(struct fb_info* info, int user) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	struct matrox_fb_info* minfo = m2info->primary_dev;
+
+	if (minfo) {
+	}
+	MOD_DEC_USE_COUNT;
+	return 0;
+#undef m2info
+}
+
+static int matroxfb_dh_get_fix(struct fb_fix_screeninfo* fix, int con,
+		struct fb_info* info) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	struct display* p;
+
+	if (con >= 0)
+		p = fb_display + con;
+	else
+		p = m2info->fbcon.disp;
+
+	memset(fix, 0, sizeof(*fix));
+	strcpy(fix->id, "MATROX DH");
+
+	fix->smem_start = m2info->video.base;
+	fix->smem_len = m2info->video.len_usable;
+	fix->type = p->type;
+	fix->type_aux = p->type_aux;
+	fix->visual = p->visual;
+	fix->xpanstep = 8;	/* TBD */
+	fix->ypanstep = 1;
+	fix->ywrapstep = 0;
+	fix->line_length = p->line_length;
+	fix->mmio_start = m2info->mmio.base;
+	fix->mmio_len = m2info->mmio.len;
+	fix->accel = 0;		/* no accel... */
+	return 0;
+#undef m2info
+}
+
+static int matroxfb_dh_get_var(struct fb_var_screeninfo* var, int con,
+		struct fb_info* info) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	if (con < 0)
+		*var = m2info->fbcon.disp->var;
+	else
+		*var = fb_display[con].var;
+	return 0;
+#undef m2info
+}
+
+static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con,
+		struct fb_info* info) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	struct display* p;
+	int chgvar;
+	int visual;
+	int cmap_len;
+	int mode;
+	int err;
+	struct matrox_fb_info* minfo = m2info->primary_dev;
+
+	if (con < 0)
+		p = m2info->fbcon.disp;
+	else
+		p = fb_display + con;
+	if ((err = matroxfb_dh_decode_var(m2info, p, var, &visual, &cmap_len, &mode)) != 0)
+		return err;
+	switch (var->activate & FB_ACTIVATE_MASK) {
+		case FB_ACTIVATE_TEST:	return 0;
+		case FB_ACTIVATE_NXTOPEN:
+		case FB_ACTIVATE_NOW:	break;
+		default:		return -EINVAL;
+	}
+	if (con >= 0) {
+		chgvar = (p->var.xres != var->xres) ||
+			(p->var.yres != var->yres) ||
+			(p->var.xres_virtual != var->xres_virtual) ||
+			(p->var.yres_virtual != var->yres_virtual) ||
+			(p->var.bits_per_pixel != var->bits_per_pixel) ||
+			memcmp(&p->var.red, &var->red, sizeof(var->red)) ||
+			memcmp(&p->var.green, &var->green, sizeof(var->green)) ||
+			memcmp(&p->var.blue, &var->blue, sizeof(var->blue));
+	} else
+		chgvar = 0;
+	p->var = *var;
+	/* cmap */
+	p->screen_base = vaddr_va(m2info->video.vbase);
+	p->visual = visual;
+	p->ypanstep = 1;
+	p->ywrapstep = 0;
+	p->type = FB_TYPE_PACKED_PIXELS;
+	p->type_aux = 0;
+	p->next_line = p->line_length = (var->xres_virtual * var->bits_per_pixel) >> 3;
+	p->can_soft_blank = 0;
+	p->inverse = 0;	/* TBD */
+	initMatroxDH(m2info, p);
+	if (chgvar && info && info->changevar)
+		info->changevar(con);
+	if (con == m2info->currcon) {
+		struct my_timming mt;
+		struct matrox_hw_state* hw;
+		struct matrox_hw_state* ohw;
+		unsigned int pos;
+
+		matroxfb_var2my(var, &mt);
+		/* CRTC2 delay */
+		mt.delay = 34;
+
+		hw = ACCESS_FBINFO(newhw);
+		ohw = ACCESS_FBINFO(currenthw);
+
+		/* copy last setting... */
+		memcpy(hw, ohw, sizeof(*hw));
+
+		pos = (var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel >> 3;
+		pos += m2info->video.offbase;
+		DAC1064_global_init(PMINFO hw);
+		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {
+			if (ACCESS_FBINFO(primout))
+				ACCESS_FBINFO(primout)->compute(MINFO, &mt, hw);
+		}
+		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
+			down_read(&ACCESS_FBINFO(altout.lock));
+			if (ACCESS_FBINFO(altout.output))
+				ACCESS_FBINFO(altout.output)->compute(ACCESS_FBINFO(altout.device), &mt, hw);
+			up_read(&ACCESS_FBINFO(altout.lock));
+		}
+		matroxfb_dh_restore(m2info, &mt, p, mode, pos);
+		DAC1064_global_restore(PMINFO hw);
+		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {
+			if (ACCESS_FBINFO(primout))
+				ACCESS_FBINFO(primout)->program(MINFO, hw);
+		}
+		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
+			down_read(&ACCESS_FBINFO(altout.lock));
+			if (ACCESS_FBINFO(altout.output))
+				ACCESS_FBINFO(altout.output)->program(ACCESS_FBINFO(altout.device), hw);
+			up_read(&ACCESS_FBINFO(altout.lock));
+		}
+		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {
+			if (ACCESS_FBINFO(primout))
+				ACCESS_FBINFO(primout)->start(MINFO);
+		}
+		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
+			down_read(&ACCESS_FBINFO(altout.lock));
+			if (ACCESS_FBINFO(altout.output))
+				ACCESS_FBINFO(altout.output)->start(ACCESS_FBINFO(altout.device));
+			up_read(&ACCESS_FBINFO(altout.lock));
+		}
+		matroxfb_dh_cfbX_init(m2info, p);
+		do_install_cmap(m2info, p);
+	}
+	return 0;
+#undef m2info
+}
+
+static int matroxfb_dh_get_cmap(struct fb_cmap* cmap, int kspc, int con,
+		struct fb_info* info) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	struct display* dsp;
+
+	if (con < 0)
+		dsp = m2info->fbcon.disp;
+	else
+		dsp = fb_display + con;
+	if (con == m2info->currcon)
+		return fb_get_cmap(cmap, kspc, matroxfb_dh_getcolreg, info);
+	else if (dsp->cmap.len)
+		fb_copy_cmap(&dsp->cmap, cmap, kspc ? 0 : 2);
+	else
+		fb_copy_cmap(fb_default_cmap(16), cmap, kspc ? 0 : 2);
+	return 0;
+#undef m2info
+}
+
+static int matroxfb_dh_set_cmap(struct fb_cmap* cmap, int kspc, int con,
+		struct fb_info* info) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	struct display* dsp;
+
+	if (con < 0)
+		dsp = m2info->fbcon.disp;
+	else
+		dsp = fb_display + con;
+	if (dsp->cmap.len != 16) {
+		int err;
+
+		err = fb_alloc_cmap(&dsp->cmap, 16, 0);
+		if (err)
+			return err;
+	}
+	if (con == m2info->currcon)
+		return fb_set_cmap(cmap, kspc, matroxfb_dh_setcolreg, info);
+	else
+		fb_copy_cmap(cmap, &dsp->cmap, kspc ? 0 : 1);
+	return 0;
+#undef m2info
+}
+
+static int matroxfb_dh_pan_display(struct fb_var_screeninfo* var, int con,
+		struct fb_info* info) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	if (var->xoffset + fb_display[con].var.xres > fb_display[con].var.xres_virtual ||
+	    var->yoffset + fb_display[con].var.yres > fb_display[con].var.yres_virtual)
+		return -EINVAL;
+	if (con == m2info->currcon)
+		matroxfb_dh_pan_var(m2info, var);
+	fb_display[con].var.xoffset = var->xoffset;
+	fb_display[con].var.yoffset = var->yoffset;
+	return 0;
+#undef m2info
+}
+
+static int matroxfb_dh_switch(int con, struct fb_info* info);
+
+static int matroxfb_dh_get_vblank(const struct matroxfb_dh_fb_info* m2info, struct fb_vblank* vblank) {
+	struct matrox_fb_info* minfo = m2info->primary_dev;
+
+	memset(vblank, 0, sizeof(*vblank));
+	vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VBLANK;
+	/* mask out reserved bits + field number (odd/even) */
+	vblank->vcount = mga_inl(0x3C48) & 0x000007FF;
+	/* compatibility stuff */
+	if (vblank->vcount >= m2info->currcon_display->var.yres)
+		vblank->flags |= FB_VBLANK_VBLANKING;
+	return 0;
+}
+
+static int matroxfb_dh_ioctl(struct inode* inode,
+		struct file* file,
+		unsigned int cmd,
+		unsigned long arg,
+		int con,
+		struct fb_info* info) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	struct matrox_fb_info* minfo = m2info->primary_dev;
+
+	DBG("matroxfb_crtc2_ioctl")
+
+	switch (cmd) {
+		case FBIOGET_VBLANK:
+			{
+				struct fb_vblank vblank;
+				int err;
+
+				err = matroxfb_dh_get_vblank(m2info, &vblank);
+				if (err)
+					return err;
+				copy_to_user_ret((struct fb_vblank*)arg, &vblank, sizeof(vblank), -EFAULT);
+				return 0;
+			}
+		case MATROXFB_SET_OUTPUT_MODE:
+		case MATROXFB_GET_OUTPUT_MODE:
+		case MATROXFB_GET_ALL_OUTPUTS:
+			{
+				return ACCESS_FBINFO(fbcon.fbops)->fb_ioctl(inode, file, cmd, arg, con, &minfo->fbcon);
+			}
+		case MATROXFB_SET_OUTPUT_CONNECTION:
+			{
+				u_int32_t tmp;
+
+				get_user_ret(tmp, (u_int32_t*)arg, -EFAULT);
+				if (tmp & ~ACCESS_FBINFO(output.all))
+					return -EINVAL;
+				if (tmp & ACCESS_FBINFO(output.ph))
+					return -EINVAL;
+				if (tmp == ACCESS_FBINFO(output.sh))
+					return 0;
+				ACCESS_FBINFO(output.sh) = tmp;
+				matroxfb_dh_switch(m2info->currcon, info);
+				return 0;
+			}
+		case MATROXFB_GET_OUTPUT_CONNECTION:
+			{
+				put_user_ret(ACCESS_FBINFO(output.sh), (u_int32_t*)arg, -EFAULT);
+				return 0;
+			}
+		case MATROXFB_GET_AVAILABLE_OUTPUTS:
+			{
+				u_int32_t tmp;
+
+				tmp = ACCESS_FBINFO(output.all) & ~ACCESS_FBINFO(output.ph);
+				put_user_ret(tmp, (u_int32_t*)arg, -EFAULT);
+				return 0;
+			}
+	}
+	return -EINVAL;
+#undef m2info
+}
+
+static struct fb_ops matroxfb_dh_ops = {
+	matroxfb_dh_open,
+	matroxfb_dh_release,
+	matroxfb_dh_get_fix,
+	matroxfb_dh_get_var,
+	matroxfb_dh_set_var,
+	matroxfb_dh_get_cmap,
+	matroxfb_dh_set_cmap,
+	matroxfb_dh_pan_display,
+	matroxfb_dh_ioctl,
+	NULL			/* mmap */
+};
+
+static int matroxfb_dh_switch(int con, struct fb_info* info) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	struct fb_cmap* cmap;
+	struct display* p;
+
+	if (m2info->currcon >= 0) {
+		cmap = &m2info->currcon_display->cmap;
+		if (cmap->len) {
+			fb_get_cmap(cmap, 1, matroxfb_dh_getcolreg, info);
+		}
+	}
+	m2info->currcon = con;
+	if (con < 0)
+		p = m2info->fbcon.disp;
+	else
+		p = fb_display + con;
+	m2info->currcon_display = p;
+	p->var.activate = FB_ACTIVATE_NOW;
+	matroxfb_dh_set_var(&p->var, con, info);
+	return 0;
+#undef m2info
+}
+
+static int matroxfb_dh_updatevar(int con, struct fb_info* info) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	matroxfb_dh_pan_var(m2info, &fb_display[con].var);
+	return 0;
+#undef m2info
+}
+
+static void matroxfb_dh_blank(int blank, struct fb_info* info) {
+#define m2info ((struct matroxfb_dh_fb_info*)info)
+	switch (blank) {
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		default:;
+	}
+	/* do something... */
+#undef m2info
+}
+
+static struct fb_var_screeninfo matroxfb_dh_defined = {
+		640,480,640,480,/* W,H, virtual W,H */
+		0,0,		/* offset */
+		32,		/* depth */
+		0,		/* gray */
+		{0,0,0},	/* R */
+		{0,0,0},	/* G */
+		{0,0,0},	/* B */
+		{0,0,0},	/* alpha */
+		0,		/* nonstd */
+		FB_ACTIVATE_NOW,
+		-1,-1,		/* display size */
+		0,		/* accel flags */
+		39721L,48L,16L,33L,10L,
+		96L,2,0,	/* no sync info */
+		FB_VMODE_NONINTERLACED,
+		{0,0,0,0,0,0}
+};
+
+static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) {
+#define minfo (m2info->primary_dev)
+	struct display* d;
+	void* oldcrtc2;
+
+	d = kmalloc(sizeof(*d), GFP_KERNEL);
+
+	memset(d, 0, sizeof(*d));
+
+	strcpy(m2info->fbcon.modename, "MATROX CRTC2");
+	m2info->fbcon.changevar = NULL;
+	m2info->fbcon.node = -1;
+	m2info->fbcon.fbops = &matroxfb_dh_ops;
+	m2info->fbcon.disp = d;
+	m2info->fbcon.switch_con = &matroxfb_dh_switch;
+	m2info->fbcon.updatevar = &matroxfb_dh_updatevar;
+	m2info->fbcon.blank = &matroxfb_dh_blank;
+	m2info->fbcon.flags = FBINFO_FLAG_DEFAULT;
+	m2info->currcon = -1;
+	m2info->currcon_display = d;
+
+	if (mem < 64)
+		mem *= 1024;
+	if (mem < 64*1024)
+		mem *= 1024;
+	mem &= ~0x00000FFF;	/* PAGE_MASK? */
+	if (minfo->video.len_usable + mem <= minfo->video.len)
+		m2info->video.offbase = minfo->video.len - mem;
+	else if (minfo->video.len < mem) {
+		kfree(d);
+		return -ENOMEM;
+	} else { /* check yres on first head... */
+		m2info->video.borrowed = mem;
+		minfo->video.len_usable -= mem;
+		m2info->video.offbase = minfo->video.len_usable;
+	}
+	m2info->video.base = ACCESS_FBINFO(video.base) + m2info->video.offbase;
+	m2info->video.len = m2info->video.len_usable = m2info->video.len_maximum = mem;
+	m2info->video.vbase.vaddr = vaddr_va(ACCESS_FBINFO(video.vbase)) + m2info->video.offbase;
+	m2info->mmio.base = ACCESS_FBINFO(mmio.base);
+	m2info->mmio.vbase = ACCESS_FBINFO(mmio.vbase);
+	m2info->mmio.len = ACCESS_FBINFO(mmio.len);
+
+	/*
+	 *  If we have two outputs, connect CRTC2 to it...
+	 */
+	if (ACCESS_FBINFO(output.all) & MATROXFB_OUTPUT_CONN_SECONDARY) {
+		ACCESS_FBINFO(output.sh) |= MATROXFB_OUTPUT_CONN_SECONDARY;
+		ACCESS_FBINFO(output.ph) &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
+	}
+
+	matroxfb_dh_set_var(&matroxfb_dh_defined, -2, &m2info->fbcon);
+	if (register_framebuffer(&m2info->fbcon)) {
+		kfree(d);
+		return -ENXIO;
+	}
+	if (m2info->currcon < 0) {
+		matroxfb_dh_set_var(&matroxfb_dh_defined, -1, &m2info->fbcon);
+	}
+	down_write(&ACCESS_FBINFO(crtc2.lock));
+	oldcrtc2 = minfo->crtc2.info;
+	minfo->crtc2.info = &m2info->fbcon;
+	up_write(&ACCESS_FBINFO(crtc2.lock));
+	if (oldcrtc2) {
+		printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 already present: %p\n",
+			oldcrtc2);
+	}
+	return 0;
+#undef minfo
+}
+
+/* ************************** */
+
+static int matroxfb_dh_registerfb(struct matroxfb_dh_fb_info* m2info) {
+#define minfo (m2info->primary_dev)
+	if (matroxfb_dh_regit(PMINFO m2info)) {
+		printk(KERN_ERR "matroxfb_crtc2: secondary head failed to register\n");
+		return -1;
+	}
+	printk(KERN_INFO "matroxfb_crtc2: secondary head of fb%u was registered as fb%u\n",
+		GET_FB_IDX(ACCESS_FBINFO(fbcon.node)), GET_FB_IDX(m2info->fbcon.node));
+	m2info->fbcon_registered = 1;
+	return 0;
+#undef minfo
+}
+
+static void matroxfb_dh_deregisterfb(struct matroxfb_dh_fb_info* m2info) {
+#define minfo (m2info->primary_dev)
+	if (m2info->fbcon_registered) {
+		int id;
+		struct fb_info* crtc2;
+
+		down_write(&ACCESS_FBINFO(crtc2.lock));
+		crtc2 = minfo->crtc2.info;
+		if (crtc2 == &m2info->fbcon)
+			minfo->crtc2.info = NULL;
+		up_write(&ACCESS_FBINFO(crtc2.lock));
+		if (crtc2 != &m2info->fbcon) {
+			printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 mismatch at unload: %p != %p\n",
+				crtc2, &m2info->fbcon);
+			printk(KERN_ERR "matroxfb_crtc2: Expect kernel crash after module unload.\n");
+			return;
+		}
+		id = GET_FB_IDX(m2info->fbcon.node);
+		unregister_framebuffer(&m2info->fbcon);
+		kfree(m2info->fbcon.disp);
+		/* return memory back to primary head */
+		ACCESS_FBINFO(video.len_usable) += m2info->video.borrowed;
+		printk(KERN_INFO "matroxfb_crtc2: fb%u unregistered\n", id);
+		m2info->fbcon_registered = 0;
+	}
+#undef minfo
+}
+
+static void* matroxfb_crtc2_probe(struct matrox_fb_info* minfo) {
+	struct matroxfb_dh_fb_info* m2info;
+
+	/* hardware is CRTC2 incapable... */
+	if (!minfo->devflags.crtc2)
+		return NULL;
+	m2info = (struct matroxfb_dh_fb_info*)kmalloc(sizeof(*m2info), GFP_KERNEL);
+	if (!m2info) {
+		printk(KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n");
+		return NULL;
+	}
+	memset(m2info, 0, sizeof(*m2info));
+	m2info->primary_dev = minfo;
+	if (matroxfb_dh_registerfb(m2info)) {
+		kfree(m2info);
+		printk(KERN_ERR "matroxfb_crtc2: CRTC2 framebuffer failed to register\n");
+		return NULL;
+	}
+	return m2info;
+}
+
+static void matroxfb_crtc2_remove(struct matrox_fb_info* minfo, void* crtc2) {
+	matroxfb_dh_deregisterfb(crtc2);
+}
+
+static struct matroxfb_driver crtc2 = {
+		name:	"Matrox G400 CRTC2",
+		probe:	matroxfb_crtc2_probe,
+		remove:	matroxfb_crtc2_remove };
+
+static int matroxfb_crtc2_init(void) {
+	matroxfb_register_driver(&crtc2);
+	return 0;
+}
+
+static void matroxfb_crtc2_exit(void) {
+	matroxfb_unregister_driver(&crtc2);
+}
+
+MODULE_AUTHOR("(c) 1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>");
+MODULE_DESCRIPTION("Matrox G400 CRTC2 driver");
+module_init(matroxfb_crtc2_init);
+module_exit(matroxfb_crtc2_exit);
+/* we do not have __setup() yet */
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_crtc2.h linux/drivers/video/matrox/matroxfb_crtc2.h
--- v2.3.47/linux/drivers/video/matrox/matroxfb_crtc2.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_crtc2.h	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,44 @@
+#ifndef __MATROXFB_CRTC2_H__
+#define __MATROXFB_CRTC2_H__
+
+#include <linux/ioctl.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include "matroxfb_base.h"
+
+struct matroxfb_dh_fb_info {
+	struct fb_info		fbcon;
+	int			fbcon_registered;
+
+	struct matrox_fb_info*	primary_dev;
+
+	struct {
+		unsigned long	base;	/* physical */
+		vaddr_t		vbase;	/* virtual */
+		unsigned int	len;
+		unsigned int	len_usable;
+		unsigned int	len_maximum;
+		unsigned int 	offbase;
+		unsigned int	borrowed;
+			      } video;
+	struct {
+		unsigned long	base;
+		vaddr_t		vbase;
+		unsigned int	len;
+			      } mmio;
+
+	int			currcon;
+	struct display*		currcon_display;
+
+	union {
+#ifdef FBCON_HAS_CFB16
+		u_int16_t	cfb16[16];
+#endif
+#ifdef FBCON_HAS_CFB32
+		u_int32_t	cfb32[16];
+#endif
+	} cmap;
+	struct { unsigned red, green, blue, transp; } palette[16];
+};
+
+#endif /* __MATROXFB_CRTC2_H__ */
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_maven.c linux/drivers/video/matrox/matroxfb_maven.c
--- v2.3.47/linux/drivers/video/matrox/matroxfb_maven.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_maven.c	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,1040 @@
+#include "matroxfb_maven.h"
+#include "matroxfb_misc.h"
+#include "matroxfb_DAC1064.h"
+#include <linux/i2c.h>
+#include <linux/matroxfb.h>
+#include <asm/div64.h>
+#include <asm/uaccess.h>
+
+#define MAVEN_I2CID	(0x1B)
+
+#define MODE_PAL	MATROXFB_OUTPUT_MODE_PAL
+#define MODE_NTSC	MATROXFB_OUTPUT_MODE_NTSC
+#define MODE_TV(x)	(((x) == MODE_PAL) || ((x) == MODE_NTSC))
+#define MODE_MONITOR	MATROXFB_OUTPUT_MODE_MONITOR
+
+struct maven_data {
+	struct matrox_fb_info*		primary_head;
+	struct i2c_client*		client;
+	int				mode;
+};
+
+static int maven_get_reg(struct i2c_client* c, char reg) {
+	char dst;
+	struct i2c_msg msgs[] = {{ c->addr, I2C_M_REV_DIR_ADDR, sizeof(reg), &reg },
+				 { c->addr, I2C_M_RD | I2C_M_NOSTART, sizeof(dst), &dst }};
+	s32 err;
+
+	err = i2c_transfer(c->adapter, msgs, 2);
+	if (err < 0)
+		printk(KERN_INFO "ReadReg(%d) failed\n", reg);
+	return dst & 0xFF;
+}
+
+static int maven_set_reg(struct i2c_client* c, int reg, int val) {
+	s32 err;
+
+	err = i2c_smbus_write_byte_data(c, reg, val);
+	if (err)
+		printk(KERN_INFO "WriteReg(%d) failed\n", reg);
+	return err;
+}
+
+static int maven_set_reg_pair(struct i2c_client* c, int reg, int val) {
+	s32 err;
+
+	err = i2c_smbus_write_word_data(c, reg, val);
+	if (err)
+		printk(KERN_INFO "WriteRegPair(%d) failed\n", reg);
+	return err;
+}
+
+static const struct matrox_pll_features maven_pll = {
+	50000,
+	27000,
+	4, 127,
+	2, 31,
+	3
+};
+
+struct matrox_pll_features2 {
+	unsigned int	vco_freq_min;
+	unsigned int	vco_freq_max;
+	unsigned int	feed_div_min;
+	unsigned int	feed_div_max;
+	unsigned int	in_div_min;
+	unsigned int	in_div_max;
+	unsigned int	post_shift_max;
+};
+
+struct matrox_pll_ctl {
+	unsigned int	ref_freq;
+	unsigned int	den;
+};
+
+static const struct matrox_pll_features2 maven1000_pll = {
+	 50000000,
+	300000000,
+	 5, 128,
+	 3,  32,
+	 3
+};
+
+static const struct matrox_pll_ctl maven_PAL = {
+	540000,
+	    50
+};
+
+static const struct matrox_pll_ctl maven_NTSC = {
+	450450,	/* 27027000/60 == 27000000/59.94005994 */
+	    60
+};
+
+static int matroxfb_PLL_mavenclock(const struct matrox_pll_features2* pll,
+		const struct matrox_pll_ctl* ctl,
+		unsigned int htotal, unsigned int vtotal,
+		unsigned int* in, unsigned int* feed, unsigned int* post,
+		unsigned int* h2) {
+	unsigned int besth2 = 0;
+	unsigned int fxtal = ctl->ref_freq;
+	unsigned int fmin = pll->vco_freq_min / ctl->den;
+	unsigned int fwant;
+	unsigned int p;
+	unsigned int scrlen;
+	unsigned int fmax;
+
+	DBG("PLL_calcclock")
+
+	scrlen = htotal * (vtotal - 1);
+	fwant = htotal * vtotal;
+	fmax = pll->vco_freq_max / ctl->den;
+
+	printk(KERN_DEBUG "want: %u, xtal: %u, h: %u, v: %u, fmax: %u\n",
+		fwant, fxtal, htotal, vtotal, fmax);
+	for (p = 1; p <= pll->post_shift_max; p++) {
+		if (fwant * 2 > fmax)
+			break;
+		fwant *= 2;
+	}
+	if (fwant > fmax)
+		return 0;
+	for (; p-- > 0; fwant >>= 1) {
+		unsigned int m;
+
+		if (fwant < fmin) break;
+		for (m = pll->in_div_min; m <= pll->in_div_max; m++) {
+			unsigned int n;
+			unsigned int dvd;
+			unsigned int ln;
+
+			n = (fwant * m) / fxtal;
+			if (n < pll->feed_div_min)
+				continue;
+			if (n > pll->feed_div_max)
+				break;
+
+			ln = fxtal * n;
+			dvd = m << p;
+
+			if (ln % dvd)
+				continue;
+			ln = ln / dvd;
+
+			if (ln < scrlen + 2)
+				continue;
+			ln = ln - scrlen;
+			if (ln > htotal)
+				continue;
+			printk(KERN_DEBUG "Match: %u / %u / %u / %u\n", n, m, p, ln);
+			if (ln > besth2) {
+				printk(KERN_DEBUG "Better...\n");
+				*h2 = besth2 = ln;
+				*post = p;
+				*in = m;
+				*feed = n;
+			}
+		}
+	}
+	if (besth2 < 2)
+		return 0;
+	dprintk(KERN_ERR "clk: %02X %02X %02X %d %d\n", *in, *feed, *post, fxtal, fwant);
+	return fxtal * (*feed) / (*in) * ctl->den;
+}
+
+static unsigned int matroxfb_mavenclock(const struct matrox_pll_ctl* ctl,
+		unsigned int htotal, unsigned int vtotal,
+		unsigned int* in, unsigned int* feed, unsigned int* post,
+		unsigned int* htotal2) {
+	unsigned int fvco;
+	unsigned int p;
+
+	fvco = matroxfb_PLL_mavenclock(&maven1000_pll, ctl, htotal, vtotal, in, feed, &p, htotal2);
+	if (!fvco)
+		return -EINVAL;
+	p = (1 << p) - 1;
+	if (fvco <= 100000000)
+		;
+	else if (fvco <= 140000000)
+		p |= 0x08;
+	else if (fvco <= 180000000)
+		p |= 0x10;
+	else
+		p |= 0x18;
+	*post = p;
+	return 0;
+}
+
+static void DAC1064_calcclock(unsigned int freq, unsigned int fmax,
+		unsigned int* in, unsigned int* feed, unsigned int* post) {
+	unsigned int fvco;
+	unsigned int p;
+
+	fvco = matroxfb_PLL_calcclock(&maven_pll, freq, fmax, in, feed, &p);
+	p = (1 << p) - 1;
+	if (fvco <= 100000)
+		;
+	else if (fvco <= 140000)
+		p |= 0x08;
+	else if (fvco <= 180000)
+		p |= 0x10;
+	else
+		p |= 0x18;
+	*post = p;
+	return;
+}
+
+static void maven_init_TVdata(const struct maven_data* md, struct mavenregs* data) {
+	static struct mavenregs palregs = { {
+		0x2A, 0x09, 0x8A, 0xCB,	/* 00: chroma subcarrier */
+		0x00,
+		0x00,	/* ? not written */
+		0x00,	/* modified by code (F9 written...) */
+		0x00,	/* ? not written */
+		0x7E,	/* 08 */
+		0x44,	/* 09 */
+		0x9C,	/* 0A */
+		0x2E,	/* 0B */
+		0x21,	/* 0C */
+		0x00,	/* ? not written */
+		0x3F, 0x03, /* 0E-0F */
+		0x3F, 0x03, /* 10-11 */
+		0x1A,	/* 12 */
+		0x2A,	/* 13 */
+		0x1C, 0x3D, 0x14, /* 14-16 */
+		0x9C, 0x01, /* 17-18 */
+		0x00,	/* 19 */
+		0xFE,	/* 1A */
+		0x7E,	/* 1B */
+		0x60,	/* 1C */
+		0x05,	/* 1D */
+		0x89, 0x03, /* 1E-1F */
+		0x72,	/* 20 */
+		0x07,	/* 21 */
+		0x72,	/* 22 */
+		0x00,	/* 23 */
+		0x00,	/* 24 */
+		0x00,	/* 25 */
+		0x08,	/* 26 */
+		0x04,	/* 27 */
+		0x00,	/* 28 */
+		0x1A,	/* 29 */
+		0x55, 0x01, /* 2A-2B */
+		0x26,	/* 2C */
+		0x07, 0x7E, /* 2D-2E */
+		0x02, 0x54, /* 2F-30 */
+		0xB0, 0x00, /* 31-32 */
+		0x14,	/* 33 */
+		0x49,	/* 34 */
+		0x00,	/* 35 written multiple times */
+		0x00,	/* 36 not written */
+		0xA3,	/* 37 */
+		0xC8,	/* 38 */
+		0x22,	/* 39 */
+		0x02,	/* 3A */
+		0x22,	/* 3B */
+		0x3F, 0x03, /* 3C-3D */
+		0x00,	/* 3E written multiple times */
+		0x00,	/* 3F not written */
+	}, MODE_PAL, 625, 50 };
+	static struct mavenregs ntscregs = { {
+		0x21, 0xF0, 0x7C, 0x1F,	/* 00: chroma subcarrier */
+		0x00,
+		0x00,	/* ? not written */
+		0x00,	/* modified by code (F9 written...) */
+		0x00,	/* ? not written */
+		0x7E,	/* 08 */
+		0x43,	/* 09 */
+		0x7E,	/* 0A */
+		0x3D,	/* 0B */
+		0x00,	/* 0C */
+		0x00,	/* ? not written */
+		0x41, 0x00, /* 0E-0F */
+		0x3C, 0x00, /* 10-11 */
+		0x17,	/* 12 */
+		0x21,	/* 13 */
+		0x1B, 0x1B, 0x24, /* 14-16 */
+		0x83, 0x01, /* 17-18 */
+		0x00,	/* 19 */
+		0x0F,	/* 1A */
+		0x0F,	/* 1B */
+		0x60,	/* 1C */
+		0x05,	/* 1D */
+		0x89, 0x02, /* 1E-1F */
+		0x5F,	/* 20 */
+		0x04,	/* 21 */
+		0x5F,	/* 22 */
+		0x01,	/* 23 */
+		0x02,	/* 24 */
+		0x00,	/* 25 */
+		0x0A,	/* 26 */
+		0x05,	/* 27 */
+		0x00,	/* 28 */
+		0x10,	/* 29 */
+		0xFF, 0x03, /* 2A-2B */
+		0x24,	/* 2C */
+		0x0F, 0x78, /* 2D-2E */
+		0x00, 0x00, /* 2F-30 */
+		0xB2, 0x04, /* 31-32 */
+		0x14,	/* 33 */
+		0x02,	/* 34 */
+		0x00,	/* 35 written multiple times */
+		0x00,	/* 36 not written */
+		0xA3,	/* 37 */
+		0xC8,	/* 38 */
+		0x15,	/* 39 */
+		0x05,	/* 3A */
+		0x3B,	/* 3B */
+		0x3C, 0x00, /* 3C-3D */
+		0x00,	/* 3E written multiple times */
+		0x00,	/* never written */
+	}, MODE_NTSC, 525, 60 };
+
+	if (md->mode & MODE_PAL)
+		*data = palregs;
+	else
+		*data = ntscregs;
+
+	data->regs[0x93] = 0xA2;
+
+	/* gamma correction registers */
+	data->regs[0x83] = 0x00;
+	data->regs[0x84] = 0x00;
+	data->regs[0x85] = 0x00;
+	data->regs[0x86] = 0x1F;
+	data->regs[0x87] = 0x10;
+	data->regs[0x88] = 0x10;
+	data->regs[0x89] = 0x10;
+	data->regs[0x8A] = 0x64;	/* 100 */
+	data->regs[0x8B] = 0xC8;	/* 200 */
+
+	return;
+}
+
+#define LR(x) maven_set_reg(c, (x), m->regs[(x)])
+#define LRP(x) maven_set_reg_pair(c, (x), m->regs[(x)] | (m->regs[(x)+1] << 8))
+static void maven_init_TV(struct i2c_client* c, const struct mavenregs* m) {
+	int val;
+
+
+	maven_set_reg(c, 0x3E, 0x01);
+	maven_get_reg(c, 0x82);	/* fetch oscillator state? */
+	maven_set_reg(c, 0x8C, 0x00);
+	maven_get_reg(c, 0x94);	/* get 0x82 */
+	maven_set_reg(c, 0x94, 0xA2);
+	/* xmiscctrl */
+
+	maven_set_reg_pair(c, 0x8E, 0x1EFF);
+	maven_set_reg(c, 0xC6, 0x01);
+
+	/* removed code... */
+
+	maven_get_reg(c, 0x06);
+	maven_set_reg(c, 0x06, 0xF9);	/* or read |= 0xF0 ? */
+
+	/* removed code here... */
+
+	/* real code begins here? */
+	/* chroma subcarrier */
+	LR(0x00); LR(0x01); LR(0x02); LR(0x03);
+
+	LR(0x04);
+
+	LR(0x2C);
+	LR(0x08);
+	LR(0x0A);
+	LR(0x09);
+	LR(0x29);
+	LRP(0x31);
+	LRP(0x17);
+	LR(0x0B);
+	LR(0x0C);
+	if (m->mode & MODE_PAL) {
+		maven_set_reg(c, 0x35, 0x10); /* ... */
+	} else {
+		maven_set_reg(c, 0x35, 0x0F); /* ... */
+	}
+
+	LRP(0x10);
+
+	LRP(0x0E);
+	LRP(0x1E);
+
+	LR(0x20);	/* saturation #1 */
+	LR(0x22);	/* saturation #2 */
+	LR(0x25);	/* hue */
+	LR(0x34);
+	LR(0x33);
+	LR(0x19);
+	LR(0x12);
+	LR(0x3B);
+	LR(0x13);
+	LR(0x39);
+	LR(0x1D);
+	LR(0x3A);
+	LR(0x24);
+	LR(0x14);
+	LR(0x15);
+	LR(0x16);
+	LRP(0x2D);
+	LRP(0x2F);
+	LR(0x1A);
+	LR(0x1B);
+	LR(0x1C);
+	LR(0x23);
+	LR(0x26);
+	LR(0x28);
+	LR(0x27);
+	LR(0x21);
+	LRP(0x2A);
+	if (m->mode & MODE_PAL)
+		maven_set_reg(c, 0x35, 0x1D);	/* ... */
+	else
+		maven_set_reg(c, 0x35, 0x1C);
+
+	LRP(0x3C);
+	LR(0x37);
+	LR(0x38);
+	maven_set_reg(c, 0xB3, 0x01);
+
+	maven_get_reg(c, 0xB0);	/* read 0x80 */
+	maven_set_reg(c, 0xB0, 0x08);	/* ugh... */
+	maven_get_reg(c, 0xB9);	/* read 0x7C */
+	maven_set_reg(c, 0xB9, 0x78);
+	maven_get_reg(c, 0xBF);	/* read 0x00 */
+	maven_set_reg(c, 0xBF, 0x02);
+	maven_get_reg(c, 0x94);	/* read 0x82 */
+	maven_set_reg(c, 0x94, 0xB3);
+
+	LR(0x80); /* 04 1A 91 or 05 21 91 */
+	LR(0x81);
+	LR(0x82);
+
+	maven_set_reg(c, 0x8C, 0x20);
+	maven_get_reg(c, 0x8D);
+	maven_set_reg(c, 0x8D, 0x10);
+
+	LR(0x90); /* 4D 50 52 or 4E 05 45 */
+	LR(0x91);
+	LR(0x92);
+
+	LRP(0x9A); /* 0049 or 004F */
+	LRP(0x9C); /* 0004 or 0004 */
+	LRP(0x9E); /* 0458 or 045E */
+	LRP(0xA0); /* 05DA or 051B */
+	LRP(0xA2); /* 00CC or 00CF */
+	LRP(0xA4); /* 007D or 007F */
+	LRP(0xA6); /* 007C or 007E */
+	LRP(0xA8); /* 03CB or 03CE */
+	LRP(0x98); /* 0000 or 0000 */
+	LRP(0xAE); /* 0044 or 003A */
+	LRP(0x96); /* 05DA or 051B */
+	LRP(0xAA); /* 04BC or 046A */
+	LRP(0xAC); /* 004D or 004E */
+
+	LR(0xBE);
+	LR(0xC2);
+
+	maven_get_reg(c, 0x8D);
+	maven_set_reg(c, 0x8D, 0x00);
+
+	LR(0x20);	/* saturation #1 */
+	LR(0x22);	/* saturation #2 */
+	LR(0x93);	/* whoops */
+	LR(0x20);	/* oh, saturation #1 again */
+	LR(0x22);	/* oh, saturation #2 again */
+	LR(0x25);	/* hue */
+	LRP(0x0E);
+	LRP(0x1E);
+	LRP(0x0E);	/* problems with memory? */
+	LRP(0x1E);	/* yes, matrox must have problems in memory area... */
+
+	/* load gamma correction stuff */
+	LR(0x83);
+	LR(0x84);
+	LR(0x85);
+	LR(0x86);
+	LR(0x87);
+	LR(0x88);
+	LR(0x89);
+	LR(0x8A);
+	LR(0x8B);
+
+	val = maven_get_reg(c, 0x8D);
+	val &= 0x10;			/* 0x10 or anything ored with it */
+	maven_set_reg(c, 0x8D, val);
+
+	LR(0x33);
+	LR(0x19);
+	LR(0x12);
+	LR(0x3B);
+	LR(0x13);
+	LR(0x39);
+	LR(0x1D);
+	LR(0x3A);
+	LR(0x24);
+	LR(0x14);
+	LR(0x15);
+	LR(0x16);
+	LRP(0x2D);
+	LRP(0x2F);
+	LR(0x1A);
+	LR(0x1B);
+	LR(0x1C);
+	LR(0x23);
+	LR(0x26);
+	LR(0x28);
+	LR(0x27);
+	LR(0x21);
+	LRP(0x2A);
+	if (m->mode & MODE_PAL)
+		maven_set_reg(c, 0x35, 0x1D);
+	else
+		maven_set_reg(c, 0x35, 0x1C);
+	LRP(0x3C);
+	LR(0x37);
+	LR(0x38);
+
+	maven_get_reg(c, 0xB0);
+	LR(0xB0);	/* output mode */
+	LR(0x90);
+	LR(0xBE);
+	LR(0xC2);
+
+	LRP(0x9A);
+	LRP(0xA2);
+	LRP(0x9E);
+	LRP(0xA6);
+	LRP(0xAA);
+	LRP(0xAC);
+	maven_set_reg(c, 0x3E, 0x00);
+	maven_set_reg(c, 0x95, 0x20);
+}
+
+static int maven_find_exact_clocks(unsigned int ht, unsigned int vt,
+		struct mavenregs* m) {
+	unsigned int x;
+	unsigned int err = ~0;
+
+	/* 1:1 */
+	m->regs[0x80] = 0x0F;
+	m->regs[0x81] = 0x07;
+	m->regs[0x82] = 0x81;
+
+	for (x = 0; x < 8; x++) {
+		unsigned int a, b, c, h2;
+		unsigned int h = ht + 2 + x;
+
+		if (!matroxfb_mavenclock((m->mode & MODE_PAL) ? &maven_PAL : &maven_NTSC, h, vt, &a, &b, &c, &h2)) {
+			unsigned int diff = h - h2;
+
+			if (diff < err) {
+				err = diff;
+				m->regs[0x80] = a - 1;
+				m->regs[0x81] = b - 1;
+				m->regs[0x82] = c | 0x80;
+				m->hcorr = h2 - 2;
+				m->htotal = h - 2;
+			}
+		}
+	}
+	return err != ~0U;
+}
+
+static inline int maven_compute_timming(struct maven_data* md,
+		struct my_timming* mt,
+		struct mavenregs* m) {
+	unsigned int tmpi;
+	unsigned int a, bv, c;
+
+	m->mode = md->mode;
+	if (MODE_TV(md->mode)) {
+		unsigned int lmargin;
+		unsigned int umargin;
+		unsigned int vslen;
+		unsigned int hcrt;
+		unsigned int slen;
+
+		maven_init_TVdata(md, m);
+
+		if (maven_find_exact_clocks(mt->HTotal, mt->VTotal, m) == 0)
+			return -EINVAL;
+
+		lmargin = mt->HTotal - mt->HSyncEnd;
+		slen = mt->HSyncEnd - mt->HSyncStart;
+		hcrt = mt->HTotal - slen - mt->delay;
+		umargin = mt->VTotal - mt->VSyncEnd;
+		vslen = mt->VSyncEnd - mt->VSyncStart;
+
+		if (m->hcorr < mt->HTotal)
+			hcrt += m->hcorr;
+		if (hcrt > mt->HTotal)
+			hcrt -= mt->HTotal;
+		if (hcrt + 2 > mt->HTotal)
+			hcrt = 0;	/* or issue warning? */
+
+		/* last (first? middle?) line in picture can have different length */
+		/* hlen - 2 */
+		m->regs[0x96] = m->hcorr;
+		m->regs[0x97] = m->hcorr >> 8;
+		/* ... */
+		m->regs[0x98] = 0x00; m->regs[0x99] = 0x00;
+		/* hblanking end */
+		m->regs[0x9A] = lmargin;	/* 100% */
+		m->regs[0x9B] = lmargin >> 8;	/* 100% */
+		/* who knows */
+		m->regs[0x9C] = 0x04;
+		m->regs[0x9D] = 0x00;
+		/* htotal - 2 */
+		m->regs[0xA0] = m->htotal;
+		m->regs[0xA1] = m->htotal >> 8;
+		/* vblanking end */
+		m->regs[0xA2] = mt->VTotal - mt->VSyncStart - 1;	/* stop vblanking */
+		m->regs[0xA3] = (mt->VTotal - mt->VSyncStart - 1) >> 8;
+		/* something end... [A6]+1..[A8] */
+		m->regs[0xA4] = 0x01;
+		m->regs[0xA5] = 0x00;
+		/* something start... 0..[A4]-1 */
+		m->regs[0xA6] = 0x00;
+		m->regs[0xA7] = 0x00;
+		/* vertical line count - 1 */
+		m->regs[0xA8] = mt->VTotal - 1;
+		m->regs[0xA9] = (mt->VTotal - 1) >> 8;
+		/* horizontal vidrst pos */
+		m->regs[0xAA] = hcrt;		/* 0 <= hcrt <= htotal - 2 */
+		m->regs[0xAB] = hcrt >> 8;
+		/* vertical vidrst pos */
+		m->regs[0xAC] = mt->VTotal - 2;
+		m->regs[0xAD] = (mt->VTotal - 2) >> 8;
+		/* moves picture up/down and so on... */
+		m->regs[0xAE] = 0x01; /* Fix this... 0..VTotal */
+		m->regs[0xAF] = 0x00;
+		{
+			int hdec;
+			int hlen;
+			unsigned int ibmin = 4 + lmargin + mt->HDisplay;
+			unsigned int ib;
+			int i;
+
+			/* Verify! */
+			/* Where 94208 came from? */
+			if (mt->HTotal)
+				hdec = 94208 / (mt->HTotal);
+			else
+				hdec = 0x81;
+			if (hdec > 0x81)
+				hdec = 0x81;
+			if (hdec < 0x41)
+				hdec = 0x41;
+			hdec--;
+			hlen = 98304 - 128 - ((lmargin + mt->HDisplay - 8) * hdec);
+			if (hlen < 0)
+				hlen = 0;
+			hlen = hlen >> 8;
+			if (hlen > 0xFF)
+				hlen = 0xFF;
+			/* Now we have to compute input buffer length.
+			   If you want any picture, it must be between
+			     4 + lmargin + xres
+			   and
+			     94208 / hdec
+			   If you want perfect picture even on the top
+			   of screen, it must be also
+			     0x3C0000 * i / hdec + Q - R / hdec
+			   where
+			        R      Qmin   Qmax
+			     0x07000   0x5AE  0x5BF
+			     0x08000   0x5CF  0x5FF
+			     0x0C000   0x653  0x67F
+			     0x10000   0x6F8  0x6FF
+			 */
+			i = 1;
+			do {
+				ib = ((0x3C0000 * i - 0x8000)/ hdec + 0x05E7) >> 8;
+				i++;
+			} while (ib < ibmin);
+			if (ib >= m->htotal + 2) {
+				ib = ibmin;
+			}
+
+			m->regs[0x90] = hdec;	/* < 0x40 || > 0x80 is bad... 0x80 is questionable */
+			m->regs[0xC2] = hlen;
+			/* 'valid' input line length */
+			m->regs[0x9E] = ib;
+			m->regs[0x9F] = ib >> 8;
+		}
+		{
+			int vdec;
+			int vlen;
+
+#define MATROX_USE64BIT_DIVIDE
+			if (mt->VTotal) {
+#ifdef MATROX_USE64BIT_DIVIDE
+				u64 f1;
+				u32 a;
+				u32 b;
+
+				a = m->vlines * (m->htotal + 2);
+				b = (mt->VTotal - 1) * (m->htotal + 2) + m->hcorr + 2;
+
+				f1 = ((u64)a) << 15;	/* *32768 */
+				do_div(f1, b);
+				vdec = f1;
+#else
+				vdec = m->vlines * 32768 / mt->VTotal;
+#endif
+			} else
+				vdec = 0x8000;
+			if (vdec > 0x8000)
+				vdec = 0x8000;
+			vlen = (vslen + umargin + mt->VDisplay) * vdec;
+			vlen = (vlen >> 16) - 146; /* FIXME: 146?! */
+			if (vlen < 0)
+				vlen = 0;
+			if (vlen > 0xFF)
+				vlen = 0xFF;
+			vdec--;
+			m->regs[0x91] = vdec;
+			m->regs[0x92] = vdec >> 8;
+			m->regs[0xBE] = vlen;
+		}
+		m->regs[0xB0] = 0x08;	/* output: SVideo/Composite */
+		return 0;
+	}
+
+	DAC1064_calcclock(mt->pixclock, 450000, &a, &bv, &c);
+	m->regs[0x80] = a;
+	m->regs[0x81] = bv;
+	m->regs[0x82] = c | 0x80;
+
+	m->regs[0xB3] = 0x01;
+	m->regs[0x94] = 0xB2;
+
+	/* htotal... */
+	m->regs[0x96] = mt->HTotal;
+	m->regs[0x97] = mt->HTotal >> 8;
+	/* ?? */
+	m->regs[0x98] = 0x00;
+	m->regs[0x99] = 0x00;
+	/* hsync len */
+	tmpi = mt->HSyncEnd - mt->HSyncStart;
+	m->regs[0x9A] = tmpi;
+	m->regs[0x9B] = tmpi >> 8;
+	/* hblank end */
+	tmpi = mt->HTotal - mt->HSyncStart;
+	m->regs[0x9C] = tmpi;
+	m->regs[0x9D] = tmpi >> 8;
+	/* hblank start */
+	tmpi += mt->HDisplay;
+	m->regs[0x9E] = tmpi;
+	m->regs[0x9F] = tmpi >> 8;
+	/* htotal + 1 */
+	tmpi = mt->HTotal + 1;
+	m->regs[0xA0] = tmpi;
+	m->regs[0xA1] = tmpi >> 8;
+	/* vsync?! */
+	tmpi = mt->VSyncEnd - mt->VSyncStart - 1;
+	m->regs[0xA2] = tmpi;
+	m->regs[0xA3] = tmpi >> 8;
+	/* ignored? */
+	tmpi = mt->VTotal - mt->VSyncStart;
+	m->regs[0xA4] = tmpi;
+	m->regs[0xA5] = tmpi >> 8;
+	/* ignored? */
+	tmpi = mt->VTotal - 1;
+	m->regs[0xA6] = tmpi;
+	m->regs[0xA7] = tmpi >> 8;
+	/* vtotal - 1 */
+	m->regs[0xA8] = tmpi;
+	m->regs[0xA9] = tmpi >> 8;
+	/* hor vidrst */
+	tmpi = mt->HTotal - mt->delay;
+	m->regs[0xAA] = tmpi;
+	m->regs[0xAB] = tmpi >> 8;
+	/* vert vidrst */
+	tmpi = mt->VTotal - 2;
+	m->regs[0xAC] = tmpi;
+	m->regs[0xAD] = tmpi >> 8;
+	/* ignored? */
+	m->regs[0xAE] = 0x00;
+	m->regs[0xAF] = 0x00;
+
+	m->regs[0xB0] = 0x03;	/* output: monitor */
+	m->regs[0xB1] = 0xA0;	/* ??? */
+	m->regs[0x8C] = 0x20;	/* must be set... */
+	m->regs[0x8D] = 0x00;	/* defaults to 0x10: test signal */
+	m->regs[0xB9] = 0x1A;	/* defaults to 0x2C: too bright */
+	m->regs[0xBF] = 0x22;	/* makes picture stable */
+
+	return 0;
+}
+
+static inline int maven_program_timming(struct maven_data* md,
+		const struct mavenregs* m) {
+	struct i2c_client* c = md->client;
+
+	if (m->mode & MODE_MONITOR) {
+		LR(0x80);
+		LR(0x81);
+		LR(0x82);
+
+		LR(0xB3);
+		LR(0x94);
+
+		LRP(0x96);
+		LRP(0x98);
+		LRP(0x9A);
+		LRP(0x9C);
+		LRP(0x9E);
+		LRP(0xA0);
+		LRP(0xA2);
+		LRP(0xA4);
+		LRP(0xA6);
+		LRP(0xA8);
+		LRP(0xAA);
+		LRP(0xAC);
+		LRP(0xAE);
+
+		LR(0xB0);	/* output: monitor */
+		LR(0xB1);	/* ??? */
+		LR(0x8C);	/* must be set... */
+		LR(0x8D);	/* defaults to 0x10: test signal */
+		LR(0xB9);	/* defaults to 0x2C: too bright */
+		LR(0xBF);	/* makes picture stable */
+	} else {
+		maven_init_TV(c, m);
+	}
+	return 0;
+}
+
+static inline int maven_resync(struct maven_data* md) {
+	struct i2c_client* c = md->client;
+	maven_set_reg(c, 0x95, 0x20);	/* start whole thing */
+	return 0;
+}
+
+static int maven_set_output_mode(struct maven_data* md, u_int32_t arg) {
+	switch (arg) {
+		case MATROXFB_OUTPUT_MODE_PAL:
+		case MATROXFB_OUTPUT_MODE_NTSC:
+		case MATROXFB_OUTPUT_MODE_MONITOR:
+			md->mode = arg;
+			return 1;
+	}
+	return -EINVAL;
+}
+
+static int maven_get_output_mode(struct maven_data* md, u_int32_t *arg) {
+	*arg = md->mode;
+	return 0;
+}
+
+/******************************************************/
+
+static int maven_out_compute(void* md, struct my_timming* mt, struct matrox_hw_state* mr) {
+	return maven_compute_timming(md, mt, &mr->maven);
+}
+
+static int maven_out_program(void* md, const struct matrox_hw_state* mr) {
+	return maven_program_timming(md, &mr->maven);
+}
+
+static int maven_out_start(void* md) {
+	return maven_resync(md);
+}
+
+static void maven_out_incuse(void* md) {
+	if (md)
+		i2c_inc_use_client(((struct maven_data*)md)->client);
+}
+
+static void maven_out_decuse(void* md) {
+	if (md)
+		i2c_dec_use_client(((struct maven_data*)md)->client);
+}
+
+static int maven_out_set_mode(void* md, u_int32_t arg) {
+	return maven_set_output_mode(md, arg);
+}
+
+static int maven_out_get_mode(void* md, u_int32_t* arg) {
+	return maven_get_output_mode(md, arg);
+}
+
+static struct matrox_altout maven_altout = {
+	maven_out_compute,
+	maven_out_program,
+	maven_out_start,
+	maven_out_incuse,
+	maven_out_decuse,
+	maven_out_set_mode,
+	maven_out_get_mode
+};
+
+static int maven_init_client(struct i2c_client* clnt) {
+	struct i2c_adapter* a = clnt->adapter;
+	/* data are set to primary head... maybe I should change it */
+	struct matroxfb_dh_maven_info* m2info =
+		(struct matroxfb_dh_maven_info*)(((u_int8_t*)a) - offsetof(struct matroxfb_dh_maven_info, maven.adapter));
+	struct maven_data* md = clnt->data;
+	/* add some checks that m2info is matroxfb_dh_fb_info here... */
+	struct matrox_fb_info* minfo = m2info->primary_dev;
+
+	md->mode = MODE_MONITOR;
+	md->primary_head = MINFO;
+	md->client = clnt;
+	down_write(&ACCESS_FBINFO(altout.lock));
+	ACCESS_FBINFO(altout.device) = md;
+	ACCESS_FBINFO(altout.output) = &maven_altout;
+	up_write(&ACCESS_FBINFO(altout.lock));
+	ACCESS_FBINFO(output.all) |= MATROXFB_OUTPUT_CONN_SECONDARY;
+	return 0;
+}
+
+static int maven_shutdown_client(struct i2c_client* clnt) {
+	struct maven_data* md = clnt->data;
+
+	if (md->primary_head) {
+		md->primary_head->output.all &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
+		md->primary_head->output.ph &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
+		md->primary_head->output.sh &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
+		down_write(&md->primary_head->altout.lock);
+		md->primary_head->altout.device = NULL;
+		md->primary_head->altout.output = NULL;
+		up_write(&md->primary_head->altout.lock);
+		md->primary_head = NULL;
+	}
+	return 0;
+}
+
+static unsigned short normal_i2c[] = { MAVEN_I2CID, I2C_CLIENT_END };
+static unsigned short normal_i2c_range[] = { MAVEN_I2CID, MAVEN_I2CID, I2C_CLIENT_END };
+I2C_CLIENT_INSMOD;
+
+static void maven_inc_use(struct i2c_client* clnt) {
+	MOD_INC_USE_COUNT;
+}
+
+static void maven_dec_use(struct i2c_client* clnt) {
+	MOD_DEC_USE_COUNT;
+}
+
+static struct i2c_driver maven_driver;
+
+static int maven_detect_client(struct i2c_adapter* adapter, int address, unsigned short flags,
+		int kind) {
+	int err = 0;
+	struct i2c_client* new_client;
+	struct maven_data* data;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_WORD_DATA |
+					      I2C_FUNC_SMBUS_BYTE_DATA |
+					      I2C_FUNC_PROTOCOL_MANGLING))
+		goto ERROR0;
+	if (!(new_client = (struct i2c_client*)kmalloc(sizeof(struct i2c_client) + sizeof(struct maven_data),
+			GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto ERROR0;
+	}
+	data = (struct maven_data*)(new_client + 1);
+	new_client->data = data;
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &maven_driver;
+	new_client->flags = 0;
+	if (kind < 0) {
+		;
+	}
+	strcpy(new_client->name, "maven client");
+	if ((err = i2c_attach_client(new_client)))
+		goto ERROR3;
+	err = maven_init_client(new_client);
+	if (err)
+		goto ERROR4;
+	return 0;
+ERROR4:;
+	i2c_detach_client(new_client);
+ERROR3:;
+	kfree(new_client);
+ERROR0:;
+	return err;
+}
+
+static int maven_attach_adapter(struct i2c_adapter* adapter) {
+	if (adapter->id == (I2C_ALGO_BIT | I2C_HW_B_G400))
+		return i2c_probe(adapter, &addr_data, &maven_detect_client);
+	return 0;
+}
+
+static int maven_detach_client(struct i2c_client* client) {
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		printk(KERN_ERR "maven: Cannot deregister client\n");
+		return err;
+	}
+	maven_shutdown_client(client);
+	kfree(client);
+	return 0;
+}
+
+static int maven_command(struct i2c_client* client, unsigned int cmd, void* arg) {
+	return -ENOIOCTLCMD;	/* or -EINVAL, depends on who will call this */
+}
+
+static int maven_driver_registered = 0;
+
+static struct i2c_driver maven_driver={
+	"maven",
+	I2C_DRIVERID_MGATVO,
+	I2C_DF_NOTIFY,
+	maven_attach_adapter,
+	maven_detach_client,
+	maven_command,
+	maven_inc_use,
+	maven_dec_use
+};
+
+/* ************************** */
+
+static int matroxfb_maven_init(void) {
+	int err;
+
+	err = i2c_add_driver(&maven_driver);
+	if (err) {
+		printk(KERN_ERR "maven: Maven driver failed to register (%d).\n", err);
+		return err;
+	}
+	maven_driver_registered = 1;
+	return 0;
+}
+
+static void matroxfb_maven_exit(void) {
+	if (maven_driver_registered)
+		i2c_del_driver(&maven_driver);
+}
+
+MODULE_AUTHOR("(c) 1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>");
+MODULE_DESCRIPTION("Matrox G200/G400 Matrox MGA-TVO driver");
+module_init(matroxfb_maven_init);
+module_exit(matroxfb_maven_exit);
+/* we do not have __setup() yet */
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_maven.h linux/drivers/video/matrox/matroxfb_maven.h
--- v2.3.47/linux/drivers/video/matrox/matroxfb_maven.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_maven.h	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,23 @@
+#ifndef __MATROXFB_MAVEN_H__
+#define __MATROXFB_MAVEN_H__
+
+#include <linux/ioctl.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include "matroxfb_base.h"
+
+struct i2c_bit_adapter {
+	struct i2c_adapter		adapter;
+	int				initialized;
+	struct i2c_algo_bit_data	bac;
+};
+
+struct matroxfb_dh_maven_info {
+	struct matrox_fb_info*	primary_dev;
+
+	struct i2c_bit_adapter	maven;
+	struct i2c_bit_adapter	ddc1;
+	struct i2c_bit_adapter	ddc2;
+};
+
+#endif /* __MATROXFB_MAVEN_H__ */
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_misc.c linux/drivers/video/matrox/matroxfb_misc.c
--- v2.3.47/linux/drivers/video/matrox/matroxfb_misc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_misc.c	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,660 @@
+/*
+ *
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
+ *
+ * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>
+ *
+ * Version: 1.21 2000/01/09
+ *
+ * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
+ *
+ * Contributors: "menion?" <menion@mindless.com>
+ *                     Betatesting, fixes, ideas
+ *
+ *               "Kurt Garloff" <garloff@kg1.ping.de>
+ *                     Betatesting, fixes, ideas, videomodes, videomodes timmings
+ *
+ *               "Tom Rini" <trini@kernel.crashing.org>
+ *                     MTRR stuff, PPC cleanups, betatesting, fixes, ideas
+ *
+ *               "Bibek Sahu" <scorpio@dodds.net>
+ *                     Access device through readb|w|l and write b|w|l
+ *                     Extensive debugging stuff
+ *
+ *               "Daniel Haun" <haund@usa.net>
+ *                     Testing, hardware cursor fixes
+ *
+ *               "Scott Wood" <sawst46+@pitt.edu>
+ *                     Fixes
+ *
+ *               "Gerd Knorr" <kraxel@goldbach.isdn.cs.tu-berlin.de>
+ *                     Betatesting
+ *
+ *               "Kelly French" <targon@hazmat.com>
+ *               "Fernando Herrera" <fherrera@eurielec.etsit.upm.es>
+ *                     Betatesting, bug reporting
+ *
+ *               "Pablo Bianucci" <pbian@pccp.com.ar>
+ *                     Fixes, ideas, betatesting
+ *
+ *               "Inaky Perez Gonzalez" <inaky@peloncho.fis.ucm.es>
+ *                     Fixes, enhandcements, ideas, betatesting
+ *
+ *               "Ryuichi Oikawa" <roikawa@rr.iiij4u.or.jp>
+ *                     PPC betatesting, PPC support, backward compatibility
+ *
+ *               "Paul Womar" <Paul@pwomar.demon.co.uk>
+ *               "Owen Waller" <O.Waller@ee.qub.ac.uk>
+ *                     PPC betatesting
+ *
+ *               "Thomas Pornin" <pornin@bolet.ens.fr>
+ *                     Alpha betatesting
+ *
+ *               "Pieter van Leuven" <pvl@iae.nl>
+ *               "Ulf Jaenicke-Roessler" <ujr@physik.phy.tu-dresden.de>
+ *                     G100 testing
+ *
+ *               "H. Peter Arvin" <hpa@transmeta.com>
+ *                     Ideas
+ *
+ *               "Cort Dougan" <cort@cs.nmt.edu>
+ *                     CHRP fixes and PReP cleanup
+ *
+ *               "Mark Vojkovich" <mvojkovi@ucsd.edu>
+ *                     G400 support
+ *
+ * (following author is not in any relation with this code, but his code
+ *  is included in this driver)
+ *
+ * Based on framebuffer driver for VBE 2.0 compliant graphic boards
+ *     (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
+ *
+ * (following author is not in any relation with this code, but his ideas
+ *  were used when writting this driver)
+ *
+ *		 FreeVBE/AF (Matrox), "Shawn Hargreaves" <shawn@talula.demon.co.uk>
+ *
+ */
+
+/* make checkconfig does not check includes for this... */
+#include <linux/config.h>
+
+#include "matroxfb_misc.h"
+#include <linux/interrupt.h>
+#include <linux/matroxfb.h>
+
+void matroxfb_createcursorshape(WPMINFO struct display* p, int vmode) {
+	unsigned int h;
+	unsigned int cu, cd;
+
+	h = fontheight(p);
+
+	if (vmode & FB_VMODE_DOUBLE)
+		h *= 2;
+	cd = h;
+	if (cd >= 10)
+		cd--;
+	switch (ACCESS_FBINFO(cursor.type) = (p->conp->vc_cursor_type & CUR_HWMASK)) {
+		case CUR_NONE:
+				cu = cd;
+				break;
+		case CUR_UNDERLINE:
+				cu = cd - 2;
+				break;
+		case CUR_LOWER_THIRD:
+				cu = (h * 2) / 3;
+				break;
+		case CUR_LOWER_HALF:
+				cu = h / 2;
+				break;
+		case CUR_TWO_THIRDS:
+				cu = h / 3;
+				break;
+		case CUR_BLOCK:
+		default:
+				cu = 0;
+				cd = h;
+				break;
+	}
+	ACCESS_FBINFO(cursor.w) = fontwidth(p);
+	ACCESS_FBINFO(cursor.u) = cu;
+	ACCESS_FBINFO(cursor.d) = cd;
+}
+
+void matroxfb_DAC_out(CPMINFO int reg, int val) {
+	DBG_REG("outDAC");
+	mga_outb(M_RAMDAC_BASE+M_X_INDEX, reg);
+	mga_outb(M_RAMDAC_BASE+M_X_DATAREG, val);
+}
+
+int matroxfb_DAC_in(CPMINFO int reg) {
+	DBG_REG("inDAC");
+	mga_outb(M_RAMDAC_BASE+M_X_INDEX, reg);
+	return mga_inb(M_RAMDAC_BASE+M_X_DATAREG);
+}
+
+void matroxfb_var2my(struct fb_var_screeninfo* var, struct my_timming* mt) {
+	unsigned int pixclock = var->pixclock;
+
+	DBG("var2my")
+
+	if (!pixclock) pixclock = 10000;	/* 10ns = 100MHz */
+	mt->pixclock = 1000000000 / pixclock;
+	if (mt->pixclock < 1) mt->pixclock = 1;
+	mt->dblscan = var->vmode & FB_VMODE_DOUBLE;
+	mt->interlaced = var->vmode & FB_VMODE_INTERLACED;
+	mt->HDisplay = var->xres;
+	mt->HSyncStart = mt->HDisplay + var->right_margin;
+	mt->HSyncEnd = mt->HSyncStart + var->hsync_len;
+	mt->HTotal = mt->HSyncEnd + var->left_margin;
+	mt->VDisplay = var->yres;
+	mt->VSyncStart = mt->VDisplay + var->lower_margin;
+	mt->VSyncEnd = mt->VSyncStart + var->vsync_len;
+	mt->VTotal = mt->VSyncEnd + var->upper_margin;
+	mt->sync = var->sync;
+}
+
+int matroxfb_PLL_calcclock(const struct matrox_pll_features* pll, unsigned int freq, unsigned int fmax,
+		unsigned int* in, unsigned int* feed, unsigned int* post) {
+	unsigned int bestdiff = ~0;
+	unsigned int bestvco = 0;
+	unsigned int fxtal = pll->ref_freq;
+	unsigned int fwant;
+	unsigned int p;
+
+	DBG("PLL_calcclock")
+
+	fwant = freq;
+
+#ifdef DEBUG
+	printk(KERN_ERR "post_shift_max: %d\n", pll->post_shift_max);
+	printk(KERN_ERR "ref_freq: %d\n", pll->ref_freq);
+	printk(KERN_ERR "freq: %d\n", freq);
+	printk(KERN_ERR "vco_freq_min: %d\n", pll->vco_freq_min);
+	printk(KERN_ERR "in_div_min: %d\n", pll->in_div_min);
+	printk(KERN_ERR "in_div_max: %d\n", pll->in_div_max);
+	printk(KERN_ERR "feed_div_min: %d\n", pll->feed_div_min);
+	printk(KERN_ERR "feed_div_max: %d\n", pll->feed_div_max);
+	printk(KERN_ERR "fmax: %d\n", fmax);
+#endif
+	for (p = 1; p <= pll->post_shift_max; p++) {
+		if (fwant * 2 > fmax)
+			break;
+		fwant *= 2;
+	}
+	if (fwant < pll->vco_freq_min) fwant = pll->vco_freq_min;
+	if (fwant > fmax) fwant = fmax;
+	for (; p-- > 0; fwant >>= 1, bestdiff >>= 1) {
+		unsigned int m;
+
+		if (fwant < pll->vco_freq_min) break;
+		for (m = pll->in_div_min; m <= pll->in_div_max; m++) {
+			unsigned int diff, fvco;
+			unsigned int n;
+
+			n = (fwant * (m + 1) + (fxtal >> 1)) / fxtal - 1;
+			if (n > pll->feed_div_max)
+				break;
+			if (n < pll->feed_div_min)
+				n = pll->feed_div_min;
+			fvco = (fxtal * (n + 1)) / (m + 1);
+			if (fvco < fwant)
+				diff = fwant - fvco;
+			else
+				diff = fvco - fwant;
+			if (diff < bestdiff) {
+				bestdiff = diff;
+				*post = p;
+				*in = m;
+				*feed = n;
+				bestvco = fvco;
+			}
+		}
+	}
+	dprintk(KERN_ERR "clk: %02X %02X %02X %d %d %d\n", *in, *feed, *post, fxtal, bestvco, fwant);
+	return bestvco;
+}
+
+int matroxfb_vgaHWinit(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
+	unsigned int hd, hs, he, hbe, ht;
+	unsigned int vd, vs, ve, vt;
+	unsigned int wd;
+	unsigned int divider;
+	int i;
+	int text = p->type == FB_TYPE_TEXT;
+	int fwidth;
+
+	if (text) {
+		fwidth = fontwidth(p);
+		if (!fwidth) fwidth = 8;
+	} else
+		fwidth = 8;
+
+	DBG("vgaHWinit")
+
+	hw->SEQ[0] = 0x00;
+	if (fwidth == 9)
+		hw->SEQ[1] = 0x00;
+	else
+		hw->SEQ[1] = 0x01;	/* or 0x09 */
+	hw->SEQ[2] = 0x0F;	/* bitplanes */
+	hw->SEQ[3] = 0x00;
+	if (text)
+		hw->SEQ[4] = 0x02;
+	else
+		hw->SEQ[4] = 0x0E;
+	/* CRTC 0..7, 9, 16..19, 21, 22 are reprogrammed by Matrox Millennium code... Hope that by MGA1064 too */
+	if (m->dblscan) {
+		m->VTotal <<= 1;
+		m->VDisplay <<= 1;
+		m->VSyncStart <<= 1;
+		m->VSyncEnd <<= 1;
+	}
+	if (m->interlaced) {
+		m->VTotal >>= 1;
+		m->VDisplay >>= 1;
+		m->VSyncStart >>= 1;
+		m->VSyncEnd >>= 1;
+	}
+
+	/* GCTL is ignored when not using 0xA0000 aperture */
+	hw->GCTL[0] = 0x00;
+	hw->GCTL[1] = 0x00;
+	hw->GCTL[2] = 0x00;
+	hw->GCTL[3] = 0x00;
+	hw->GCTL[4] = 0x00;
+	if (text) {
+		hw->GCTL[5] = 0x10;
+		hw->GCTL[6] = 0x02;
+	} else {
+		hw->GCTL[5] = 0x40;
+		hw->GCTL[6] = 0x05;
+	}
+	hw->GCTL[7] = 0x0F;
+	hw->GCTL[8] = 0xFF;
+
+	/* Whole ATTR is ignored in PowerGraphics mode */
+	for (i = 0; i < 16; i++)
+		hw->ATTR[i] = i;
+	if (text) {
+		hw->ATTR[16] = 0x04;
+	} else {
+		hw->ATTR[16] = 0x41;
+	}
+	hw->ATTR[17] = 0xFF;
+	hw->ATTR[18] = 0x0F;
+	if (fwidth == 9)
+		hw->ATTR[19] = 0x08;
+	else
+		hw->ATTR[19] = 0x00;
+	hw->ATTR[20] = 0x00;
+
+	if (text) {
+		hd = m->HDisplay / fwidth;
+		hs = m->HSyncStart / fwidth;
+		he = m->HSyncEnd / fwidth;
+		ht = m->HTotal / fwidth;
+		divider = 8;
+	} else {
+		hd = m->HDisplay >> 3;
+		hs = m->HSyncStart >> 3;
+		he = m->HSyncEnd >> 3;
+		ht = m->HTotal >> 3;
+		/* standard timmings are in 8pixels, but for interleaved we cannot */
+		/* do it for 4bpp (because of (4bpp >> 1(interleaved))/4 == 0) */
+		/* using 16 or more pixels per unit can save us */
+		divider = ACCESS_FBINFO(curr.final_bppShift);
+	}
+	while (divider & 3) {
+		hd >>= 1;
+		hs >>= 1;
+		he >>= 1;
+		ht >>= 1;
+		divider <<= 1;
+	}
+	divider = divider / 4;
+	/* divider can be from 1 to 8 */
+	while (divider > 8) {
+		hd <<= 1;
+		hs <<= 1;
+		he <<= 1;
+		ht <<= 1;
+		divider >>= 1;
+	}
+	hd = hd - 1;
+	hs = hs - 1;
+	he = he - 1;
+	ht = ht - 1;
+	vd = m->VDisplay - 1;
+	vs = m->VSyncStart - 1;
+	ve = m->VSyncEnd - 1;
+	vt = m->VTotal - 2;
+	/* G200 cannot work with (ht & 7) == 6 */
+	if (((ht & 0x07) == 0x06) || ((ht & 0x0F) == 0x04))
+		ht++;
+	if (text) {
+		hbe = ht - 1;
+		wd = p->var.xres_virtual / (fwidth * 2);
+	} else {
+		hbe = ht;
+		wd = p->var.xres_virtual * ACCESS_FBINFO(curr.final_bppShift) / 64;
+	}
+
+	hw->CRTCEXT[0] = 0;
+	hw->CRTCEXT[5] = 0;
+	if (m->interlaced) {
+		hw->CRTCEXT[0] = 0x80;
+		hw->CRTCEXT[5] = (hs + he - ht) >> 1;
+		if (!m->dblscan)
+			wd <<= 1;
+		vt &= ~1;
+	}
+	hw->CRTCEXT[0] |=  (wd & 0x300) >> 4;
+	hw->CRTCEXT[1] = (((ht - 4) & 0x100) >> 8) |
+			  ((hd      & 0x100) >> 7) | /* blanking */
+			  ((hs      & 0x100) >> 6) | /* sync start */
+			   (hbe     & 0x040);	 /* end hor. blanking */
+	if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY)
+		hw->CRTCEXT[1] |= 0x88;		/* enable horizontal and vertical vidrst */
+	hw->CRTCEXT[2] =  ((vt & 0xC00) >> 10) |
+			  ((vd & 0x400) >>  8) |	/* disp end */
+			  ((vd & 0xC00) >>  7) |	/* vblanking start */
+			  ((vs & 0xC00) >>  5);
+	if (text)
+		hw->CRTCEXT[3] = 0x00;
+	else
+		hw->CRTCEXT[3] = (divider - 1) | 0x80;
+	hw->CRTCEXT[4] = 0;
+
+	hw->CRTC[0] = ht-4;
+	hw->CRTC[1] = hd;
+	hw->CRTC[2] = hd;
+	hw->CRTC[3] = (hbe & 0x1F) | 0x80;
+	hw->CRTC[4] = hs;
+	hw->CRTC[5] = ((hbe & 0x20) << 2) | (he & 0x1F);
+	if (text)
+		hw->CRTC[5] |= 0x60;	/* delay sync for 3 clocks (to same picture position on MGA and VGA) */
+	hw->CRTC[6] = vt & 0xFF;
+	hw->CRTC[7] = ((vt & 0x100) >> 8) |
+		      ((vd & 0x100) >> 7) |
+		      ((vs & 0x100) >> 6) |
+		      ((vd & 0x100) >> 5) |
+		      0x10                |
+		      ((vt & 0x200) >> 4) |
+		      ((vd & 0x200) >> 3) |
+		      ((vs & 0x200) >> 2);
+	hw->CRTC[8] = 0x00;
+	hw->CRTC[9] = ((vd & 0x200) >> 4) | 0x40;
+	if (text)
+		hw->CRTC[9] |= fontheight(p) - 1;
+	if (m->dblscan && !m->interlaced)
+		hw->CRTC[9] |= 0x80;
+	for (i = 10; i < 16; i++)
+		hw->CRTC[i] = 0x00;
+	hw->CRTC[16] = vs /* & 0xFF */;
+	hw->CRTC[17] = (ve & 0x0F) | 0x20;
+	hw->CRTC[18] = vd /* & 0xFF */;
+	hw->CRTC[19] = wd /* & 0xFF */;
+	hw->CRTC[20] = 0x00;
+	hw->CRTC[21] = vd /* & 0xFF */;
+	hw->CRTC[22] = (vt + 1) /* & 0xFF */;
+	if (text) {
+		if (ACCESS_FBINFO(devflags.textmode) == 1)
+			hw->CRTC[23] = 0xC3;
+		else
+			hw->CRTC[23] = 0xA3;
+		if (ACCESS_FBINFO(devflags.textmode) == 4)
+			hw->CRTC[20] = 0x5F;
+		else
+			hw->CRTC[20] = 0x1F;
+	} else
+		hw->CRTC[23] = 0xC3;
+	hw->CRTC[24] = 0xFF;
+	return 0;
+};
+
+void matroxfb_vgaHWrestore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw) {
+	int i;
+	CRITFLAGS
+
+	DBG("vgaHWrestore")
+
+	dprintk(KERN_INFO "MiscOutReg: %02X\n", hw->MiscOutReg);
+	dprintk(KERN_INFO "SEQ regs:   ");
+	for (i = 0; i < 5; i++)
+		dprintk("%02X:", hw->SEQ[i]);
+	dprintk("\n");
+	dprintk(KERN_INFO "GDC regs:   ");
+	for (i = 0; i < 9; i++)
+		dprintk("%02X:", hw->GCTL[i]);
+	dprintk("\n");
+	dprintk(KERN_INFO "CRTC regs: ");
+	for (i = 0; i < 25; i++)
+		dprintk("%02X:", hw->CRTC[i]);
+	dprintk("\n");
+	dprintk(KERN_INFO "ATTR regs: ");
+	for (i = 0; i < 21; i++)
+		dprintk("%02X:", hw->ATTR[i]);
+	dprintk("\n");
+
+	CRITBEGIN
+
+	mga_inb(M_ATTR_RESET);
+	mga_outb(M_ATTR_INDEX, 0);
+	mga_outb(M_MISC_REG, hw->MiscOutReg);
+	for (i = 1; i < 5; i++)
+		mga_setr(M_SEQ_INDEX, i, hw->SEQ[i]);
+	mga_setr(M_CRTC_INDEX, 17, hw->CRTC[17] & 0x7F);
+	for (i = 0; i < 25; i++)
+		mga_setr(M_CRTC_INDEX, i, hw->CRTC[i]);
+	for (i = 0; i < 9; i++)
+		mga_setr(M_GRAPHICS_INDEX, i, hw->GCTL[i]);
+	for (i = 0; i < 21; i++) {
+		mga_inb(M_ATTR_RESET);
+		mga_outb(M_ATTR_INDEX, i);
+		mga_outb(M_ATTR_INDEX, hw->ATTR[i]);
+	}
+	mga_outb(M_PALETTE_MASK, 0xFF);
+	mga_outb(M_DAC_REG, 0x00);
+	for (i = 0; i < 768; i++)
+		mga_outb(M_DAC_VAL, hw->DACpal[i]);
+	mga_inb(M_ATTR_RESET);
+	mga_outb(M_ATTR_INDEX, 0x20);
+
+	CRITEND
+}
+
+void matroxfb_fastfont_init(struct matrox_fb_info* minfo){
+	unsigned int size;
+
+	size = ACCESS_FBINFO(fastfont.size);
+	ACCESS_FBINFO(fastfont.size) = 0;
+	if (size) {
+		unsigned int end = ACCESS_FBINFO(video.len_usable);
+
+		if (size < end) {
+			unsigned int start;
+
+			start = (end - size) & PAGE_MASK;
+			if (start >= 0x00100000) {
+				ACCESS_FBINFO(video.len_usable) = start;
+				ACCESS_FBINFO(fastfont.mgabase) = start * 8;
+				ACCESS_FBINFO(fastfont.vbase) = ACCESS_FBINFO(video.vbase);
+				vaddr_add(&ACCESS_FBINFO(fastfont.vbase), start);
+				ACCESS_FBINFO(fastfont.size) = end - start;
+			}
+		}
+	}
+}
+
+#ifndef FNTCHARCNT
+#define FNTCHARCNT(fd)	(((int *)(fd))[-3])
+#endif
+
+int matrox_text_loadfont(WPMINFO struct display* p) {
+	unsigned int fsize;
+	unsigned int width;
+	vaddr_t dst;
+	unsigned int i;
+	u_int8_t* font;
+	CRITFLAGS
+
+	if (!p || !p->fontdata)
+		return 0;
+	width = fontwidth(p);
+	fsize = p->userfont?FNTCHARCNT(p->fontdata):256;
+
+	dst = ACCESS_FBINFO(video.vbase);
+	i = 2;
+	font = (u_int8_t*)p->fontdata;
+
+	CRITBEGIN
+
+	mga_setr(M_SEQ_INDEX, 0x02, 0x04);
+	while (fsize--) {
+		int l;
+
+		for (l = 0; l < fontheight(p); l++) {
+			mga_writeb(dst, i, *font++);
+			if (fontwidth(p) > 8) font++;
+			i += ACCESS_FBINFO(devflags.vgastep);
+		}
+		i += (32 - fontheight(p)) * ACCESS_FBINFO(devflags.vgastep);
+	}
+	mga_setr(M_SEQ_INDEX, 0x02, 0x03);
+
+	CRITEND
+
+	return 1;
+}
+
+int matroxfb_fastfont_tryset(WPMINFO struct display* p) {
+	unsigned int fsize;
+	unsigned int width;
+	CRITFLAGS
+
+	if (!p || !p->fontdata)
+		return 0;
+	width = fontwidth(p);
+	if (width > 32)
+		return 0;
+	fsize = (p->userfont?FNTCHARCNT(p->fontdata):256) * fontheight(p);
+	if (((fsize * width + 31) / 32) * 4 > ACCESS_FBINFO(fastfont.size))
+		return 0;
+
+	CRITBEGIN
+
+	mga_outl(M_OPMODE, M_OPMODE_8BPP);
+	if (width <= 8) {
+		if (width == 8)
+			mga_memcpy_toio(ACCESS_FBINFO(fastfont.vbase), 0, p->fontdata, fsize);
+		else {
+			vaddr_t dst;
+			unsigned int i;
+			u_int8_t* font;
+			u_int32_t mask, valid, reg;
+
+			dst = ACCESS_FBINFO(fastfont.vbase);
+			font = (u_int8_t*)p->fontdata;
+			mask = ~0 << (8 - width);
+			valid = 0;
+			reg = 0;
+			i = 0;
+			while (fsize--) {
+				reg |= (*font++ & mask) << (8 - valid);
+				valid += width;
+				if (valid >= 8) {
+					mga_writeb(dst, i++, reg >> 8);
+					reg = reg << 8;
+					valid -= 8;
+				}
+			}
+			if (valid)
+				mga_writeb(dst, i, reg >> 8);
+		}
+	} else if (width <= 16) {
+		if (width == 16)
+			mga_memcpy_toio(ACCESS_FBINFO(fastfont.vbase), 0, p->fontdata, fsize*2);
+		else {
+			vaddr_t dst;
+			u_int16_t* font;
+			u_int32_t mask, valid, reg;
+			unsigned int i;
+
+			dst = ACCESS_FBINFO(fastfont.vbase);
+			font = (u_int16_t*)p->fontdata;
+			mask = ~0 << (16 - width);
+			valid = 0;
+			reg = 0;
+			i = 0;
+			while (fsize--) {
+				reg |= (ntohs(*font++) & mask) << (16 - valid);
+				valid += width;
+				if (valid >= 16) {
+					mga_writew(dst, i, htons(reg >> 16));
+					i += 2;
+					reg = reg << 16;
+					valid -= 16;
+				}
+			}
+			if (valid)
+				mga_writew(dst, i, htons(reg >> 16));
+		}
+	} else {
+		if (width == 32)
+			mga_memcpy_toio(ACCESS_FBINFO(fastfont.vbase), 0, p->fontdata, fsize*4);
+		else {
+			vaddr_t dst;
+			u_int32_t* font;
+			u_int32_t mask, valid, reg;
+			unsigned int i;
+
+			dst = ACCESS_FBINFO(fastfont.vbase);
+			font = (u_int32_t*)p->fontdata;
+			mask = ~0 << (32 - width);
+			valid = 0;
+			reg = 0;
+			i = 0;
+			while (fsize--) {
+				reg |= (ntohl(*font) & mask) >> valid;
+				valid += width;
+				if (valid >= 32) {
+					mga_writel(dst, i, htonl(reg));
+					i += 4;
+					valid -= 32;
+					if (valid)
+						reg = (ntohl(*font) & mask) << (width - valid);
+					else
+						reg = 0;
+				}
+				font++;
+			}
+			if (valid)
+				mga_writel(dst, i, htonl(reg));
+		}
+	}
+	mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
+
+	CRITEND
+
+	return 1;
+}
+
+EXPORT_SYMBOL(matroxfb_DAC_in);
+EXPORT_SYMBOL(matroxfb_DAC_out);
+EXPORT_SYMBOL(matroxfb_var2my);
+EXPORT_SYMBOL(matroxfb_PLL_calcclock);
+#ifndef CONFIG_FB_MATROX_MULTIHEAD
+struct matrox_fb_info matroxfb_global_mxinfo;
+EXPORT_SYMBOL(matroxfb_global_mxinfo);
+#endif
+EXPORT_SYMBOL(matrox_text_loadfont);	/* for matroxfb_accel */
+EXPORT_SYMBOL(matroxfb_createcursorshape);	/* accel, DAC1064, Ti3026 */
+EXPORT_SYMBOL(matroxfb_fastfont_tryset);	/* accel */
+EXPORT_SYMBOL(matroxfb_fastfont_init);		/* DAC1064, Ti3026 */
+EXPORT_SYMBOL(matroxfb_vgaHWinit);		/* DAC1064, Ti3026 */
+EXPORT_SYMBOL(matroxfb_vgaHWrestore);		/* DAC1064, Ti3026 */
+#ifdef MATROXFB_USE_SPINLOCK
+spinlock_t matroxfb_spinlock = SPIN_LOCK_UNLOCKED;
+EXPORT_SYMBOL(matroxfb_spinlock);
+#endif
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matrox/matroxfb_misc.h linux/drivers/video/matrox/matroxfb_misc.h
--- v2.3.47/linux/drivers/video/matrox/matroxfb_misc.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/matrox/matroxfb_misc.h	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,21 @@
+#ifndef __MATROXFB_MISC_H__
+#define __MATROXFB_MISC_H__
+
+#include "matroxfb_base.h"
+
+/* also for modules */
+int matroxfb_PLL_calcclock(const struct matrox_pll_features* pll, unsigned int freq, unsigned int fmax,
+	unsigned int* in, unsigned int* feed, unsigned int* post);
+static inline int PLL_calcclock(CPMINFO unsigned int freq, unsigned int fmax,
+		unsigned int* in, unsigned int* feed, unsigned int* post) {
+	return matroxfb_PLL_calcclock(&ACCESS_FBINFO(features.pll), freq, fmax, in, feed, post);
+}
+
+void matroxfb_createcursorshape(WPMINFO struct display* p, int vmode);
+int matroxfb_vgaHWinit(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p);
+void matroxfb_vgaHWrestore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw);
+void matroxfb_fastfont_init(struct matrox_fb_info* minfo);
+int matrox_text_loadfont(WPMINFO struct display* p);
+int matroxfb_fastfont_tryset(WPMINFO struct display* p);
+
+#endif	/* __MATROXFB_MISC_H__ */
diff -u --recursive --new-file v2.3.47/linux/drivers/video/matroxfb.c linux/drivers/video/matroxfb.c
--- v2.3.47/linux/drivers/video/matroxfb.c	Wed Feb 16 17:03:52 2000
+++ linux/drivers/video/matroxfb.c	Wed Dec 31 16:00:00 1969
@@ -1,6107 +0,0 @@
-/*
- *
- * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
- *
- * (c) 1998,1999 Petr Vandrovec <vandrove@vc.cvut.cz>
- *
- * Version: 1.19 1999/08/05
- *
- * MTRR stuff: 1998 Tom Rini <tmrini@ntplx.net>
- *
- * Contributors: "menion?" <menion@mindless.com>
- *                     Betatesting, fixes, ideas
- *
- *               "Kurt Garloff" <garloff@kg1.ping.de>
- *                     Betatesting, fixes, ideas, videomodes, videomodes timmings
- *
- *               "Tom Rini" <trini@disparity.net>
- *                     MTRR stuff, PPC cleanups, betatesting, fixes, ideas
- *
- *               "Bibek Sahu" <scorpio@dodds.net>
- *                     Access device through readb|w|l and write b|w|l
- *                     Extensive debugging stuff
- *
- *               "Daniel Haun" <haund@usa.net>
- *                     Testing, hardware cursor fixes
- *
- *               "Scott Wood" <sawst46+@pitt.edu>
- *                     Fixes
- *
- *               "Gerd Knorr" <kraxel@goldbach.isdn.cs.tu-berlin.de>
- *                     Betatesting
- *
- *               "Kelly French" <targon@hazmat.com>
- *               "Fernando Herrera" <fherrera@eurielec.etsit.upm.es>
- *                     Betatesting, bug reporting
- *
- *               "Pablo Bianucci" <pbian@pccp.com.ar>
- *                     Fixes, ideas, betatesting
- *
- *               "Inaky Perez Gonzalez" <inaky@peloncho.fis.ucm.es>
- *                     Fixes, enhandcements, ideas, betatesting
- *
- *               "Ryuichi Oikawa" <roikawa@rr.iiij4u.or.jp>
- *                     PPC betatesting, PPC support, backward compatibility
- *
- *               "Paul Womar" <Paul@pwomar.demon.co.uk>
- *               "Owen Waller" <O.Waller@ee.qub.ac.uk>
- *                     PPC betatesting 
- *
- *               "Thomas Pornin" <pornin@bolet.ens.fr>
- *                     Alpha betatesting
- *
- *               "Pieter van Leuven" <pvl@iae.nl>
- *               "Ulf Jaenicke-Roessler" <ujr@physik.phy.tu-dresden.de>
- *                     G100 testing
- *
- *               "H. Peter Arvin" <hpa@transmeta.com>
- *                     Ideas
- *
- *               "Cort Dougan" <cort@cs.nmt.edu>
- *                     CHRP fixes and PReP cleanup
- *
- *               "Mark Vojkovich" <mvojkovi@ucsd.edu>
- *                     G400 support
- *
- * (following author is not in any relation with this code, but his code
- *  is included in this driver)
- *
- * Based on framebuffer driver for VBE 2.0 compliant graphic boards
- *     (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
- *
- * (following author is not in any relation with this code, but his ideas
- *  were used when writting this driver)
- *
- *		 FreeVBE/AF (Matrox), "Shawn Hargreaves" <shawn@talula.demon.co.uk>
- *
- */ 
-
-/* general, but fairly heavy, debugging */
-#undef MATROXFB_DEBUG
-
-/* heavy debugging: */
-/* -- logs putc[s], so everytime a char is displayed, it's logged */
-#undef MATROXFB_DEBUG_HEAVY
-
-/* This one _could_ cause infinite loops */
-/* It _does_ cause lots and lots of messages during idle loops */
-#undef MATROXFB_DEBUG_LOOP 
-
-/* Debug register calls, too? */
-#undef MATROXFB_DEBUG_REG
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/malloc.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/console.h>
-#include <linux/selection.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/timer.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include <asm/io.h>
-#include <asm/unaligned.h>
-#ifdef CONFIG_MTRR
-#include <asm/mtrr.h>
-#endif
-
-#include <video/fbcon.h>
-#include <video/fbcon-cfb4.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-
-#if defined(CONFIG_FB_OF)
-#if defined(CONFIG_FB_COMPAT_XPMAC)
-#include <asm/vc_ioctl.h>
-#endif
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <video/macmodes.h>
-#endif
-
-/* always compile support for 32MB... It cost almost nothing */
-#define CONFIG_FB_MATROX_32MB
-
-#define FBCON_HAS_VGATEXT
-
-#ifdef MATROXFB_DEBUG
-
-#define DEBUG
-#define DBG(x)		printk(KERN_DEBUG "matroxfb: %s\n", (x));
-
-#ifdef MATROXFB_DEBUG_HEAVY
-#define DBG_HEAVY(x)	DBG(x)
-#else /* MATROXFB_DEBUG_HEAVY */
-#define DBG_HEAVY(x)	/* DBG_HEAVY */
-#endif /* MATROXFB_DEBUG_HEAVY */
-
-#ifdef MATROXFB_DEBUG_LOOP
-#define DBG_LOOP(x)	DBG(x)
-#else /* MATROXFB_DEBUG_LOOP */
-#define DBG_LOOP(x)	/* DBG_LOOP */
-#endif /* MATROXFB_DEBUG_LOOP */
-
-#ifdef MATROXFB_DEBUG_REG
-#define DBG_REG(x)	DBG(x)
-#else /* MATROXFB_DEBUG_REG */
-#define DBG_REG(x)	/* DBG_REG */
-#endif /* MATROXFB_DEBUG_REG */
-
-#else /* MATROXFB_DEBUG */
-
-#define DBG(x)		/* DBG */
-#define DBG_HEAVY(x)	/* DBG_HEAVY */
-#define DBG_REG(x)	/* DBG_REG */
-#define DBG_LOOP(x)	/* DBG_LOOP */
-
-#endif /* MATROXFB_DEBUG */
-
-#ifndef __i386__
-#ifndef ioremap_nocache
-#define ioremap_nocache(X,Y) ioremap(X,Y)
-#endif 
-#endif
-
-#if defined(__alpha__) || defined(__m68k__)
-#define READx_WORKS
-#define MEMCPYTOIO_WORKS
-#else
-#define READx_FAILS
-/* recheck __ppc__, maybe that __ppc__ needs MEMCPYTOIO_WRITEL */
-/* I benchmarked PII/350MHz with G200... MEMCPY, MEMCPYTOIO and WRITEL are on same speed ( <2% diff) */
-/* so that means that G200 speed (or AGP speed?) is our limit... I do not have benchmark to test, how */
-/* much of PCI bandwidth is used during transfers... */
-#if defined(__i386__)
-#define MEMCPYTOIO_MEMCPY
-#else
-#define MEMCPYTOIO_WRITEL
-#endif
-#endif
-
-#ifdef __sparc__
-#error "Sorry, I have no idea how to do this on sparc... There is mapioaddr... With bus_type parameter..."
-#endif
-
-#if defined(__m68k__)
-#define MAP_BUSTOVIRT
-#else
-#define MAP_IOREMAP
-#endif
-
-#ifdef DEBUG
-#define dprintk(X...)	printk(X)
-#else
-#define dprintk(X...)
-#endif
-
-#ifndef PCI_SS_VENDOR_ID_SIEMENS_NIXDORF
-#define PCI_SS_VENDOR_ID_SIEMENS_NIXDORF	0x110A
-#endif
-#ifndef PCI_SS_VENDOR_ID_MATROX
-#define PCI_SS_VENDOR_ID_MATROX		PCI_VENDOR_ID_MATROX
-#endif
-#ifndef PCI_DEVICE_ID_MATROX_G200_PCI
-#define PCI_DEVICE_ID_MATROX_G200_PCI	0x0520
-#endif
-#ifndef PCI_DEVICE_ID_MATROX_G200_AGP
-#define PCI_DEVICE_ID_MATROX_G200_AGP	0x0521
-#endif
-#ifndef PCI_DEVICE_ID_MATROX_G100
-#define PCI_DEVICE_ID_MATROX_G100	0x1000
-#endif
-#ifndef PCI_DEVICE_ID_MATROX_G100_AGP
-#define PCI_DEVICE_ID_MATROX_G100_AGP	0x1001
-#endif
-#ifndef PCI_DEVICE_ID_MATROX_G400_AGP
-#define PCI_DEVICE_ID_MATROX_G400_AGP	0x0525
-#endif
-
-#ifndef PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP
-#define PCI_SS_ID_MATROX_GENERIC		0xFF00
-#define PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP	0xFF01
-#define PCI_SS_ID_MATROX_MYSTIQUE_G200_AGP	0xFF02
-#define PCI_SS_ID_MATROX_MILLENIUM_G200_AGP	0xFF03
-#define PCI_SS_ID_MATROX_MARVEL_G200_AGP	0xFF04
-#define PCI_SS_ID_MATROX_MGA_G100_PCI		0xFF05
-#define PCI_SS_ID_MATROX_MGA_G100_AGP		0x1001
-#define PCI_SS_ID_SIEMENS_MGA_G100_AGP		0x001E /* 30 */
-#define PCI_SS_ID_SIEMENS_MGA_G200_AGP		0x0032 /* 50 */
-#endif
-
-#define MX_VISUAL_TRUECOLOR	FB_VISUAL_DIRECTCOLOR
-#define MX_VISUAL_DIRECTCOLOR	FB_VISUAL_TRUECOLOR
-#define MX_VISUAL_PSEUDOCOLOR	FB_VISUAL_PSEUDOCOLOR
-
-#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
-
-/* G100, G200 and Mystique have (almost) same DAC */
-#undef NEED_DAC1064
-#if defined(CONFIG_FB_MATROX_MYSTIQUE) || defined(CONFIG_FB_MATROX_G100)
-#define NEED_DAC1064 1
-#endif
-
-typedef struct {
-	u_int8_t*	vaddr;
-} vaddr_t;
-
-#ifdef READx_WORKS
-static inline unsigned int mga_readb(vaddr_t va, unsigned int offs) {
-	return readb(va.vaddr + offs);
-}
-
-static inline unsigned int mga_readw(vaddr_t va, unsigned int offs) {
-	return readw(va.vaddr + offs);
-}
-
-static inline u_int32_t mga_readl(vaddr_t va, unsigned int offs) {
-	return readl(va.vaddr + offs);
-}
-
-static inline void mga_writeb(vaddr_t va, unsigned int offs, u_int8_t value) {
-	writeb(value, va.vaddr + offs);
-}
-
-static inline void mga_writew(vaddr_t va, unsigned int offs, u_int16_t value) {
-	writew(value, va.vaddr + offs);
-}
-
-static inline void mga_writel(vaddr_t va, unsigned int offs, u_int32_t value) {
-	writel(value, va.vaddr + offs);
-}
-#else
-static inline unsigned int mga_readb(vaddr_t va, unsigned int offs) {
-	return *(volatile u_int8_t*)(va.vaddr + offs);
-}
-
-static inline unsigned int mga_readw(vaddr_t va, unsigned int offs) {
-	return *(volatile u_int16_t*)(va.vaddr + offs);
-}
-
-static inline u_int32_t mga_readl(vaddr_t va, unsigned int offs) {
-	return *(volatile u_int32_t*)(va.vaddr + offs);
-}
-
-static inline void mga_writeb(vaddr_t va, unsigned int offs, u_int8_t value) {
-	*(volatile u_int8_t*)(va.vaddr + offs) = value;
-}
-
-static inline void mga_writew(vaddr_t va, unsigned int offs, u_int16_t value) {
-	*(volatile u_int16_t*)(va.vaddr + offs) = value;
-}
-
-static inline void mga_writel(vaddr_t va, unsigned int offs, u_int32_t value) {
-	*(volatile u_int32_t*)(va.vaddr + offs) = value;
-}
-#endif
-
-static inline void mga_memcpy_toio(vaddr_t va, unsigned int offs, const void* src, int len) {
-#ifdef MEMCPYTOIO_WORKS
-	memcpy_toio(va.vaddr + offs, src, len);
-#elif defined(MEMCPYTOIO_WRITEL)
-#define srcd ((const u_int32_t*)src)
-	if (offs & 3) {
-		while (len >= 4) {
-			mga_writel(va, offs, get_unaligned(srcd++));
-			offs += 4;
-			len -= 4;
-		}
-	} else {
-		while (len >= 4) {
-			mga_writel(va, offs, *srcd++);
-			offs += 4;
-			len -= 4;
-		}
-	}
-#undef srcd
-	if (len) {
-		u_int32_t tmp;
-
-		memcpy(&tmp, src, len);
-		mga_writel(va, offs, tmp);
-	}
-#elif defined(MEMCPYTOIO_MEMCPY)
-	memcpy(va.vaddr + offs, src, len);
-#else
-#error "Sorry, do not know how to write block of data to device"
-#endif
-}
-
-static inline void vaddr_add(vaddr_t* va, unsigned long offs) {
-	va->vaddr += offs;
-}
-
-static inline void* vaddr_va(vaddr_t va) {
-	return va.vaddr;
-}
-
-#define MGA_IOREMAP_NORMAL	0
-#define MGA_IOREMAP_NOCACHE	1
-
-#define MGA_IOREMAP_FB		MGA_IOREMAP_NOCACHE
-#define MGA_IOREMAP_MMIO	MGA_IOREMAP_NOCACHE
-static inline int mga_ioremap(unsigned long phys, unsigned long size, int flags, vaddr_t* virt) {
-#ifdef MAP_IOREMAP
-	if (flags & MGA_IOREMAP_NOCACHE)
-		virt->vaddr = ioremap_nocache(phys, size);
-	else
-		virt->vaddr = ioremap(phys, size);
-#else
-#ifdef MAP_BUSTOVIRT
-	virt->vaddr = bus_to_virt(phys);
-#else
-#error "Your architecture does not have neither ioremap nor bus_to_virt... Giving up"
-#endif
-#endif
-	return (virt->vaddr == 0); /* 0, !0... 0, error_code in future */
-}
-
-static inline void mga_iounmap(vaddr_t va) {
-#ifdef MAP_IOREMAP
-	iounmap(va.vaddr);
-#endif
-}
-
-struct matroxfb_par
-{
-	unsigned int	final_bppShift;
-	unsigned int	cmap_len;
-	struct {
-		unsigned int bytes;
-		unsigned int pixels;
-		unsigned int chunks;
-		      } ydstorg;
-	void		(*putc)(u_int32_t, u_int32_t, struct display*, int, int, int);
-	void		(*putcs)(u_int32_t, u_int32_t, struct display*, const unsigned short*, int, int, int);
-};
-
-struct my_timming {
-	unsigned int pixclock;
-	unsigned int HDisplay;
-	unsigned int HSyncStart;
-	unsigned int HSyncEnd;
-	unsigned int HTotal;
-	unsigned int VDisplay;
-	unsigned int VSyncStart;
-	unsigned int VSyncEnd;
-	unsigned int VTotal;
-	unsigned int sync;
-	int	     dblscan;
-	int	     interlaced;
-};
-
-struct matrox_fb_info;
-
-#define MATROX_2MB_WITH_4MB_ADDON
-
-struct matrox_pll_features {
-	unsigned int	vco_freq_min;	
-	unsigned int	ref_freq;
-	unsigned int	feed_div_min;
-	unsigned int	feed_div_max;
-	unsigned int	in_div_min;
-	unsigned int	in_div_max;
-	unsigned int	post_shift_max;
-};
-
-struct matrox_DAC1064_features {
-	u_int8_t	xvrefctrl;
-	unsigned int	cursorimage;
-};
-
-struct matrox_accel_features {
-	int		has_cacheflush;
-};
-
-/* current hardware status */
-struct matrox_hw_state {
-	u_int32_t	MXoptionReg;
-	unsigned char	DACclk[6];
-	unsigned char	DACreg[64];
-	unsigned char	MiscOutReg;
-	unsigned char	DACpal[768];
-	unsigned char	CRTC[25];
-	unsigned char	CRTCEXT[9];
-	unsigned char	SEQ[5];
-	/* unused for MGA mode, but who knows... */
-	unsigned char	GCTL[9];
-	/* unused for MGA mode, but who knows... */
-	unsigned char	ATTR[21];
-};
-
-struct matrox_accel_data {
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-	unsigned char	ramdac_rev;
-#endif
-	u_int32_t	m_dwg_rect;
-	u_int32_t	m_opmode;
-};
-
-#ifdef CONFIG_FB_MATROX_MULTIHEAD
-#define ACCESS_FBINFO2(info, x) (info->x)
-#define ACCESS_FBINFO(x) ACCESS_FBINFO2(minfo,x)
-
-#define MINFO minfo
-
-#define WPMINFO struct matrox_fb_info* minfo,
-#define CPMINFO	const struct matrox_fb_info* minfo,
-#define PMINFO  minfo,
-
-static inline struct matrox_fb_info* mxinfo(const struct display* p) {
-	return (struct matrox_fb_info*)p->fb_info;
-}
-
-#define PMXINFO(p) mxinfo(p),
-#define MINFO_FROM(x)	   struct matrox_fb_info* minfo = x
-#define MINFO_FROM_DISP(x) MINFO_FROM(mxinfo(x))
-
-#else
-
-struct matrox_fb_info global_mxinfo;
-struct display global_disp;
-
-#define ACCESS_FBINFO(x) (global_mxinfo.x)
-#define ACCESS_FBINFO2(info, x) (global_mxinfo.x)
-
-#define MINFO (&global_mxinfo)
-
-#define WPMINFO
-#define CPMINFO
-#define PMINFO
-
-#if 0
-static inline struct matrox_fb_info* mxinfo(const struct display* p) {
-	return &global_mxinfo;
-}
-#endif
-
-#define PMXINFO(p)
-#define MINFO_FROM(x)
-#define MINFO_FROM_DISP(x)
-
-#endif
-
-struct matrox_switch {
-	int	(*preinit)(WPMINFO struct matrox_hw_state*);
-	void	(*reset)(WPMINFO struct matrox_hw_state*);
-	int	(*init)(CPMINFO struct matrox_hw_state*, struct my_timming*, struct display*);
-	void	(*restore)(WPMINFO struct matrox_hw_state*, struct matrox_hw_state*, struct display*);
-};
-
-struct matrox_fb_info {
-	/* fb_info must be first */
-	struct fb_info		fbcon;
-
-	struct matrox_fb_info*	next_fb;
-
-	struct matroxfb_par	curr;
-	struct matrox_hw_state	hw1;
-	struct matrox_hw_state	hw2;
-	struct matrox_hw_state*	newhw;
-	struct matrox_hw_state*	currenthw;
-
-	struct matrox_accel_data accel;
-
-	struct pci_dev*		pcidev;
-
-	struct {
-	unsigned long	base;	/* physical */
-	vaddr_t		vbase;	/* CPU view */
-	unsigned int	len;
-	unsigned int	len_usable;
-		      } video;
-
-	struct {
-	unsigned long	base;	/* physical */
-	vaddr_t		vbase;	/* CPU view */
-	unsigned int	len;
-		      } mmio;
-
-	unsigned int	max_pixel_clock;
-
-	struct matrox_switch*	hw_switch;
-	int		currcon;
-	struct display*	currcon_display;
-
-	struct {
-		struct matrox_pll_features pll;
-		struct matrox_DAC1064_features DAC1064;
-		struct matrox_accel_features accel;
-			      } features;
-	struct {
-		spinlock_t	DAC;
-			      } lock;
-
-	int			interleave;
-	int			millenium;
-	int			milleniumII;
-	struct {
-		int		cfb4;
-		const int*	vxres;
-		int		cross4MB;
-		int		text;
-		int		plnwt;
-			      } capable;
-	struct {
-		unsigned int	size;
-		unsigned int	mgabase;
-		vaddr_t		vbase;
-			      } fastfont;
-#ifdef CONFIG_MTRR
-	struct {
-		int		vram;
-		int		vram_valid;
-			      } mtrr;
-#endif
-	struct {
-		int		precise_width;
-		int		mga_24bpp_fix;
-		int		novga;
-		int		nobios;
-		int		nopciretry;
-		int		noinit;
-		int		inverse;
-		int		hwcursor;
-		int		blink;
-		int		sgram;
-#ifdef CONFIG_FB_MATROX_32MB
-		int		support32MB;
-#endif
-
-		int		accelerator;
-		int		text_type_aux;
-		int		video64bits;
-		unsigned int	vgastep;
-		unsigned int	textmode;
-		unsigned int	textstep;
-		unsigned int	textvram;	/* character cells */
-		unsigned int	ydstorg;	/* offset in bytes from video start to usable memory */
-						/* 0 except for 6MB Millenium */
-			      } devflags;
-	struct display_switch	dispsw;
-	struct {
-		int		x;
-		int		y;
-		unsigned int	w;
-		unsigned int	u;
-		unsigned int	d;
-		unsigned int	type;
-		int		state;
-		int		redraw;
-		struct timer_list timer;
-			      } cursor;
-#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
-	union {
-#ifdef FBCON_HAS_CFB16
-		u_int16_t	cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB24
-		u_int32_t	cfb24[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-		u_int32_t	cfb32[16];
-#endif
-	} cmap;
-#endif
-	struct { unsigned red, green, blue, transp; } palette[256];
-#if defined(CONFIG_FB_OF) && defined(CONFIG_FB_COMPAT_XPMAC)
-	char	matrox_name[32];
-#endif
-};
-
-#if defined(CONFIG_FB_OF)
-unsigned char nvram_read_byte(int);
-int matrox_of_init(struct device_node *dp);
-static int default_vmode = VMODE_NVRAM;
-static int default_cmode = CMODE_NVRAM;
-#endif
-
-#define curr_ydstorg(x)	ACCESS_FBINFO2(x, curr.ydstorg.pixels)
-
-#define PCI_OPTION_REG	0x40
-#define PCI_MGA_INDEX	0x44
-#define PCI_MGA_DATA	0x48
-
-#define M_DWGCTL	0x1C00
-#define M_MACCESS	0x1C04
-#define M_CTLWTST	0x1C08
-
-#define M_PLNWT		0x1C1C
-
-#define M_BCOL		0x1C20
-#define M_FCOL		0x1C24
-
-#define M_SGN		0x1C58
-#define M_LEN		0x1C5C
-#define M_AR0		0x1C60
-#define M_AR1		0x1C64
-#define M_AR2		0x1C68
-#define M_AR3		0x1C6C
-#define M_AR4		0x1C70
-#define M_AR5		0x1C74
-#define M_AR6		0x1C78
-
-#define M_CXBNDRY	0x1C80
-#define M_FXBNDRY	0x1C84
-#define M_YDSTLEN	0x1C88
-#define M_PITCH		0x1C8C
-#define M_YDST		0x1C90
-#define M_YDSTORG	0x1C94
-#define M_YTOP		0x1C98
-#define M_YBOT		0x1C9C
-
-/* mystique only */
-#define M_CACHEFLUSH	0x1FFF
-
-#define M_EXEC		0x0100
-
-#define M_DWG_TRAP	0x04
-#define M_DWG_BITBLT	0x08
-#define M_DWG_ILOAD	0x09
-
-#define M_DWG_LINEAR	0x0080
-#define M_DWG_SOLID	0x0800
-#define M_DWG_ARZERO	0x1000
-#define M_DWG_SGNZERO	0x2000
-#define M_DWG_SHIFTZERO	0x4000
-
-#define M_DWG_REPLACE	0x000C0000
-#define M_DWG_REPLACE2	(M_DWG_REPLACE | 0x40)
-#define M_DWG_XOR	0x00060010
-
-#define M_DWG_BFCOL	0x04000000
-#define M_DWG_BMONOWF	0x08000000
-
-#define M_DWG_TRANSC	0x40000000
-
-#define M_FIFOSTATUS	0x1E10
-#define M_STATUS	0x1E14
-
-#define M_IEN		0x1E1C
-
-#define M_VCOUNT	0x1E20
-
-#define M_RESET		0x1E40
-
-#define M_AGP2PLL	0x1E4C
-
-#define M_OPMODE	0x1E54
-#define     M_OPMODE_DMA_GEN_WRITE	0x00
-#define     M_OPMODE_DMA_BLIT		0x04
-#define     M_OPMODE_DMA_VECTOR_WRITE	0x08
-#define     M_OPMODE_DMA_LE		0x0000		/* little endian - no transformation */
-#define     M_OPMODE_DMA_BE_8BPP	0x0000
-#define     M_OPMODE_DMA_BE_16BPP	0x0100
-#define     M_OPMODE_DMA_BE_32BPP	0x0200
-#define     M_OPMODE_DIR_LE		0x000000	/* little endian - no transformation */
-#define     M_OPMODE_DIR_BE_8BPP	0x000000
-#define     M_OPMODE_DIR_BE_16BPP	0x010000
-#define     M_OPMODE_DIR_BE_32BPP	0x020000
-
-#define M_ATTR_INDEX	0x1FC0
-#define M_ATTR_DATA	0x1FC1
-
-#define M_MISC_REG	0x1FC2
-#define M_3C2_RD	0x1FC2
-
-#define M_SEQ_INDEX	0x1FC4
-#define M_SEQ_DATA	0x1FC5
-
-#define M_MISC_REG_READ	0x1FCC
-
-#define M_GRAPHICS_INDEX 0x1FCE
-#define M_GRAPHICS_DATA	0x1FCF
-
-#define M_CRTC_INDEX	0x1FD4
-
-#define M_ATTR_RESET	0x1FDA
-#define M_3DA_WR	0x1FDA
-
-#define M_EXTVGA_INDEX	0x1FDE
-#define M_EXTVGA_DATA	0x1FDF
-
-/* G200 only */
-#define M_SRCORG	0x2CB4
-
-#define M_RAMDAC_BASE	0x3C00
-
-/* fortunately, same on TVP3026 and MGA1064 */
-#define M_DAC_REG	(M_RAMDAC_BASE+0)
-#define M_DAC_VAL	(M_RAMDAC_BASE+1)
-#define M_PALETTE_MASK	(M_RAMDAC_BASE+2)
-
-#define M_X_INDEX	0x00
-#define M_X_DATAREG	0x0A
-
-#define DAC_XGENIOCTRL		0x2A
-#define DAC_XGENIODATA		0x2B
-
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-#define TVP3026_INDEX		0x00
-#define TVP3026_PALWRADD	0x00
-#define TVP3026_PALDATA		0x01
-#define TVP3026_PIXRDMSK	0x02
-#define TVP3026_PALRDADD	0x03
-#define TVP3026_CURCOLWRADD	0x04
-#define     TVP3026_CLOVERSCAN		0x00
-#define     TVP3026_CLCOLOR0		0x01
-#define     TVP3026_CLCOLOR1		0x02
-#define     TVP3026_CLCOLOR2		0x03
-#define TVP3026_CURCOLDATA	0x05
-#define TVP3026_CURCOLRDADD	0x07
-#define TVP3026_CURCTRL		0x09
-#define TVP3026_X_DATAREG	0x0A
-#define TVP3026_CURRAMDATA	0x0B
-#define TVP3026_CURPOSXL	0x0C
-#define TVP3026_CURPOSXH	0x0D
-#define TVP3026_CURPOSYL	0x0E
-#define TVP3026_CURPOSYH	0x0F
-
-#define TVP3026_XSILICONREV	0x01
-#define TVP3026_XCURCTRL	0x06
-#define     TVP3026_XCURCTRL_DIS	0x00	/* transparent, transparent, transparent, transparent */
-#define     TVP3026_XCURCTRL_3COLOR	0x01	/* transparent, 0, 1, 2 */
-#define     TVP3026_XCURCTRL_XGA	0x02	/* 0, 1, transparent, complement */
-#define     TVP3026_XCURCTRL_XWIN	0x03	/* transparent, transparent, 0, 1 */
-#define     TVP3026_XCURCTRL_BLANK2048	0x00
-#define     TVP3026_XCURCTRL_BLANK4096	0x10
-#define     TVP3026_XCURCTRL_INTERLACED	0x20
-#define     TVP3026_XCURCTRL_ODD	0x00 /* ext.signal ODD/\EVEN */
-#define     TVP3026_XCURCTRL_EVEN	0x40 /* ext.signal EVEN/\ODD */
-#define     TVP3026_XCURCTRL_INDIRECT	0x00
-#define     TVP3026_XCURCTRL_DIRECT	0x80
-#define TVP3026_XLATCHCTRL	0x0F
-#define     TVP3026_XLATCHCTRL_1_1	0x06
-#define     TVP3026_XLATCHCTRL_2_1	0x07
-#define     TVP3026_XLATCHCTRL_4_1	0x06
-#define     TVP3026_XLATCHCTRL_8_1	0x06
-#define     TVP3026_XLATCHCTRL_16_1	0x06
-#define     TVP3026A_XLATCHCTRL_4_3	0x06	/* ??? do not understand... but it works... !!! */
-#define     TVP3026A_XLATCHCTRL_8_3	0x07
-#define     TVP3026B_XLATCHCTRL_4_3	0x08
-#define     TVP3026B_XLATCHCTRL_8_3	0x06	/* ??? do not understand... but it works... !!! */
-#define TVP3026_XTRUECOLORCTRL	0x18
-#define     TVP3026_XTRUECOLORCTRL_VRAM_SHIFT_ACCEL	0x00
-#define     TVP3026_XTRUECOLORCTRL_VRAM_SHIFT_TVP	0x20
-#define     TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR		0x80
-#define     TVP3026_XTRUECOLORCTRL_TRUECOLOR		0x40 /* paletized */
-#define     TVP3026_XTRUECOLORCTRL_DIRECTCOLOR		0x00
-#define     TVP3026_XTRUECOLORCTRL_24_ALTERNATE		0x08 /* 5:4/5:2 instead of 4:3/8:3 */
-#define     TVP3026_XTRUECOLORCTRL_RGB_888		0x16 /* 4:3/8:3 (or 5:4/5:2) */
-#define	    TVP3026_XTRUECOLORCTRL_BGR_888		0x17
-#define     TVP3026_XTRUECOLORCTRL_ORGB_8888		0x06
-#define     TVP3026_XTRUECOLORCTRL_BGRO_8888		0x07
-#define     TVP3026_XTRUECOLORCTRL_RGB_565		0x05
-#define     TVP3026_XTRUECOLORCTRL_ORGB_1555		0x04
-#define     TVP3026_XTRUECOLORCTRL_RGB_664		0x03
-#define     TVP3026_XTRUECOLORCTRL_RGBO_4444		0x01
-#define TVP3026_XMUXCTRL	0x19
-#define     TVP3026_XMUXCTRL_MEMORY_8BIT			0x01 /* - */
-#define     TVP3026_XMUXCTRL_MEMORY_16BIT			0x02 /* - */
-#define     TVP3026_XMUXCTRL_MEMORY_32BIT			0x03 /* 2MB RAM, 512K * 4 */
-#define     TVP3026_XMUXCTRL_MEMORY_64BIT			0x04 /* >2MB RAM, 512K * 8 & more */
-#define     TVP3026_XMUXCTRL_PIXEL_4BIT				0x40 /* L0,H0,L1,H1... */
-#define     TVP3026_XMUXCTRL_PIXEL_4BIT_SWAPPED			0x60 /* H0,L0,H1,L1... */
-#define     TVP3026_XMUXCTRL_PIXEL_8BIT				0x48
-#define     TVP3026_XMUXCTRL_PIXEL_16BIT			0x50
-#define     TVP3026_XMUXCTRL_PIXEL_32BIT			0x58
-#define     TVP3026_XMUXCTRL_VGA				0x98 /* VGA MEMORY, 8BIT PIXEL */
-#define TVP3026_XCLKCTRL	0x1A
-#define     TVP3026_XCLKCTRL_DIV1	0x00
-#define     TVP3026_XCLKCTRL_DIV2	0x10
-#define     TVP3026_XCLKCTRL_DIV4	0x20
-#define     TVP3026_XCLKCTRL_DIV8	0x30
-#define     TVP3026_XCLKCTRL_DIV16	0x40
-#define     TVP3026_XCLKCTRL_DIV32	0x50
-#define     TVP3026_XCLKCTRL_DIV64	0x60
-#define     TVP3026_XCLKCTRL_CLKSTOPPED	0x70
-#define     TVP3026_XCLKCTRL_SRC_CLK0	0x00
-#define     TVP3026_XCLKCTRL_SRC_CLK1   0x01
-#define     TVP3026_XCLKCTRL_SRC_CLK2	0x02	/* CLK2 is TTL source*/
-#define     TVP3026_XCLKCTRL_SRC_NCLK2	0x03	/* not CLK2 is TTL source */
-#define     TVP3026_XCLKCTRL_SRC_ECLK2	0x04	/* CLK2 and not CLK2 is ECL source */
-#define     TVP3026_XCLKCTRL_SRC_PLL	0x05
-#define     TVP3026_XCLKCTRL_SRC_DIS	0x06	/* disable & poweroff internal clock */
-#define     TVP3026_XCLKCTRL_SRC_CLK0VGA 0x07
-#define TVP3026_XPALETTEPAGE	0x1C
-#define TVP3026_XGENCTRL	0x1D
-#define     TVP3026_XGENCTRL_HSYNC_POS	0x00
-#define     TVP3026_XGENCTRL_HSYNC_NEG	0x01
-#define     TVP3026_XGENCTRL_VSYNC_POS	0x00
-#define     TVP3026_XGENCTRL_VSYNC_NEG	0x02
-#define     TVP3026_XGENCTRL_LITTLE_ENDIAN 0x00
-#define     TVP3026_XGENCTRL_BIG_ENDIAN    0x08
-#define     TVP3026_XGENCTRL_BLACK_0IRE		0x00
-#define     TVP3026_XGENCTRL_BLACK_75IRE	0x10
-#define     TVP3026_XGENCTRL_NO_SYNC_ON_GREEN	0x00
-#define     TVP3026_XGENCTRL_SYNC_ON_GREEN	0x20
-#define     TVP3026_XGENCTRL_OVERSCAN_DIS	0x00
-#define     TVP3026_XGENCTRL_OVERSCAN_EN	0x40
-#define TVP3026_XMISCCTRL	0x1E
-#define     TVP3026_XMISCCTRL_DAC_PUP	0x00
-#define     TVP3026_XMISCCTRL_DAC_PDOWN	0x01
-#define     TVP3026_XMISCCTRL_DAC_EXT	0x00 /* or 8, bit 3 is ignored */
-#define     TVP3026_XMISCCTRL_DAC_6BIT	0x04
-#define     TVP3026_XMISCCTRL_DAC_8BIT	0x0C
-#define     TVP3026_XMISCCTRL_PSEL_DIS	0x00
-#define     TVP3026_XMISCCTRL_PSEL_EN	0x10
-#define     TVP3026_XMISCCTRL_PSEL_LOW	0x00 /* PSEL high selects directcolor */
-#define     TVP3026_XMISCCTRL_PSEL_HIGH 0x20 /* PSEL high selects truecolor or pseudocolor */
-#define TVP3026_XGENIOCTRL	0x2A
-#define TVP3026_XGENIODATA	0x2B
-#define TVP3026_XPLLADDR	0x2C
-#define     TVP3026_XPLLADDR_X(LOOP,MCLK,PIX) (((LOOP)<<4) | ((MCLK)<<2) | (PIX))
-#define     TVP3026_XPLLDATA_N		0x00
-#define     TVP3026_XPLLDATA_M		0x01
-#define     TVP3026_XPLLDATA_P		0x02
-#define     TVP3026_XPLLDATA_STAT	0x03
-#define TVP3026_XPIXPLLDATA	0x2D
-#define TVP3026_XMEMPLLDATA	0x2E
-#define TVP3026_XLOOPPLLDATA	0x2F
-#define TVP3026_XCOLKEYOVRMIN	0x30
-#define TVP3026_XCOLKEYOVRMAX	0x31
-#define TVP3026_XCOLKEYREDMIN	0x32
-#define TVP3026_XCOLKEYREDMAX	0x33
-#define TVP3026_XCOLKEYGREENMIN	0x34
-#define TVP3026_XCOLKEYGREENMAX	0x35
-#define TVP3026_XCOLKEYBLUEMIN	0x36
-#define TVP3026_XCOLKEYBLUEMAX	0x37
-#define TVP3026_XCOLKEYCTRL	0x38
-#define     TVP3026_XCOLKEYCTRL_OVR_EN	0x01
-#define     TVP3026_XCOLKEYCTRL_RED_EN	0x02
-#define     TVP3026_XCOLKEYCTRL_GREEN_EN 0x04
-#define     TVP3026_XCOLKEYCTRL_BLUE_EN	0x08
-#define     TVP3026_XCOLKEYCTRL_NEGATE	0x10
-#define     TVP3026_XCOLKEYCTRL_ZOOM1	0x00
-#define     TVP3026_XCOLKEYCTRL_ZOOM2	0x20
-#define     TVP3026_XCOLKEYCTRL_ZOOM4	0x40
-#define     TVP3026_XCOLKEYCTRL_ZOOM8	0x60
-#define     TVP3026_XCOLKEYCTRL_ZOOM16	0x80
-#define     TVP3026_XCOLKEYCTRL_ZOOM32	0xA0
-#define TVP3026_XMEMPLLCTRL	0x39
-#define     TVP3026_XMEMPLLCTRL_DIV(X)	(((X)-1)>>1)	/* 2,4,6,8,10,12,14,16, division applied to LOOP PLL after divide by 2^P */
-#define     TVP3026_XMEMPLLCTRL_STROBEMKC4	0x08
-#define     TVP3026_XMEMPLLCTRL_MCLK_DOTCLOCK	0x00	/* MKC4 */
-#define     TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL	0x10	/* MKC4 */
-#define     TVP3026_XMEMPLLCTRL_RCLK_PIXPLL	0x00
-#define     TVP3026_XMEMPLLCTRL_RCLK_LOOPPLL	0x20
-#define     TVP3026_XMEMPLLCTRL_RCLK_DOTDIVN	0x40	/* dot clock divided by loop pclk N prescaler */
-#define TVP3026_XSENSETEST	0x3A
-#define TVP3026_XTESTMODEDATA	0x3B
-#define TVP3026_XCRCREML	0x3C
-#define TVP3026_XCRCREMH	0x3D
-#define TVP3026_XCRCBITSEL	0x3E
-#define TVP3026_XID		0x3F
-
-#endif
-
-#ifdef NEED_DAC1064
-
-#define DAC1064_OPT_SCLK_PCI	0x00
-#define DAC1064_OPT_SCLK_PLL	0x01
-#define DAC1064_OPT_SCLK_EXT	0x02
-#define DAC1064_OPT_SCLK_MASK	0x03
-#define DAC1064_OPT_GDIV1	0x04	/* maybe it is GDIV2 on G100 ?! */
-#define DAC1064_OPT_GDIV3	0x00
-#define DAC1064_OPT_MDIV1	0x08
-#define DAC1064_OPT_MDIV2	0x00
-#define DAC1064_OPT_RESERVED	0x10
-
-#define M1064_INDEX	0x00
-#define M1064_PALWRADD	0x00
-#define M1064_PALDATA	0x01
-#define M1064_PIXRDMSK	0x02
-#define M1064_PALRDADD	0x03
-#define M1064_X_DATAREG	0x0A
-#define M1064_CURPOSXL	0x0C	/* can be accessed as DWORD */
-#define M1064_CURPOSXH	0x0D
-#define M1064_CURPOSYL	0x0E
-#define M1064_CURPOSYH	0x0F
-
-#define M1064_XCURADDL		0x04
-#define M1064_XCURADDH		0x05
-#define M1064_XCURCTRL		0x06
-#define     M1064_XCURCTRL_DIS		0x00	/* transparent, transparent, transparent, transparent */
-#define     M1064_XCURCTRL_3COLOR	0x01	/* transparent, 0, 1, 2 */
-#define     M1064_XCURCTRL_XGA		0x02	/* 0, 1, transparent, complement */
-#define     M1064_XCURCTRL_XWIN		0x03	/* transparent, transparent, 0, 1 */
-#define M1064_XCURCOL0RED	0x08
-#define M1064_XCURCOL0GREEN	0x09
-#define M1064_XCURCOL0BLUE	0x0A
-#define M1064_XCURCOL1RED	0x0C
-#define M1064_XCURCOL1GREEN	0x0D
-#define M1064_XCURCOL1BLUE	0x0E
-#define M1064_XCURCOL2RED	0x10
-#define M1064_XCURCOL2GREEN	0x11
-#define M1064_XCURCOL2BLUE	0x12
-#define DAC1064_XVREFCTRL	0x18
-#define      DAC1064_XVREFCTRL_INTERNAL		0x3F
-#define      DAC1064_XVREFCTRL_EXTERNAL		0x00
-#define      DAC1064_XVREFCTRL_G100_DEFAULT	0x03
-#define M1064_XMULCTRL		0x19
-#define      M1064_XMULCTRL_DEPTH_8BPP		0x00	/* 8 bpp paletized */
-#define      M1064_XMULCTRL_DEPTH_15BPP_1BPP	0x01	/* 15 bpp paletized + 1 bpp overlay */
-#define      M1064_XMULCTRL_DEPTH_16BPP		0x02	/* 16 bpp paletized */
-#define      M1064_XMULCTRL_DEPTH_24BPP		0x03	/* 24 bpp paletized */
-#define      M1064_XMULCTRL_DEPTH_24BPP_8BPP	0x04	/* 24 bpp direct + 8 bpp overlay paletized */
-#define      M1064_XMULCTRL_2G8V16		0x05	/* 15 bpp video direct, half xres, 8bpp paletized */
-#define      M1064_XMULCTRL_G16V16		0x06	/* 15 bpp video, 15bpp graphics, one of them paletized */
-#define      M1064_XMULCTRL_DEPTH_32BPP		0x07	/* 24 bpp paletized + 8 bpp unused */
-#define      M1064_XMULCTRL_GRAPHICS_PALETIZED	0x00
-#define      M1064_XMULCTRL_VIDEO_PALETIZED	0x08
-#define M1064_XPIXCLKCTRL	0x1A
-#define      M1064_XPIXCLKCTRL_SRC_PCI		0x00
-#define      M1064_XPIXCLKCTRL_SRC_PLL		0x01
-#define      M1064_XPIXCLKCTRL_SRC_EXT		0x02
-#define      M1064_XPIXCLKCTRL_SRC_MASK		0x03
-#define      M1064_XPIXCLKCTRL_EN		0x00
-#define      M1064_XPIXCLKCTRL_DIS		0x04
-#define      M1064_XPIXCLKCTRL_PLL_DOWN		0x00
-#define      M1064_XPIXCLKCTRL_PLL_UP		0x08
-#define M1064_XGENCTRL		0x1D
-#define      M1064_XGENCTRL_VS_0		0x00
-#define      M1064_XGENCTRL_VS_1		0x01
-#define      M1064_XGENCTRL_ALPHA_DIS		0x00
-#define      M1064_XGENCTRL_ALPHA_EN		0x02
-#define      M1064_XGENCTRL_BLACK_0IRE		0x00
-#define      M1064_XGENCTRL_BLACK_75IRE		0x10
-#define      M1064_XGENCTRL_SYNC_ON_GREEN	0x00
-#define      M1064_XGENCTRL_NO_SYNC_ON_GREEN	0x20
-#define      M1064_XGENCTRL_SYNC_ON_GREEN_MASK	0x20
-#define M1064_XMISCCTRL		0x1E
-#define      M1064_XMISCCTRL_DAC_DIS		0x00
-#define      M1064_XMISCCTRL_DAC_EN		0x01
-#define      M1064_XMISCCTRL_MFC_VGA		0x00
-#define      M1064_XMISCCTRL_MFC_MAFC		0x02
-#define      M1064_XMISCCTRL_MFC_DIS		0x06
-#define      M1064_XMISCCTRL_DAC_6BIT		0x00
-#define      M1064_XMISCCTRL_DAC_8BIT		0x08
-#define      M1064_XMISCCTRL_LUT_DIS		0x00
-#define      M1064_XMISCCTRL_LUT_EN		0x10
-#define M1064_XGENIOCTRL	0x2A
-#define M1064_XGENIODATA	0x2B
-#define DAC1064_XSYSPLLM	0x2C
-#define DAC1064_XSYSPLLN	0x2D
-#define DAC1064_XSYSPLLP	0x2E
-#define DAC1064_XSYSPLLSTAT	0x2F
-#define M1064_XZOOMCTRL		0x38
-#define      M1064_XZOOMCTRL_1			0x00
-#define      M1064_XZOOMCTRL_2			0x01
-#define      M1064_XZOOMCTRL_4			0x03
-#define M1064_XSENSETEST	0x3A
-#define      M1064_XSENSETEST_BCOMP		0x01
-#define      M1064_XSENSETEST_GCOMP		0x02
-#define      M1064_XSENSETEST_RCOMP		0x04
-#define      M1064_XSENSETEST_PDOWN		0x00
-#define      M1064_XSENSETEST_PUP		0x80
-#define M1064_XCRCREML		0x3C
-#define M1064_XCRCREMH		0x3D
-#define M1064_XCRCBITSEL	0x3E
-#define M1064_XCOLKEYMASKL	0x40
-#define M1064_XCOLKEYMASKH	0x41
-#define M1064_XCOLKEYL		0x42
-#define M1064_XCOLKEYH		0x43
-#define M1064_XPIXPLLAM		0x44
-#define M1064_XPIXPLLAN		0x45
-#define M1064_XPIXPLLAP		0x46
-#define M1064_XPIXPLLBM		0x48
-#define M1064_XPIXPLLBN		0x49
-#define M1064_XPIXPLLBP		0x4A
-#define M1064_XPIXPLLCM		0x4C
-#define M1064_XPIXPLLCN		0x4D
-#define M1064_XPIXPLLCP		0x4E
-#define M1064_XPIXPLLSTAT	0x4F
-
-#endif
-
-#ifdef __LITTLE_ENDIAN
-#define MX_OPTION_BSWAP		0x00000000
-
-#define M_OPMODE_4BPP	(M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT)
-#define M_OPMODE_8BPP	(M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT)
-#define M_OPMODE_16BPP	(M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT)
-#define M_OPMODE_24BPP	(M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT)
-#define M_OPMODE_32BPP	(M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT)
-#else
-#ifdef __BIG_ENDIAN
-#define MX_OPTION_BSWAP		0x80000000
-
-#define M_OPMODE_4BPP	(M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT)	/* TODO */
-#define M_OPMODE_8BPP	(M_OPMODE_DMA_BE_8BPP  | M_OPMODE_DIR_BE_8BPP  | M_OPMODE_DMA_BLIT)
-#define M_OPMODE_16BPP	(M_OPMODE_DMA_BE_16BPP | M_OPMODE_DIR_BE_16BPP | M_OPMODE_DMA_BLIT)
-#define M_OPMODE_24BPP	(M_OPMODE_DMA_BE_8BPP | M_OPMODE_DIR_BE_8BPP | M_OPMODE_DMA_BLIT)	/* TODO, ?32 */
-#define M_OPMODE_32BPP	(M_OPMODE_DMA_BE_32BPP | M_OPMODE_DIR_BE_32BPP | M_OPMODE_DMA_BLIT)
-#else
-#error "Byte ordering have to be defined. Cannot continue."
-#endif
-#endif
-
-#define mga_inb(addr)	mga_readb(ACCESS_FBINFO(mmio.vbase), (addr))
-#define mga_inl(addr)	mga_readl(ACCESS_FBINFO(mmio.vbase), (addr))
-#define mga_outb(addr,val) mga_writeb(ACCESS_FBINFO(mmio.vbase), (addr), (val))
-#define mga_outw(addr,val) mga_writew(ACCESS_FBINFO(mmio.vbase), (addr), (val))
-#define mga_outl(addr,val) mga_writel(ACCESS_FBINFO(mmio.vbase), (addr), (val))
-#define mga_readr(port,idx) (mga_outb((port),(idx)), mga_inb((port)+1))
-#ifdef __LITTLE_ENDIAN
-#define mga_setr(addr,port,val) mga_outw(addr, ((val)<<8) | (port))
-#else
-#define mga_setr(addr,port,val) do { mga_outb(addr, port); mga_outb((addr)+1, val); } while (0)
-#endif
-
-#ifdef __LITTLE_ENDIAN
-#define mga_fifo(n)	do {} while (mga_inb(M_FIFOSTATUS) < (n))
-#else
-#define mga_fifo(n)	do {} while ((mga_inl(M_FIFOSTATUS) & 0xFF) < (n))
-#endif
-
-#define WaitTillIdle()	do {} while (mga_inl(M_STATUS) & 0x10000)
-
-/* code speedup */
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-#define isInterleave(x)	 (x->interleave)
-#define isMillenium(x)	 (x->millenium)
-#define isMilleniumII(x) (x->milleniumII)
-#else
-#define isInterleave(x)  (0)
-#define isMillenium(x)	 (0)
-#define isMilleniumII(x) (0)
-#endif
-
-#define mga_ydstlen(y,l) mga_outl(M_YDSTLEN | M_EXEC, ((y) << 16) | (l))
-
-static void matrox_cfbX_init(WPMINFO struct display* p) {
-	u_int32_t maccess;
-	u_int32_t mpitch;
-	u_int32_t mopmode;
-
-	DBG("matrox_cfbX_init")
-	
-	mpitch = p->var.xres_virtual;
-
-	if (p->type == FB_TYPE_TEXT) {
-		maccess = 0x00000000;
-		mpitch = (mpitch >> 4) | 0x8000; /* set something */
-		mopmode = M_OPMODE_8BPP;
-	} else {
-		switch (p->var.bits_per_pixel) {
-		case 4:		maccess = 0x00000000;	/* accelerate as 8bpp video */
-				mpitch = (mpitch >> 1) | 0x8000; /* disable linearization */
-				mopmode = M_OPMODE_4BPP;
-				break;
-    		case 8:		maccess = 0x00000000; 
-				mopmode = M_OPMODE_8BPP;
-				break;
-    		case 16:	if (p->var.green.length == 5)
-					maccess = 0xC0000001; 
-				else
-    				    	maccess = 0x40000001; 
-				mopmode = M_OPMODE_16BPP;
-				break;
-		case 24:	maccess = 0x00000003;
-				mopmode = M_OPMODE_24BPP;
-				break;
-		case 32:	maccess = 0x00000002; 
-				mopmode = M_OPMODE_32BPP;
-				break;
-		default:	maccess = 0x00000000; 
-				mopmode = 0x00000000;
-				break;	/* turn off acceleration!!! */
-		}
-	}
-	mga_fifo(8);
-	mga_outl(M_PITCH, mpitch);
-	mga_outl(M_YDSTORG, curr_ydstorg(MINFO));
-	if (ACCESS_FBINFO(capable.plnwt))
-		mga_outl(M_PLNWT, -1);
-	mga_outl(M_OPMODE, mopmode);
-	mga_outl(M_CXBNDRY, 0xFFFF0000);
-	mga_outl(M_YTOP, 0);
-	mga_outl(M_YBOT, 0x01FFFFFF);
-	mga_outl(M_MACCESS, maccess);
-	ACCESS_FBINFO(accel.m_dwg_rect) = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO;
-	if (isMilleniumII(MINFO)) ACCESS_FBINFO(accel.m_dwg_rect) |= M_DWG_TRANSC;
-	ACCESS_FBINFO(accel.m_opmode) = mopmode;
-}
-
-static void matrox_cfbX_bmove(struct display* p, int sy, int sx, int dy, int dx, int height, int width) {
-	int pixx = p->var.xres_virtual, start, end;
-	MINFO_FROM_DISP(p);
-
-	DBG("matrox_cfbX_bmove")
-
-	sx *= fontwidth(p);
-	dx *= fontwidth(p);
-	width *= fontwidth(p);
-	height *= fontheight(p);
-	sy *= fontheight(p);
-	dy *= fontheight(p);
-	if ((dy < sy) || ((dy == sy) && (dx <= sx))) {
-		mga_fifo(2);
-		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |
-			       M_DWG_BFCOL | M_DWG_REPLACE);
-		mga_outl(M_AR5, pixx);
-		width--;
-		start = sy*pixx+sx+curr_ydstorg(MINFO);
-		end = start+width;
-	} else {
-		mga_fifo(3);
-		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);
-		mga_outl(M_SGN, 5);
-		mga_outl(M_AR5, -pixx);
-		width--;
-		end = (sy+height-1)*pixx+sx+curr_ydstorg(MINFO);
-		start = end+width;
-		dy += height-1;
-	}
-	mga_fifo(4);
-	mga_outl(M_AR0, end);
-	mga_outl(M_AR3, start);
-	mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
-	mga_ydstlen(dy, height);
-	WaitTillIdle();
-}
-
-#ifdef FBCON_HAS_CFB4
-static void matrox_cfb4_bmove(struct display* p, int sy, int sx, int dy, int dx, int height, int width) {
-	int pixx, start, end;
-	MINFO_FROM_DISP(p);
-	/* both (sx or dx or width) and fontwidth() are odd, so their multiply is
-	   also odd, that means that we cannot use acceleration */
-	
-	DBG("matrox_cfb4_bmove")
-
-	if ((sx | dx | width) & fontwidth(p) & 1) {
-		fbcon_cfb4_bmove(p, sy, sx, dy, dx, height, width);
-		return;
-	}
-	sx *= fontwidth(p);
-	dx *= fontwidth(p);
-	width *= fontwidth(p);
-	height *= fontheight(p);
-	sy *= fontheight(p);
-	dy *= fontheight(p);
-	pixx = p->var.xres_virtual >> 1;
-	sx >>= 1;
-	dx >>= 1;
-	width >>= 1;
-	if ((dy < sy) || ((dy == sy) && (dx <= sx))) {
-		mga_fifo(2);
-		mga_outl(M_AR5, pixx);
-		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |
-			M_DWG_BFCOL | M_DWG_REPLACE);
-		width--;
-		start = sy*pixx+sx+curr_ydstorg(MINFO);
-		end = start+width;
-	} else {
-		mga_fifo(3);
-		mga_outl(M_SGN, 5);
-		mga_outl(M_AR5, -pixx);
-		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);
-		width--;
-		end = (sy+height-1)*pixx+sx+curr_ydstorg(MINFO);
-		start = end+width;
-		dy += height-1;
-	}
-	mga_fifo(5);
-	mga_outl(M_AR0, end);
-	mga_outl(M_AR3, start);
-	mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
-	mga_outl(M_YDST, dy*pixx >> 5);
-	mga_outl(M_LEN | M_EXEC, height);
-	WaitTillIdle();
-}
-#endif
-
-static void matroxfb_accel_clear(CPMINFO u_int32_t color, int sy, int sx, int height, 
-		int width) {
-	
-	DBG("matroxfb_accel_clear")
-
-	mga_fifo(5);
-	mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_REPLACE);
-	mga_outl(M_FCOL, color);
-	mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
-	mga_ydstlen(sy, height);
-	WaitTillIdle();
-}
-
-static void matrox_cfbX_clear(u_int32_t color, struct display* p, int sy, int sx, int height, int width) {
-	
-	DBG("matrox_cfbX_clear")
-	
-	matroxfb_accel_clear(PMXINFO(p) color, sy * fontheight(p), sx * fontwidth(p),
-			     height * fontheight(p), width * fontwidth(p));
-}
-
-#ifdef FBCON_HAS_CFB4
-static void matrox_cfb4_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) {
-	u_int32_t bgx;
-	int whattodo;
-	MINFO_FROM_DISP(p);
-
-	DBG("matrox_cfb4_clear")
-
-	whattodo = 0; 
-	bgx = attr_bgcol_ec(p, conp);
-	bgx |= bgx << 4;
-	bgx |= bgx << 8;
-	bgx |= bgx << 16;
-	sy *= fontheight(p);
-	sx *= fontwidth(p);
-	height *= fontheight(p);
-	width *= fontwidth(p);
-	if (sx & 1) {
-		sx ++;
-		if (!width) return;
-		width --;
-		whattodo = 1;
-	}
-	if (width & 1) {
-		whattodo |= 2;
-	}
-	width >>= 1;
-	sx >>= 1;
-	if (width) {
-		mga_fifo(5);
-		mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_REPLACE2);
-		mga_outl(M_FCOL, bgx);
-		mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
-		mga_outl(M_YDST, sy * p->var.xres_virtual >> 6);
-		mga_outl(M_LEN | M_EXEC, height);
-		WaitTillIdle();
-	}
-	if (whattodo) {
-		u_int32_t step = p->var.xres_virtual >> 1;
-		vaddr_t vbase = ACCESS_FBINFO(video.vbase);
-		if (whattodo & 1) {
-			unsigned int uaddr = sy * step + sx - 1;
-			u_int32_t loop;
-			u_int8_t bgx2 = bgx & 0xF0;
-			for (loop = height; loop > 0; loop --) {
-				mga_writeb(vbase, uaddr, (mga_readb(vbase, uaddr) & 0x0F) | bgx2);
-				uaddr += step;
-			}
-		}
-		if (whattodo & 2) {
-			unsigned int uaddr = sy * step + sx + width;
-			u_int32_t loop;
-			u_int8_t bgx2 = bgx & 0x0F;
-			for (loop = height; loop > 0; loop --) {
-				mga_writeb(vbase, uaddr, (mga_readb(vbase, uaddr) & 0xF0) | bgx2);
-				uaddr += step;
-			}
-		}
-	}
-}
-#endif
-
-#ifdef FBCON_HAS_CFB8
-static void matrox_cfb8_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) {
-	u_int32_t bgx;
-
-	DBG("matrox_cfb8_clear")
-	
-	bgx = attr_bgcol_ec(p, conp);
-	bgx |= bgx << 8;
-	bgx |= bgx << 16;
-	matrox_cfbX_clear(bgx, p, sy, sx, height, width);
-}
-#endif
-
-#ifdef FBCON_HAS_CFB16
-static void matrox_cfb16_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) {
-	u_int32_t bgx;
-
-	DBG("matrox_cfb16_clear")
-	
-	bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-	matrox_cfbX_clear((bgx << 16) | bgx, p, sy, sx, height, width);
-}
-#endif
-
-#if defined(FBCON_HAS_CFB32) || defined(FBCON_HAS_CFB24)
-static void matrox_cfb32_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) {
-	u_int32_t bgx;
-
-	DBG("matrox_cfb32_clear")
-	
-	bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-	matrox_cfbX_clear(bgx, p, sy, sx, height, width);
-}
-#endif
-
-static void matrox_cfbX_fastputc(u_int32_t fgx, u_int32_t bgx, struct display* p, int c, int yy, int xx) {
-	unsigned int charcell;
-	unsigned int ar3;
-	MINFO_FROM_DISP(p);
-
-	charcell = fontwidth(p) * fontheight(p);
-	yy *= fontheight(p);
-	xx *= fontwidth(p);
-
-	mga_fifo(8);
-	mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
-	
-	mga_outl(M_FCOL, fgx);
-	mga_outl(M_BCOL, bgx);
-	mga_outl(M_FXBNDRY, ((xx + fontwidth(p) - 1) << 16) | xx);
-	ar3 = ACCESS_FBINFO(fastfont.mgabase) + (c & p->charmask) * charcell;
-	mga_outl(M_AR3, ar3);
-	mga_outl(M_AR0, (ar3 + charcell - 1) & 0x0003FFFF);
-	mga_ydstlen(yy, fontheight(p));
-	WaitTillIdle();
-}
-	
-static void matrox_cfbX_putc(u_int32_t fgx, u_int32_t bgx, struct display* p, int c, int yy, int xx) {
-	u_int32_t ar0;
-	u_int32_t step;
-	MINFO_FROM_DISP(p);
-
-	DBG_HEAVY("matrox_cfbX_putc");
-	
-	yy *= fontheight(p);
-	xx *= fontwidth(p);
-
-#ifdef __BIG_ENDIAN
-	WaitTillIdle();
-	mga_outl(M_OPMODE, M_OPMODE_8BPP);
-#else
-	mga_fifo(7);
-#endif
-	ar0 = fontwidth(p) - 1;
-	mga_outl(M_FXBNDRY, ((xx+ar0)<<16) | xx);
-	if (fontwidth(p) <= 8)
-		step = 1;
-	else if (fontwidth(p) <= 16)
-		step = 2;
-	else 
-		step = 4;
-	if (fontwidth(p) == step << 3) {
-		size_t charcell = fontheight(p)*step;
-		/* TODO: Align charcell to 4B for BE */
-		mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
-		mga_outl(M_FCOL, fgx);
-		mga_outl(M_BCOL, bgx);
-		mga_outl(M_AR3, 0);
-		mga_outl(M_AR0, fontheight(p)*fontwidth(p)-1);
-		mga_ydstlen(yy, fontheight(p));
-		mga_memcpy_toio(ACCESS_FBINFO(mmio.vbase), 0, p->fontdata+(c&p->charmask)*charcell, charcell);
-	} else {
-		u8* chardata = p->fontdata+(c&p->charmask)*fontheight(p)*step;
-		int i;
-
-		mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_REPLACE);
-		mga_outl(M_FCOL, fgx);
-		mga_outl(M_BCOL, bgx);
-		mga_outl(M_AR5, 0);
-		mga_outl(M_AR3, 0);
-		mga_outl(M_AR0, ar0);
-		mga_ydstlen(yy, fontheight(p));
-
-		switch (step) {
-		case 1:	
-			for (i = fontheight(p); i > 0; i--) {
-#ifdef __LITTLE_ENDIAN
-				mga_outl(0, *chardata++);
-#else
-				mga_outl(0, (*chardata++) << 24);
-#endif
-			}
-			break;
-		case 2:
-			for (i = fontheight(p); i > 0; i--) {
-#ifdef __LITTLE_ENDIAN
-				mga_outl(0, *(u_int16_t*)chardata);
-#else
-				mga_outl(0, (*(u_int16_t*)chardata) << 16);
-#endif
-				chardata += 2;
-			}
-			break;
-		case 4:
-			mga_memcpy_toio(ACCESS_FBINFO(mmio.vbase), 0, chardata, fontheight(p) * 4);
-			break;
-		}
-	}
-	WaitTillIdle();
-#ifdef __BIG_ENDIAN
-	mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
-#endif
-}
-
-#ifdef FBCON_HAS_CFB8
-static void matrox_cfb8_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
-	u_int32_t fgx, bgx;
-	MINFO_FROM_DISP(p);
-
-	DBG_HEAVY("matroxfb_cfb8_putc");
-
-	fgx = attr_fgcol(p, c);
-	bgx = attr_bgcol(p, c);
-	fgx |= (fgx << 8);
-	fgx |= (fgx << 16);
-	bgx |= (bgx << 8);
-	bgx |= (bgx << 16);
-	ACCESS_FBINFO(curr.putc)(fgx, bgx, p, c, yy, xx);
-}
-#endif
-
-#ifdef FBCON_HAS_CFB16
-static void matrox_cfb16_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
-	u_int32_t fgx, bgx;
-	MINFO_FROM_DISP(p);
-
-	DBG_HEAVY("matroxfb_cfb16_putc");
-
-	fgx = ((u_int16_t*)p->dispsw_data)[attr_fgcol(p, c)];
-	bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol(p, c)];
-	fgx |= (fgx << 16);
-	bgx |= (bgx << 16);
-	ACCESS_FBINFO(curr.putc)(fgx, bgx, p, c, yy, xx);
-}
-#endif
-
-#if defined(FBCON_HAS_CFB32) || defined(FBCON_HAS_CFB24)
-static void matrox_cfb32_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
-	u_int32_t fgx, bgx;
-	MINFO_FROM_DISP(p);
-
-	DBG_HEAVY("matroxfb_cfb32_putc");
-
-	fgx = ((u_int32_t*)p->dispsw_data)[attr_fgcol(p, c)];
-	bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol(p, c)];
-	ACCESS_FBINFO(curr.putc)(fgx, bgx, p, c, yy, xx);
-}
-#endif
-
-static void matrox_cfbX_fastputcs(u_int32_t fgx, u_int32_t bgx, struct display* p, const unsigned short* s, int count, int yy, int xx) {
-	unsigned int charcell;
-	MINFO_FROM_DISP(p);
-
-	yy *= fontheight(p);
-	xx *= fontwidth(p);
-	charcell = fontwidth(p) * fontheight(p);
-
-	mga_fifo(3);
-	mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
-	mga_outl(M_FCOL, fgx);
-	mga_outl(M_BCOL, bgx);
-	while (count--) {
-		u_int32_t ar3 = ACCESS_FBINFO(fastfont.mgabase) + (scr_readw(s++) & p->charmask)*charcell;
-
-		mga_fifo(4);
-		mga_outl(M_FXBNDRY, ((xx + fontwidth(p) - 1) << 16) | xx);
-		mga_outl(M_AR3, ar3);
-		mga_outl(M_AR0, (ar3 + charcell - 1) & 0x0003FFFF);
-		mga_ydstlen(yy, fontheight(p));
-		xx += fontwidth(p);
-	}
-	WaitTillIdle();
-}
-
-static void matrox_cfbX_putcs(u_int32_t fgx, u_int32_t bgx, struct display* p, const unsigned short* s, int count, int yy, int xx) {
-	u_int32_t step;
-	u_int32_t ydstlen;
-	u_int32_t xlen;
-	u_int32_t ar0;
-	u_int32_t charcell;
-	u_int32_t fxbndry;
-	vaddr_t mmio;
-	int easy;
-	MINFO_FROM_DISP(p);
-
-	DBG_HEAVY("matroxfb_cfbX_putcs");
-
-	yy *= fontheight(p);
-	xx *= fontwidth(p);
-	if (fontwidth(p) <= 8)
-		step = 1;
-	else if (fontwidth(p) <= 16)
-		step = 2;
-	else
-		step = 4;
-	charcell = fontheight(p)*step;
-	xlen = (charcell + 3) & ~3;
-	ydstlen = (yy << 16) | fontheight(p);
-	if (fontwidth(p) == step << 3) {
-		ar0 = fontheight(p)*fontwidth(p) - 1;
-		easy = 1;
-	} else {
-		ar0 = fontwidth(p) - 1;
-		easy = 0;
-	}
-
-#ifdef __BIG_ENDIAN
-	WaitTillIdle();
-	mga_outl(M_OPMODE, M_OPMODE_8BPP);
-#else
-	mga_fifo(3);
-#endif
-	if (easy)
-		mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
-	else
-		mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_REPLACE);
-	mga_outl(M_FCOL, fgx);
-	mga_outl(M_BCOL, bgx);
-	fxbndry = ((xx + fontwidth(p) - 1) << 16) | xx;
-	mmio = ACCESS_FBINFO(mmio.vbase);
-	while (count--) {
-		u_int8_t* chardata = p->fontdata + (scr_readw(s++) & p->charmask)*charcell;
-
-		mga_fifo(6);
-		mga_writel(mmio, M_FXBNDRY, fxbndry);
-		mga_writel(mmio, M_AR0, ar0);
-		mga_writel(mmio, M_AR3, 0);
-		if (easy) {
-			mga_writel(mmio, M_YDSTLEN | M_EXEC, ydstlen);
-			mga_memcpy_toio(mmio, 0, chardata, xlen);
-		} else {
-			mga_writel(mmio, M_AR5, 0);
-			mga_writel(mmio, M_YDSTLEN | M_EXEC, ydstlen);
-			switch (step) {
-				case 1:	{
-						u_int8_t* charend = chardata + charcell;
-						for (; chardata != charend; chardata++) {
-#ifdef __LITTLE_ENDIAN
-							mga_writel(mmio, 0, *chardata);
-#else
-							mga_writel(mmio, 0, (*chardata) << 24);
-#endif
-						}
-					}
-					break;
-				case 2:	{
-						u_int8_t* charend = chardata + charcell;
-						for (; chardata != charend; chardata += 2) {
-#ifdef __LITTLE_ENDIAN
-							mga_writel(mmio, 0, *(u_int16_t*)chardata);
-#else
-							mga_writel(mmio, 0, (*(u_int16_t*)chardata) << 16);
-#endif
-						}
-					}
-					break;
-				default:
-					mga_memcpy_toio(mmio, 0, chardata, charcell);
-					break;
-			}
-		}
-		fxbndry += fontwidth(p) + (fontwidth(p) << 16);
-	}
-	WaitTillIdle();
-#ifdef __BIG_ENDIAN
-	mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
-#endif
-}
-
-#ifdef FBCON_HAS_CFB8
-static void matrox_cfb8_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
-	u_int32_t fgx, bgx;
-	MINFO_FROM_DISP(p);
-
-	DBG_HEAVY("matroxfb_cfb8_putcs");
-
-	fgx = attr_fgcol(p, scr_readw(s));
-	bgx = attr_bgcol(p, scr_readw(s));
-	fgx |= (fgx << 8);
-	fgx |= (fgx << 16);
-	bgx |= (bgx << 8);
-	bgx |= (bgx << 16);
-	ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
-}
-#endif
-
-#ifdef FBCON_HAS_CFB16
-static void matrox_cfb16_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
-	u_int32_t fgx, bgx;
-	MINFO_FROM_DISP(p);
-
-	DBG_HEAVY("matroxfb_cfb16_putcs");
-
-	fgx = ((u_int16_t*)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
-	bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
-	fgx |= (fgx << 16);
-	bgx |= (bgx << 16);
-	ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
-}
-#endif
-
-#if defined(FBCON_HAS_CFB32) || defined(FBCON_HAS_CFB24)
-static void matrox_cfb32_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
-	u_int32_t fgx, bgx;
-	MINFO_FROM_DISP(p);
-
-	DBG_HEAVY("matroxfb_cfb32_putcs");
-
-	fgx = ((u_int32_t*)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
-	bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
-	ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
-}
-#endif
-
-#ifdef FBCON_HAS_CFB4
-static void matrox_cfb4_revc(struct display* p, int xx, int yy) {
-	MINFO_FROM_DISP(p);
-
-	DBG_LOOP("matroxfb_cfb4_revc");
-
-	if (fontwidth(p) & 1) {
-		fbcon_cfb4_revc(p, xx, yy);
-		return;
-	}
-	yy *= fontheight(p);
-	xx *= fontwidth(p);
-	xx |= (xx + fontwidth(p)) << 16;
-	xx >>= 1;
-
-	mga_fifo(5);
-	mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
-	mga_outl(M_FCOL, 0xFFFFFFFF);
-	mga_outl(M_FXBNDRY, xx);
-	mga_outl(M_YDST, yy * p->var.xres_virtual >> 6);
-	mga_outl(M_LEN | M_EXEC, fontheight(p));
-	WaitTillIdle();
-} 
-#endif
-
-#ifdef FBCON_HAS_CFB8
-static void matrox_cfb8_revc(struct display* p, int xx, int yy) {
-	MINFO_FROM_DISP(p);
-
-	DBG_LOOP("matrox_cfb8_revc")
-	
-	yy *= fontheight(p);
-	xx *= fontwidth(p);
-
-	mga_fifo(4);
-	mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
-	mga_outl(M_FCOL, 0x0F0F0F0F);
-	mga_outl(M_FXBNDRY, ((xx + fontwidth(p)) << 16) | xx);
-	mga_ydstlen(yy, fontheight(p));
-	WaitTillIdle();
-}
-#endif
-
-static void matrox_cfbX_revc(struct display* p, int xx, int yy) {
-	MINFO_FROM_DISP(p);
-
-	DBG_LOOP("matrox_cfbX_revc")
-	
-	yy *= fontheight(p);
-	xx *= fontwidth(p);
-
-	mga_fifo(4);
-	mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
-	mga_outl(M_FCOL, 0xFFFFFFFF);
-	mga_outl(M_FXBNDRY, ((xx + fontwidth(p)) << 16) | xx);
-	mga_ydstlen(yy, fontheight(p));
-	WaitTillIdle();
-}
-
-static void matrox_cfbX_clear_margins(struct vc_data* conp, struct display* p, int bottom_only) {
-	unsigned int bottom_height, right_width;
-	unsigned int bottom_start, right_start;
-	unsigned int cell_h, cell_w;
-
-	DBG("matrox_cfbX_clear_margins")
-	
-	cell_w = fontwidth(p);
-	if (!cell_w) return;	/* PARANOID */
-	right_width = p->var.xres % cell_w;
-	right_start = p->var.xres - right_width;
-	if (!bottom_only && right_width) {
-		/* clear whole right margin, not only visible portion */
-		matroxfb_accel_clear(     PMXINFO(p)
-			     /* color */  0x00000000,
-			     /* y */      0,
-			     /* x */      p->var.xoffset + right_start,
-			     /* height */ p->var.yres_virtual,
-			     /* width */  right_width);
-	}
-	cell_h = fontheight(p);
-	if (!cell_h) return;	/* PARANOID */
-	bottom_height = p->var.yres % cell_h;
-	if (bottom_height) {
-		bottom_start = p->var.yres - bottom_height;
-		matroxfb_accel_clear(		  PMXINFO(p)
-				     /* color */  0x00000000,
-				     /* y */	  p->var.yoffset + bottom_start,
-				     /* x */	  p->var.xoffset,
-				     /* height */ bottom_height,
-				     /* width */  right_start);
-	}
-}
-
-static void outDAC(CPMINFO int reg, int val) {
-	DBG_REG("outDAC");
-	mga_outb(M_RAMDAC_BASE+M_X_INDEX, reg);
-	mga_outb(M_RAMDAC_BASE+M_X_DATAREG, val);
-}
-
-static int inDAC(CPMINFO int reg) {
-	DBG_REG("inDAC");
-	mga_outb(M_RAMDAC_BASE+M_X_INDEX, reg);
-	return mga_inb(M_RAMDAC_BASE+M_X_DATAREG);
-}
-
-#define outTi3026 outDAC
-#define inTi3026 inDAC
-#define outDAC1064 outDAC
-#define inDAC1064 inDAC
-
-static void matroxfb_createcursorshape(WPMINFO struct display* p, int vmode) {
-	unsigned int h;
-	unsigned int cu, cd;
-
-	h = fontheight(p);
-
-	if (vmode & FB_VMODE_DOUBLE)
-		h *= 2;
-	cd = h;
-	if (cd >= 10)
-		cd--;
-	switch (ACCESS_FBINFO(cursor.type) = (p->conp->vc_cursor_type & CUR_HWMASK)) {
-		case CUR_NONE:
-				cu = cd;
-				break;
-		case CUR_UNDERLINE:
-				cu = cd - 2;
-				break;
-		case CUR_LOWER_THIRD:
-				cu = (h * 2) / 3;
-				break;
-		case CUR_LOWER_HALF:
-				cu = h / 2;
-				break;
-		case CUR_TWO_THIRDS:
-				cu = h / 3;
-				break;
-		case CUR_BLOCK:
-		default:
-				cu = 0;
-				cd = h;
-				break;
-	}
-	ACCESS_FBINFO(cursor.w) = fontwidth(p);
-	ACCESS_FBINFO(cursor.u) = cu;
-	ACCESS_FBINFO(cursor.d) = cd;
-}	
-
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-#define POS3026_XCURCTRL	20
-
-static void matroxfb_ti3026_flashcursor(unsigned long ptr) {
-#define minfo ((struct matrox_fb_info*)ptr)
-	spin_lock(&ACCESS_FBINFO(lock.DAC));
-	outTi3026(PMINFO TVP3026_XCURCTRL, inTi3026(PMINFO TVP3026_XCURCTRL) ^ TVP3026_XCURCTRL_DIS ^ TVP3026_XCURCTRL_XGA);
-	ACCESS_FBINFO(cursor.timer.expires) = jiffies + HZ/2;
-	add_timer(&ACCESS_FBINFO(cursor.timer));
-	spin_unlock(&ACCESS_FBINFO(lock.DAC));
-#undef minfo
-}
-
-static void matroxfb_ti3026_createcursor(WPMINFO struct display* p) {
-	unsigned long flags;
-	u_int32_t xline;
-	unsigned int i;
-	unsigned int to;
-
-	if (ACCESS_FBINFO(currcon_display) != p)
-		return;
-
-	DBG("matroxfb_ti3026_createcursor");
-
-	matroxfb_createcursorshape(PMINFO p, p->var.vmode);
-
-	xline = (~0) << (32 - ACCESS_FBINFO(cursor.w));
-	spin_lock_irqsave(&ACCESS_FBINFO(lock.DAC), flags);
-	mga_outb(M_RAMDAC_BASE+TVP3026_INDEX, 0);
-	to = ACCESS_FBINFO(cursor.u);
-	for (i = 0; i < to; i++) {
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-	}
-	to = ACCESS_FBINFO(cursor.d);
-	for (; i < to; i++) {
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, xline >> 24);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, xline >> 16);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, xline >> 8);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, xline);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-	}
-	for (; i < 64; i++) {
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0);
-	}
-	for (i = 0; i < 512; i++) 
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURRAMDATA, 0xFF);
-	spin_unlock_irqrestore(&ACCESS_FBINFO(lock.DAC), flags);
-}
-	
-static void matroxfb_ti3026_cursor(struct display* p, int mode, int x, int y) {
-	unsigned long flags;
-	MINFO_FROM_DISP(p);
-
-	DBG("matroxfb_ti3026_cursor")
-	
-	if (ACCESS_FBINFO(currcon_display) != p)
-		return;
-
-	if (mode == CM_ERASE) {
-		if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
-			spin_lock_irqsave(&ACCESS_FBINFO(lock.DAC), flags);
-			ACCESS_FBINFO(cursor.state) = CM_ERASE;
-			del_timer(&ACCESS_FBINFO(cursor.timer));
-			outTi3026(PMINFO TVP3026_XCURCTRL, ACCESS_FBINFO(currenthw->DACreg[POS3026_XCURCTRL]));
-			spin_unlock_irqrestore(&ACCESS_FBINFO(lock.DAC), flags);
-		}
-		return;
-	}
-	if ((p->conp->vc_cursor_type & CUR_HWMASK) != ACCESS_FBINFO(cursor.type))
-		matroxfb_ti3026_createcursor(PMINFO p);
-	x *= fontwidth(p);
-	y *= fontheight(p);
-	y -= p->var.yoffset;
-	if (p->var.vmode & FB_VMODE_DOUBLE)
-		y *= 2;
-	spin_lock_irqsave(&ACCESS_FBINFO(lock.DAC), flags);
-	if ((x != ACCESS_FBINFO(cursor.x)) || (y != ACCESS_FBINFO(cursor.y)) || ACCESS_FBINFO(cursor.redraw)) {
-		ACCESS_FBINFO(cursor.redraw) = 0;
-		ACCESS_FBINFO(cursor.x) = x;
-		ACCESS_FBINFO(cursor.y) = y;
-		x += 64;
-		y += 64;
-		outTi3026(PMINFO TVP3026_XCURCTRL, ACCESS_FBINFO(currenthw->DACreg[POS3026_XCURCTRL]));
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURPOSXL, x);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURPOSXH, x >> 8);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURPOSYL, y);
-		mga_outb(M_RAMDAC_BASE+TVP3026_CURPOSYH, y >> 8);
-	}
-	ACCESS_FBINFO(cursor.state) = CM_DRAW;
-	if (ACCESS_FBINFO(devflags.blink))
-		mod_timer(&ACCESS_FBINFO(cursor.timer), jiffies + HZ/2);
-	outTi3026(PMINFO TVP3026_XCURCTRL, ACCESS_FBINFO(currenthw->DACreg[POS3026_XCURCTRL]) | TVP3026_XCURCTRL_XGA);
-	spin_unlock_irqrestore(&ACCESS_FBINFO(lock.DAC), flags);
-}
-#undef POS3026_XCURCTRL
-
-static int matroxfb_ti3026_setfont(struct display* p, int width, int height) {
-
-	DBG("matrox_ti3026_setfont");
-
-	if (p && p->conp)
-		matroxfb_ti3026_createcursor(PMXINFO(p) p);
-	return 0;
-}
-#endif
-
-#ifdef NEED_DAC1064
-
-static void matroxfb_DAC1064_flashcursor(unsigned long ptr) {
-#define minfo ((struct matrox_fb_info*)ptr)
-	spin_lock(&ACCESS_FBINFO(lock.DAC));
-	outDAC1064(PMINFO M1064_XCURCTRL, inDAC1064(PMINFO M1064_XCURCTRL) ^ M1064_XCURCTRL_DIS ^ M1064_XCURCTRL_XGA);	
-	ACCESS_FBINFO(cursor.timer.expires) = jiffies + HZ/2;
-	add_timer(&ACCESS_FBINFO(cursor.timer));
-	spin_unlock(&ACCESS_FBINFO(lock.DAC));
-#undef minfo
-}
-
-static void matroxfb_DAC1064_createcursor(WPMINFO struct display* p) {
-	vaddr_t cursorbase;
-	u_int32_t xline;
-	unsigned int i;
-	unsigned int h, to;
-
-	if (ACCESS_FBINFO(currcon_display) != p)
-		return;
-
-	matroxfb_createcursorshape(PMINFO p, p->var.vmode);
-
-	xline = (~0) << (32 - ACCESS_FBINFO(cursor.w));
-	cursorbase = ACCESS_FBINFO(video.vbase);
-	h = ACCESS_FBINFO(features.DAC1064.cursorimage);
-
-#ifdef __BIG_ENDIAN
-	WaitTillIdle();
-	mga_outl(M_OPMODE, M_OPMODE_32BPP);
-#endif
-	to = ACCESS_FBINFO(cursor.u);
-	for (i = 0; i < to; i++) {
-		mga_writel(cursorbase, h, 0);
-		mga_writel(cursorbase, h+4, 0);
-		mga_writel(cursorbase, h+8, ~0);
-		mga_writel(cursorbase, h+12, ~0);
-		h += 16;
-	}
-	to = ACCESS_FBINFO(cursor.d);
-	for (; i < to; i++) {
-		mga_writel(cursorbase, h, 0);
-		mga_writel(cursorbase, h+4, xline);
-		mga_writel(cursorbase, h+8, ~0);
-		mga_writel(cursorbase, h+12, ~0);
-		h += 16;
-	}
-	for (; i < 64; i++) {
-		mga_writel(cursorbase, h, 0);
-		mga_writel(cursorbase, h+4, 0);
-		mga_writel(cursorbase, h+8, ~0);
-		mga_writel(cursorbase, h+12, ~0);
-		h += 16;
-	}
-#ifdef __BIG_ENDIAN
-	mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
-#endif
-}
-	
-static void matroxfb_DAC1064_cursor(struct display* p, int mode, int x, int y) {
-	unsigned long flags;
-	MINFO_FROM_DISP(p);
-
-	if (ACCESS_FBINFO(currcon_display) != p)
-		return;
-
-	if (mode == CM_ERASE) {
-		if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
-			spin_lock_irqsave(&ACCESS_FBINFO(lock.DAC), flags);
-			ACCESS_FBINFO(cursor.state) = CM_ERASE;
-			del_timer(&ACCESS_FBINFO(cursor.timer));
-			outDAC1064(PMINFO M1064_XCURCTRL, M1064_XCURCTRL_DIS);
-			spin_unlock_irqrestore(&ACCESS_FBINFO(lock.DAC), flags);
-		}
-		return;
-	}
-	if ((p->conp->vc_cursor_type & CUR_HWMASK) != ACCESS_FBINFO(cursor.type))
-		matroxfb_DAC1064_createcursor(PMINFO p);
-	x *= fontwidth(p);
-	y *= fontheight(p);
-	y -= p->var.yoffset;
-	if (p->var.vmode & FB_VMODE_DOUBLE)
-		y *= 2;
-	spin_lock_irqsave(&ACCESS_FBINFO(lock.DAC), flags);
-	if ((x != ACCESS_FBINFO(cursor.x)) || (y != ACCESS_FBINFO(cursor.y)) || ACCESS_FBINFO(cursor.redraw)) {
-		ACCESS_FBINFO(cursor.redraw) = 0;
-		ACCESS_FBINFO(cursor.x) = x;
-		ACCESS_FBINFO(cursor.y) = y;
-		x += 64;
-		y += 64;
-		outDAC1064(PMINFO M1064_XCURCTRL, M1064_XCURCTRL_DIS);
-		mga_outb(M_RAMDAC_BASE+M1064_CURPOSXL, x);
-		mga_outb(M_RAMDAC_BASE+M1064_CURPOSXH, x >> 8);
-		mga_outb(M_RAMDAC_BASE+M1064_CURPOSYL, y);
-		mga_outb(M_RAMDAC_BASE+M1064_CURPOSYH, y >> 8);
-	}
-	ACCESS_FBINFO(cursor.state) = CM_DRAW;
-	if (ACCESS_FBINFO(devflags.blink))
-		mod_timer(&ACCESS_FBINFO(cursor.timer), jiffies + HZ/2);
-	outDAC1064(PMINFO M1064_XCURCTRL, M1064_XCURCTRL_XGA);
-	spin_unlock_irqrestore(&ACCESS_FBINFO(lock.DAC), flags);
-}
-
-static int matroxfb_DAC1064_setfont(struct display* p, int width, int height) {
-	if (p && p->conp)
-		matroxfb_DAC1064_createcursor(PMXINFO(p) p);
-	return 0;
-}
-#endif
-
-#ifndef FNTCHARCNT
-#define FNTCHARCNT(fd)	(((int *)(fd))[-3])
-#endif
-
-static int matroxfb_fastfont_tryset(WPMINFO struct display* p) {
-	unsigned int fsize;
-	unsigned int width;
-
-	if (!p || !p->fontdata)
-		return 0;
-	width = fontwidth(p);
-	if (width > 32)
-		return 0;
-	fsize = (p->userfont?FNTCHARCNT(p->fontdata):256) * fontheight(p);
-	if (((fsize * width + 31) / 32) * 4 > ACCESS_FBINFO(fastfont.size))
-		return 0;
-
-	mga_outl(M_OPMODE, M_OPMODE_8BPP);
-	if (width <= 8) {
-		if (width == 8)
-			mga_memcpy_toio(ACCESS_FBINFO(fastfont.vbase), 0, p->fontdata, fsize);
-		else {
-			vaddr_t dst;
-			unsigned int i;
-			u_int8_t* font;
-			u_int32_t mask, valid, reg;
-
-			dst = ACCESS_FBINFO(fastfont.vbase);
-			font = (u_int8_t*)p->fontdata;
-			mask = ~0 << (8 - width);
-			valid = 0;
-			reg = 0;
-			i = 0;
-			while (fsize--) {
-				reg |= (*font++ & mask) << (8 - valid);
-				valid += width;
-				if (valid >= 8) {
-					mga_writeb(dst, i++, reg >> 8);
-					reg = reg << 8;
-					valid -= 8;
-				}
-			}
-			if (valid)
-				mga_writeb(dst, i, reg >> 8);
-		}
-	} else if (width <= 16) {
-		if (width == 16)
-			mga_memcpy_toio(ACCESS_FBINFO(fastfont.vbase), 0, p->fontdata, fsize*2);
-		else {
-			vaddr_t dst;
-			u_int16_t* font;
-			u_int32_t mask, valid, reg;
-			unsigned int i;
-
-			dst = ACCESS_FBINFO(fastfont.vbase);
-			font = (u_int16_t*)p->fontdata;
-			mask = ~0 << (16 - width);
-			valid = 0;
-			reg = 0;
-			i = 0;
-			while (fsize--) {
-				reg |= (ntohs(*font++) & mask) << (16 - valid);
-				valid += width;
-				if (valid >= 16) {
-					mga_writew(dst, i, htons(reg >> 16));
-					i += 2;
-					reg = reg << 16;
-					valid -= 16;
-				}
-			}
-			if (valid)
-				mga_writew(dst, i, htons(reg >> 16));
-		}
-	} else {
-		if (width == 32)
-			mga_memcpy_toio(ACCESS_FBINFO(fastfont.vbase), 0, p->fontdata, fsize*4);
-		else {
-			vaddr_t dst;
-			u_int32_t* font;
-			u_int32_t mask, valid, reg;
-			unsigned int i;
-
-			dst = ACCESS_FBINFO(fastfont.vbase);
-			font = (u_int32_t*)p->fontdata;
-			mask = ~0 << (32 - width);
-			valid = 0;
-			reg = 0;
-			i = 0;
-			while (fsize--) {
-				reg |= (ntohl(*font) & mask) >> valid;
-				valid += width;
-				if (valid >= 32) {
-					mga_writel(dst, i, htonl(reg));
-					i += 4;
-					valid -= 32;
-					if (valid)
-						reg = (ntohl(*font) & mask) << (width - valid);
-					else
-						reg = 0;
-				}
-				font++;
-			}
-			if (valid)
-				mga_writel(dst, i, htonl(reg));
-		}
-	}
-	mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
-
-	return 1;
-}
-
-static void matrox_text_setup(struct display* p) {
-	MINFO_FROM_DISP(p);
-
-	p->next_line = p->line_length ? p->line_length : ((p->var.xres_virtual / (fontwidth(p)?fontwidth(p):8)) * ACCESS_FBINFO(devflags.textstep));
-	p->next_plane = 0;
-}
-
-static void matrox_text_bmove(struct display* p, int sy, int sx, int dy, int dx,
-		int height, int width) {
-	unsigned int srcoff;
-	unsigned int dstoff;
-	unsigned int step;
-	MINFO_FROM_DISP(p);
-
-	step = ACCESS_FBINFO(devflags.textstep);
-	srcoff = (sy * p->next_line) + (sx * step);
-	dstoff = (dy * p->next_line) + (dx * step);
-	if (dstoff < srcoff) {
-		while (height > 0) {
-			int i;
-			for (i = width; i > 0; dstoff += step, srcoff += step, i--)
-				mga_writew(ACCESS_FBINFO(video.vbase), dstoff, mga_readw(ACCESS_FBINFO(video.vbase), srcoff));
-			height--;
-			dstoff += p->next_line - width * step;
-			srcoff += p->next_line - width * step;
-		}
-	} else {
-		unsigned int off;
-
-		off = (height - 1) * p->next_line + (width - 1) * step;
-		srcoff += off;
-		dstoff += off;
-		while (height > 0) {
-			int i;
-			for (i = width; i > 0; dstoff -= step, srcoff -= step, i--)
-				mga_writew(ACCESS_FBINFO(video.vbase), dstoff, mga_readw(ACCESS_FBINFO(video.vbase), srcoff));
-			dstoff -= p->next_line - width * step;
-			srcoff -= p->next_line - width * step;
-			height--;
-		}
-	}
-}
-
-static void matrox_text_clear(struct vc_data* conp, struct display* p, int sy, int sx,
-		int height, int width) {
-	unsigned int offs;
-	unsigned int val;
-	unsigned int step;
-	MINFO_FROM_DISP(p);
-
-	step = ACCESS_FBINFO(devflags.textstep);
-	offs = sy * p->next_line + sx * step;
-	val = ntohs((attr_bgcol(p, conp->vc_video_erase_char) << 4) | attr_fgcol(p, conp->vc_video_erase_char) | (' ' << 8));
-
-	while (height > 0) {
-		int i;
-		for (i = width; i > 0; offs += step, i--)
-			mga_writew(ACCESS_FBINFO(video.vbase), offs, val);
-		offs += p->next_line - width * step;
-		height--;
-	}
-}
-
-static void matrox_text_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
-	unsigned int offs;
-	unsigned int chr;
-	unsigned int step;
-	MINFO_FROM_DISP(p);
-
-	step = ACCESS_FBINFO(devflags.textstep);
-	offs = yy * p->next_line + xx * step;
-	chr = attr_fgcol(p,c) | (attr_bgcol(p,c) << 4) | ((c & p->charmask) << 8);
-	if (chr & 0x10000) chr |= 0x08;
-
-	mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(chr));
-}
-
-static void matrox_text_putcs(struct vc_data* conp, struct display* p, const unsigned short* s,
-		int count, int yy, int xx) {
-	unsigned int offs;
-	unsigned int attr;
-	unsigned int step;
-	MINFO_FROM_DISP(p);
-
-	step = ACCESS_FBINFO(devflags.textstep);
-	offs = yy * p->next_line + xx * step;
-	attr = attr_fgcol(p, scr_readw(s)) | (attr_bgcol(p, scr_readw(s)) << 4);
-
-	while (count-- > 0) {
-		unsigned int chr = ((scr_readw(s++)) & p->charmask) << 8;
-		if (chr & 0x10000) chr ^= 0x10008;
-		mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(attr|chr));
-		offs += step;
-	}
-}
-
-static void matrox_text_revc(struct display* p, int xx, int yy) {
-	unsigned int offs;
-	unsigned int step;
-	MINFO_FROM_DISP(p);
-
-	step = ACCESS_FBINFO(devflags.textstep);
-	offs = yy * p->next_line + xx * step + 1;
-	
-	mga_writeb(ACCESS_FBINFO(video.vbase), offs, mga_readb(ACCESS_FBINFO(video.vbase), offs) ^ 0x77);
-}
-
-static int matrox_text_loadfont(WPMINFO struct display* p) {
-	unsigned int fsize;
-	unsigned int width;
-	vaddr_t dst;
-	unsigned int i;
-	u_int8_t* font;
-
-	if (!p || !p->fontdata)
-		return 0;
-	width = fontwidth(p);
-	fsize = p->userfont?FNTCHARCNT(p->fontdata):256;
-
-	dst = ACCESS_FBINFO(video.vbase);
-	i = 2;
-	font = (u_int8_t*)p->fontdata;
-
-	mga_setr(M_SEQ_INDEX, 0x02, 0x04);
-	while (fsize--) {
-		int l;
-
-		for (l = 0; l < fontheight(p); l++) {
-			mga_writeb(dst, i, *font++);
-			if (fontwidth(p) > 8) font++;
-			i += ACCESS_FBINFO(devflags.vgastep);
-		}
-		i += (32 - fontheight(p)) * ACCESS_FBINFO(devflags.vgastep);
-	}
-	mga_setr(M_SEQ_INDEX, 0x02, 0x03);
-
-	return 1;
-}
-
-static void matrox_text_createcursor(WPMINFO struct display* p) {
-
-	if (ACCESS_FBINFO(currcon_display) != p)
-		return;
-
-	matroxfb_createcursorshape(PMINFO p, 0);
-
-	mga_setr(M_CRTC_INDEX, 0x0A, ACCESS_FBINFO(cursor.u));
-	mga_setr(M_CRTC_INDEX, 0x0B, ACCESS_FBINFO(cursor.d) - 1);
-}
-
-static void matrox_text_cursor(struct display* p, int mode, int x, int y) {
-	unsigned int pos;
-	MINFO_FROM_DISP(p);
-
-	if (ACCESS_FBINFO(currcon_display) != p)
-		return;
-
-	if (mode == CM_ERASE) {
-		if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
-
-			mga_setr(M_CRTC_INDEX, 0x0A, 0x20);
-
-			ACCESS_FBINFO(cursor.state) = CM_ERASE;
-		}
-		return;
-	}
-	if ((p->conp->vc_cursor_type & CUR_HWMASK) != ACCESS_FBINFO(cursor.type))
-		matrox_text_createcursor(PMINFO p);
-
-	/* DO NOT CHECK cursor.x != x because of vgaHWinit moves cursor to 0,0 */
-	ACCESS_FBINFO(cursor.x) = x;
-	ACCESS_FBINFO(cursor.y) = y;
-	pos = p->next_line / ACCESS_FBINFO(devflags.textstep) * y + x;
-
-	mga_setr(M_CRTC_INDEX, 0x0F, pos);
-	mga_setr(M_CRTC_INDEX, 0x0E, pos >> 8);
-
-	mga_setr(M_CRTC_INDEX, 0x0A, ACCESS_FBINFO(cursor.u));
-
-	ACCESS_FBINFO(cursor.state) = CM_DRAW;
-}
-
-static void matrox_text_round(CPMINFO struct fb_var_screeninfo* var, struct display* p) {
-	unsigned hf;
-	unsigned vf;
-	unsigned vxres;
-	unsigned ych;
-
-	hf = fontwidth(p);
-	if (!hf) hf = 8;
-	/* do not touch xres */
-	vxres = (var->xres_virtual + hf - 1) / hf;
-	if (vxres >= 256)
-		vxres = 255;
-	if (vxres < 16)
-		vxres = 16;
-	vxres = (vxres + 1) & ~1;	/* must be even */
-	vf = fontheight(p);
-	if (!vf) vf = 16;
-	if (var->yres < var->yres_virtual) {
-		ych = ACCESS_FBINFO(devflags.textvram) / vxres;
-		var->yres_virtual = ych * vf;
-	} else
-		ych = var->yres_virtual / vf;
-	if (vxres * ych > ACCESS_FBINFO(devflags.textvram)) {
-		ych = ACCESS_FBINFO(devflags.textvram) / vxres;
-		var->yres_virtual = ych * vf;
-	}
-	var->xres_virtual = vxres * hf;
-}
-
-static int matrox_text_setfont(struct display* p, int width, int height) {
-	DBG("matrox_text_setfont");
-
-	if (p) {
-		MINFO_FROM_DISP(p);
-		
-		matrox_text_round(PMINFO &p->var, p);
-		p->next_line = p->line_length = ((p->var.xres_virtual / (fontwidth(p)?fontwidth(p):8)) * ACCESS_FBINFO(devflags.textstep));
-
-		if (p->conp)
-			matrox_text_createcursor(PMINFO p);
-	}
-	return 0;
-}
-
-#define matrox_cfb16_revc matrox_cfbX_revc
-#define matrox_cfb24_revc matrox_cfbX_revc
-#define matrox_cfb32_revc matrox_cfbX_revc
-
-#define matrox_cfb24_clear matrox_cfb32_clear
-#define matrox_cfb24_putc matrox_cfb32_putc
-#define matrox_cfb24_putcs matrox_cfb32_putcs
-
-#ifdef FBCON_HAS_VGATEXT
-static struct display_switch matroxfb_text = {
-	matrox_text_setup,    matrox_text_bmove,  matrox_text_clear,
-	matrox_text_putc,     matrox_text_putcs,  matrox_text_revc,
-	matrox_text_cursor,   matrox_text_setfont, NULL,
-	FONTWIDTH(8)|FONTWIDTH(9)
-};
-#endif
-
-#ifdef FBCON_HAS_CFB4
-static struct display_switch matroxfb_cfb4 = {
-	fbcon_cfb4_setup,     matrox_cfb4_bmove,  matrox_cfb4_clear,
-	fbcon_cfb4_putc,      fbcon_cfb4_putcs,	  matrox_cfb4_revc,
-	NULL,		      NULL,		  NULL,
-	/* cursor... */       /* set_font... */
-	FONTWIDTH(8) /* fix, fix, fix it */
-};
-#endif
-
-#ifdef FBCON_HAS_CFB8
-static struct display_switch matroxfb_cfb8 = {
-	fbcon_cfb8_setup,     matrox_cfbX_bmove,  matrox_cfb8_clear,
-	matrox_cfb8_putc,     matrox_cfb8_putcs,  matrox_cfb8_revc,
-	NULL,		      NULL,		  matrox_cfbX_clear_margins,
-	~1 /* FONTWIDTHS */
-};
-#endif
-
-#ifdef FBCON_HAS_CFB16
-static struct display_switch matroxfb_cfb16 = {
-	fbcon_cfb16_setup,    matrox_cfbX_bmove,  matrox_cfb16_clear,
-	matrox_cfb16_putc,    matrox_cfb16_putcs, matrox_cfb16_revc,
-	NULL,		      NULL,		  matrox_cfbX_clear_margins,
-	~1 /* FONTWIDTHS */
-};
-#endif
-
-#ifdef FBCON_HAS_CFB24
-static struct display_switch matroxfb_cfb24 = {
-	fbcon_cfb24_setup,    matrox_cfbX_bmove,  matrox_cfb24_clear,
-	matrox_cfb24_putc,    matrox_cfb24_putcs, matrox_cfb24_revc,
-	NULL,		      NULL,		  matrox_cfbX_clear_margins,
-	~1 /* FONTWIDTHS */ /* TODO: and what about non-aligned access on BE? I think that there are no in my code */
-};
-#endif
-
-#ifdef FBCON_HAS_CFB32
-static struct display_switch matroxfb_cfb32 = {
-	fbcon_cfb32_setup,    matrox_cfbX_bmove,  matrox_cfb32_clear,
-	matrox_cfb32_putc,    matrox_cfb32_putcs, matrox_cfb32_revc,
-	NULL,		      NULL,		  matrox_cfbX_clear_margins,
-	~1 /* FONTWIDTHS */
-};
-#endif
-
-static void initMatrox(WPMINFO struct display* p) {
-	struct display_switch *swtmp;
-
-	DBG("initMatrox")
-	
-	if (ACCESS_FBINFO(currcon_display) != p)
-		return;
-	if (p->dispsw && p->conp)
-		fb_con.con_cursor(p->conp, CM_ERASE);
-	p->dispsw_data = NULL;
-	if ((p->var.accel_flags & FB_ACCELF_TEXT) != FB_ACCELF_TEXT) {
-		if (p->type == FB_TYPE_TEXT) {
-			swtmp = &matroxfb_text;
-		} else {
-			switch (p->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB4
-			case 4:
-				swtmp = &fbcon_cfb4;
-				break;
-#endif
-#ifdef FBCON_HAS_CFB8
-			case 8:
-				swtmp = &fbcon_cfb8;
-				break;
-#endif
-#ifdef FBCON_HAS_CFB16
-			case 16:
-				p->dispsw_data = &ACCESS_FBINFO(cmap.cfb16);
-				swtmp = &fbcon_cfb16;
-				break;
-#endif
-#ifdef FBCON_HAS_CFB24
-			case 24:
-				p->dispsw_data = &ACCESS_FBINFO(cmap.cfb24);
-				swtmp = &fbcon_cfb24;
-				break;
-#endif
-#ifdef FBCON_HAS_CFB32
-			case 32:
-				p->dispsw_data = &ACCESS_FBINFO(cmap.cfb32);
-				swtmp = &fbcon_cfb32;
-				break;
-#endif
-			default:
-				p->dispsw = &fbcon_dummy;
-				return;
-			}
-		}
-		dprintk(KERN_INFO "matroxfb: acceleration disabled\n");
-	} else if (p->type == FB_TYPE_TEXT) {
-		swtmp = &matroxfb_text;
-	} else {
-		switch (p->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB4
-		case 4:
-			swtmp = &matroxfb_cfb4;
-			break;
-#endif
-#ifdef FBCON_HAS_CFB8
-		case 8:
-			swtmp = &matroxfb_cfb8;
-			break;
-#endif
-#ifdef FBCON_HAS_CFB16
-		case 16:
-			p->dispsw_data = &ACCESS_FBINFO(cmap.cfb16);
-			swtmp = &matroxfb_cfb16;
-			break;
-#endif
-#ifdef FBCON_HAS_CFB24
-		case 24:
-			p->dispsw_data = &ACCESS_FBINFO(cmap.cfb24);
-			swtmp = &matroxfb_cfb24;
-			break;
-#endif
-#ifdef FBCON_HAS_CFB32
-		case 32:
-			p->dispsw_data = &ACCESS_FBINFO(cmap.cfb32);
-			swtmp = &matroxfb_cfb32;
-			break;
-#endif
-		default:
-			p->dispsw = &fbcon_dummy;
-			return;
-		}
-	}
-	memcpy(&ACCESS_FBINFO(dispsw), swtmp, sizeof(ACCESS_FBINFO(dispsw)));
-	p->dispsw = &ACCESS_FBINFO(dispsw);
-	if ((p->type != FB_TYPE_TEXT) && ACCESS_FBINFO(devflags.hwcursor)) {
-		if (isMillenium(MINFO)) {
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-			ACCESS_FBINFO(dispsw.cursor) = matroxfb_ti3026_cursor;
-			ACCESS_FBINFO(dispsw.set_font) = matroxfb_ti3026_setfont;
-#endif
-		} else {
-#ifdef NEED_DAC1064
-			ACCESS_FBINFO(dispsw.cursor) = matroxfb_DAC1064_cursor;
-			ACCESS_FBINFO(dispsw.set_font) = matroxfb_DAC1064_setfont;
-#endif
-		}
-	}
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * card parameters
- */
-
-/* --------------------------------------------------------------------- */
-
-static struct fb_var_screeninfo vesafb_defined __initdata = {
-	640,480,640,480,/* W,H, W, H (virtual) load xres,xres_virtual*/
-	0,0,		/* virtual -> visible no offset */
-	8,		/* depth -> load bits_per_pixel */
-	0,		/* greyscale ? */
-	{0,0,0},	/* R */
-	{0,0,0},	/* G */
-	{0,0,0},	/* B */
-	{0,0,0},	/* transparency */
-	0,		/* standard pixel format */
-	FB_ACTIVATE_NOW,
-	-1,-1,
-	FB_ACCELF_TEXT,	/* accel flags */
-	39721L,48L,16L,33L,10L,
-	96L,2L,~0,	/* No sync info */
-	FB_VMODE_NONINTERLACED,
-	{0,0,0,0,0,0}
-};
-
-
-
-/* --------------------------------------------------------------------- */
-
-static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
-	unsigned int pos;
-	unsigned short p0, p1, p2;
-#ifdef CONFIG_FB_MATROX_32MB
-	unsigned int p3;
-#endif
-	struct display *disp;
-
-	DBG("matrox_pan_var")
-	
-	disp = ACCESS_FBINFO(currcon_display);
-	if (disp->type == FB_TYPE_TEXT) {
-		pos = var->yoffset / fontheight(disp) * disp->next_line / ACCESS_FBINFO(devflags.textstep) + var->xoffset / (fontwidth(disp)?fontwidth(disp):8);
-	} else {
-		pos = (var->yoffset * var->xres_virtual + var->xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32;
-		pos += ACCESS_FBINFO(curr.ydstorg.chunks);
-	}
-	p0 = ACCESS_FBINFO(currenthw)->CRTC[0x0D] = pos & 0xFF;
-	p1 = ACCESS_FBINFO(currenthw)->CRTC[0x0C] = (pos & 0xFF00) >> 8;
-	p2 = ACCESS_FBINFO(currenthw)->CRTCEXT[0] = (ACCESS_FBINFO(currenthw)->CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
-#ifdef CONFIG_FB_MATROX_32MB
-	p3 = ACCESS_FBINFO(currenthw)->CRTCEXT[8] = pos >> 21;
-#endif	
-
-	mga_setr(M_CRTC_INDEX, 0x0D, p0);
-	mga_setr(M_CRTC_INDEX, 0x0C, p1);
-#ifdef CONFIG_FB_MATROX_32MB
-	if (ACCESS_FBINFO(devflags.support32MB))
-		mga_setr(M_EXTVGA_INDEX, 0x08, p3);
-#endif
-	mga_setr(M_EXTVGA_INDEX, 0x00, p2);
-}
-
-	/*
-	 * Open/Release the frame buffer device
-	 */
-
-static int matroxfb_open(struct fb_info *info, int user)
-{
-	DBG_LOOP("matroxfb_open")
-	
-	/*
-	 * Nothing, only a usage count for the moment
-	 */
-	MOD_INC_USE_COUNT;
-	return(0);
-}
-
-static int matroxfb_release(struct fb_info *info, int user)
-{
-	DBG_LOOP("matroxfb_release")
-	
-	MOD_DEC_USE_COUNT;
-	return(0);
-}
-
-static int matroxfb_pan_display(struct fb_var_screeninfo *var, int con,
-		struct fb_info* info) {
-#define minfo ((struct matrox_fb_info*)info)
-	
-	DBG("matroxfb_pan_display")
-	
-	if (var->vmode & FB_VMODE_YWRAP) {
-		if (var->yoffset < 0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset)
-			return -EINVAL;
-	} else {
-		if (var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual ||
-		    var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)
-			return -EINVAL;
-	}
-	if (con == ACCESS_FBINFO(currcon))
-		matrox_pan_var(PMINFO var);
-	fb_display[con].var.xoffset = var->xoffset;
-	fb_display[con].var.yoffset = var->yoffset;
-	if (var->vmode & FB_VMODE_YWRAP)
-		fb_display[con].var.vmode |= FB_VMODE_YWRAP;
-	else
-		fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
-	return 0;
-#undef minfo
-}
-	
-static int matroxfb_updatevar(int con, struct fb_info *info)
-{
-#define minfo ((struct matrox_fb_info*)info)
-	DBG("matroxfb_updatevar");
-
-	matrox_pan_var(PMINFO &fb_display[con].var);
-	return 0;
-#undef minfo
-}
-
-static int matroxfb_get_final_bppShift(CPMINFO int bpp) {
-	int bppshft2;
-
-	DBG("matroxfb_get_final_bppShift")
-	
-	bppshft2 = bpp;
-	if (!bppshft2) {
-		return 8;
-	}
-	if (isInterleave(MINFO))
-		bppshft2 >>= 1;
-	if (ACCESS_FBINFO(devflags.video64bits))
-		bppshft2 >>= 1;
-	return bppshft2;
-}
-				
-static int matroxfb_test_and_set_rounding(CPMINFO int xres, int bpp) {
-	int over;
-	int rounding;
-
-	DBG("matroxfb_test_and_set_rounding")
-	
-	switch (bpp) {
-		case 0:		return xres;
-		case 4:		rounding = 128;
-				break;
-		case 8:		rounding = 64;	/* doc says 64; 32 is OK for G400 */
-				break;
-		case 16:	rounding = 32;
-				break;
-		case 24:	rounding = 64;	/* doc says 64; 32 is OK for G400 */
-				break;
-		default:	rounding = 16;
-				/* on G400, 16 really does not work */
-				if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400)
-					rounding = 32;
-				break;
-	}
-	if (isInterleave(MINFO)) {
-		rounding *= 2;
-	}
-	over = xres % rounding;
-	if (over) 
-		xres += rounding-over;
-	return xres;
-}
-
-static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) {
-	const int* width;
-	int xres_new;
-
-	DBG("matroxfb_pitch_adjust")
-
-	if (!bpp) return xres;
-	
-	width = ACCESS_FBINFO(capable.vxres);
-
-	if (ACCESS_FBINFO(devflags.precise_width)) {
-		while (*width) {
-			if ((*width >= xres) && (matroxfb_test_and_set_rounding(PMINFO *width, bpp) == *width)) {
-				break;
-			}
-			width++;
-		}
-		xres_new = *width;
-	} else {
-		xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp);
-	}
-	if (!xres_new) return 0;
-	if (xres != xres_new) {
-		printk(KERN_INFO "matroxfb: cannot set xres to %d, rounded up to %d\n", xres, xres_new);
-	}
-	return xres_new;
-}
-
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-static const unsigned char DACseq[] =
-{ TVP3026_XLATCHCTRL, TVP3026_XTRUECOLORCTRL, 
-  TVP3026_XMUXCTRL, TVP3026_XCLKCTRL, 
-  TVP3026_XPALETTEPAGE, 
-  TVP3026_XGENCTRL, 
-  TVP3026_XMISCCTRL, 
-  TVP3026_XGENIOCTRL,
-  TVP3026_XGENIODATA, 
-  TVP3026_XCOLKEYOVRMIN, TVP3026_XCOLKEYOVRMAX, TVP3026_XCOLKEYREDMIN, TVP3026_XCOLKEYREDMAX,
-  TVP3026_XCOLKEYGREENMIN, TVP3026_XCOLKEYGREENMAX, TVP3026_XCOLKEYBLUEMIN, TVP3026_XCOLKEYBLUEMAX,
-  TVP3026_XCOLKEYCTRL,
-  TVP3026_XMEMPLLCTRL, TVP3026_XSENSETEST, TVP3026_XCURCTRL };
-
-#define POS3026_XLATCHCTRL	0
-#define POS3026_XTRUECOLORCTRL	1
-#define POS3026_XMUXCTRL	2
-#define POS3026_XCLKCTRL	3
-#define POS3026_XGENCTRL	5
-#define POS3026_XMISCCTRL	6
-#define POS3026_XMEMPLLCTRL	18
-#define POS3026_XCURCTRL	20
-
-static const unsigned char MGADACbpp32[] =
-{ TVP3026_XLATCHCTRL_2_1, TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_8888,
-  0x00, TVP3026_XCLKCTRL_DIV1 | TVP3026_XCLKCTRL_SRC_PLL, 
-  0x00, 
-  TVP3026_XGENCTRL_HSYNC_POS | TVP3026_XGENCTRL_VSYNC_POS | TVP3026_XGENCTRL_LITTLE_ENDIAN | TVP3026_XGENCTRL_BLACK_0IRE | TVP3026_XGENCTRL_NO_SYNC_ON_GREEN | TVP3026_XGENCTRL_OVERSCAN_DIS, 
-  TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_HIGH, 
-  0x00, 
-  0x1E, 
-  0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF,
-  TVP3026_XCOLKEYCTRL_ZOOM1, 
-  0x00, 0x00, TVP3026_XCURCTRL_DIS };
-#endif	/* CONFIG_FB_MATROX_MILLENIUM */
-
-static int PLL_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) {
-	unsigned int bestdiff = ~0;
-	unsigned int bestvco = 0;
-	unsigned int fxtal = ACCESS_FBINFO(features.pll.ref_freq);
-	unsigned int fwant;
-	unsigned int p;
-
-	DBG("PLL_calcclock")
-	
-	fwant = freq;
-
-#ifdef DEBUG
-	printk(KERN_ERR "post_shift_max: %d\n", ACCESS_FBINFO(features.pll.post_shift_max));
-	printk(KERN_ERR "ref_freq: %d\n", ACCESS_FBINFO(features.pll.ref_freq));
-	printk(KERN_ERR "freq: %d\n", freq);
-	printk(KERN_ERR "vco_freq_min: %d\n", ACCESS_FBINFO(features.pll.vco_freq_min));
-	printk(KERN_ERR "in_div_min: %d\n", ACCESS_FBINFO(features.pll.in_div_min));
-	printk(KERN_ERR "in_div_max: %d\n", ACCESS_FBINFO(features.pll.in_div_max));
-	printk(KERN_ERR "feed_div_min: %d\n", ACCESS_FBINFO(features.pll.feed_div_min));
-	printk(KERN_ERR "feed_div_max: %d\n", ACCESS_FBINFO(features.pll.feed_div_max));
-	printk(KERN_ERR "fmax: %d\n", fmax);
-#endif
-	for (p = 1; p <= ACCESS_FBINFO(features.pll.post_shift_max); p++) {
-		if (fwant * 2 > fmax)
-			break;
-		fwant *= 2;
-	}
-	if (fwant < ACCESS_FBINFO(features.pll.vco_freq_min)) fwant = ACCESS_FBINFO(features.pll.vco_freq_min);
-	if (fwant > fmax) fwant = fmax;
-	for (; p-- > 0; fwant >>= 1, bestdiff >>= 1) {
-		unsigned int m;
-
-		if (fwant < ACCESS_FBINFO(features.pll.vco_freq_min)) break;
-		for (m = ACCESS_FBINFO(features.pll.in_div_min); m <= ACCESS_FBINFO(features.pll.in_div_max); m++) {
-			unsigned int diff, fvco;
-			unsigned int n;
-
-			n = (fwant * (m + 1) + (fxtal >> 1)) / fxtal - 1;
-			if (n > ACCESS_FBINFO(features.pll.feed_div_max)) 
-				break;
-			if (n < ACCESS_FBINFO(features.pll.feed_div_min))
-				n = ACCESS_FBINFO(features.pll.feed_div_min);
-			fvco = (fxtal * (n + 1)) / (m + 1);
-			if (fvco < fwant)
-				diff = fwant - fvco;
-			else
-				diff = fvco - fwant;
-			if (diff < bestdiff) {
-				bestdiff = diff;
-				*post = p;
-				*in = m;
-				*feed = n;
-				bestvco = fvco;
-			}
-		}
-	}
-	dprintk(KERN_ERR "clk: %02X %02X %02X %d %d %d\n", *in, *feed, *post, fxtal, bestvco, fwant);
-	return bestvco;
-}
-
-#ifdef NEED_DAC1064
-static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) {
-	unsigned int fvco;
-	unsigned int p;
-
-	DBG("DAC1064_calcclock")
-	
-	fvco = PLL_calcclock(PMINFO freq, fmax, in, feed, &p);
-	p = (1 << p) - 1;
-	if (fvco <= 100000)
-		;
-	else if (fvco <= 140000)
-		p |= 0x08;
-	else if (fvco <= 180000)
-		p |= 0x10;
-	else
-		p |= 0x18;
-	*post = p;
-}
-#endif
-
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-static int Ti3026_calcclock(CPMINFO unsigned int freq, unsigned int fmax, int* in, int* feed, int* post) {
-	unsigned int fvco;
-	unsigned int lin, lfeed, lpost;
-
-	DBG("Ti3026_calcclock")
-	
-	fvco = PLL_calcclock(PMINFO freq, fmax, &lin, &lfeed, &lpost);
-	fvco >>= (*post = lpost);
-	*in = 64 - lin;
-	*feed = 64 - lfeed;
-	return fvco;
-}
-
-static int Ti3026_setpclk(CPMINFO struct matrox_hw_state* hw, int clk, struct display* p) {
-	unsigned int f_pll;
-	unsigned int pixfeed, pixin, pixpost;
-	
-	DBG("Ti3026_setpclk")
-	
-	f_pll = Ti3026_calcclock(PMINFO clk, ACCESS_FBINFO(max_pixel_clock), &pixin, &pixfeed, &pixpost);
-	
-	hw->DACclk[0] = pixin | 0xC0;
-	hw->DACclk[1] = pixfeed;
-	hw->DACclk[2] = pixpost | 0xB0;
-
-	if (p->type == FB_TYPE_TEXT) {
-		hw->DACreg[POS3026_XMEMPLLCTRL] = TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_RCLK_PIXPLL;
-		hw->DACclk[3] = 0xFD;
-		hw->DACclk[4] = 0x3D;
-		hw->DACclk[5] = 0x70;
-	} else {
-		unsigned int loopfeed, loopin, looppost, loopdiv, z;
-		unsigned int Bpp;
-
-		Bpp = ACCESS_FBINFO(curr.final_bppShift);
-
-		if (p->var.bits_per_pixel == 24) {
-			loopfeed = 3;		/* set lm to any possible value */
-			loopin = 3 * 32 / Bpp;
-		} else {
-			loopfeed = 4;
-			loopin = 4 * 32 / Bpp;
-		}
-		z = (110000 * loopin) / (f_pll * loopfeed);
-		loopdiv = 0; /* div 2 */
-		if (z < 2)
-			looppost = 0;
-		else if (z < 4)
-			looppost = 1;
-		else if (z < 8)
-			looppost = 2;
-		else {
-			looppost = 3;
-			loopdiv = z/16; 
-		}
-		if (p->var.bits_per_pixel == 24) {
-			hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0;
-			hw->DACclk[4] = (65 - loopfeed) | 0x80;
-			if (ACCESS_FBINFO(accel.ramdac_rev) > 0x20) {
-				if (isInterleave(MINFO))
-					hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_8_3;
-				else {
-					hw->DACclk[4] &= ~0xC0;
-					hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_4_3;
-				}
-			} else {
-				if (isInterleave(MINFO))
-					;	/* default... */
-				else {
-					hw->DACclk[4] ^= 0xC0;	/* change from 0x80 to 0x40 */
-					hw->DACreg[POS3026_XLATCHCTRL] = TVP3026A_XLATCHCTRL_4_3;
-				}
-			}
-			hw->DACclk[5] = looppost | 0xF8;
-			if (ACCESS_FBINFO(devflags.mga_24bpp_fix))
-				hw->DACclk[5] ^= 0x40;
-		} else {
-			hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0;
-			hw->DACclk[4] = 65 - loopfeed;
-			hw->DACclk[5] = looppost | 0xF0;
-		}
-		hw->DACreg[POS3026_XMEMPLLCTRL] = loopdiv | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_RCLK_LOOPPLL;
-	}
-	return 0;
-}
-#endif
-
-static void var2my(struct fb_var_screeninfo* var, struct my_timming* mt) {
-	unsigned int pixclock = var->pixclock;
-	
-	DBG("var2my")
-	
-	if (!pixclock) pixclock = 10000;	/* 10ns = 100MHz */
-	mt->pixclock = 1000000000 / pixclock;
-	if (mt->pixclock < 1) mt->pixclock = 1;
-	mt->dblscan = var->vmode & FB_VMODE_DOUBLE;
-	mt->interlaced = var->vmode & FB_VMODE_INTERLACED;
-	mt->HDisplay = var->xres;
-	mt->HSyncStart = mt->HDisplay + var->right_margin;
-	mt->HSyncEnd = mt->HSyncStart + var->hsync_len;
-	mt->HTotal = mt->HSyncEnd + var->left_margin;
-	mt->VDisplay = var->yres;
-	mt->VSyncStart = mt->VDisplay + var->lower_margin;
-	mt->VSyncEnd = mt->VSyncStart + var->vsync_len;
-	mt->VTotal = mt->VSyncEnd + var->upper_margin;
-	mt->sync = var->sync;
-}
-
-static int vgaHWinit(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
-	unsigned int hd, hs, he, hbe, ht;
-	unsigned int vd, vs, ve, vt;
-	unsigned int wd;
-	unsigned int divider;
-	int i;
-	int text = p->type == FB_TYPE_TEXT;
-	int fwidth;
-
-	if (text) {
-		fwidth = fontwidth(p);
-		if (!fwidth) fwidth = 8;
-	} else
-		fwidth = 8;
-
-	DBG("vgaHWinit")
-	
-	hw->SEQ[0] = 0x00;
-	if (fwidth == 9)
-		hw->SEQ[1] = 0x00;
-	else
-		hw->SEQ[1] = 0x01;	/* or 0x09 */
-	hw->SEQ[2] = 0x0F;	/* bitplanes */
-	hw->SEQ[3] = 0x00;
-	if (text)
-		hw->SEQ[4] = 0x02;
-	else
-		hw->SEQ[4] = 0x0E;
-	/* CRTC 0..7, 9, 16..19, 21, 22 are reprogrammed by Matrox Millenium code... Hope that by MGA1064 too */
-	if (m->dblscan) {
-		m->VTotal <<= 1;
-		m->VDisplay <<= 1;
-		m->VSyncStart <<= 1;
-		m->VSyncEnd <<= 1;
-	}
-	if (m->interlaced) {
-		m->VTotal >>= 1;
-		m->VDisplay >>= 1;
-		m->VSyncStart >>= 1;
-		m->VSyncEnd >>= 1;
-	}
-
-	/* GCTL is ignored when not using 0xA0000 aperture */
-	hw->GCTL[0] = 0x00;
-	hw->GCTL[1] = 0x00;
-	hw->GCTL[2] = 0x00;
-	hw->GCTL[3] = 0x00;
-	hw->GCTL[4] = 0x00;
-	if (text) {
-		hw->GCTL[5] = 0x10;
-		hw->GCTL[6] = 0x02;
-	} else {
-		hw->GCTL[5] = 0x40;
-		hw->GCTL[6] = 0x05;
-	}
-	hw->GCTL[7] = 0x0F;
-	hw->GCTL[8] = 0xFF;
-
-	/* Whole ATTR is ignored in PowerGraphics mode */
-	for (i = 0; i < 16; i++)
-		hw->ATTR[i] = i;
-	if (text) {
-		hw->ATTR[16] = 0x04;
-	} else {
-		hw->ATTR[16] = 0x41;
-	}
-	hw->ATTR[17] = 0xFF;
-	hw->ATTR[18] = 0x0F;
-	if (fwidth == 9)
-		hw->ATTR[19] = 0x08;
-	else
-		hw->ATTR[19] = 0x00;
-	hw->ATTR[20] = 0x00;
-
-	if (text) {
-		hd = m->HDisplay / fwidth;
-		hs = m->HSyncStart / fwidth;
-		he = m->HSyncEnd / fwidth;
-		ht = m->HTotal / fwidth;
-		divider = 8;
-	} else {
-		hd = m->HDisplay >> 3;
-		hs = m->HSyncStart >> 3;
-		he = m->HSyncEnd >> 3;
-		ht = m->HTotal >> 3;
-		/* standard timmings are in 8pixels, but for interleaved we cannot */
-		/* do it for 4bpp (because of (4bpp >> 1(interleaved))/4 == 0) */
-		/* using 16 or more pixels per unit can save us */
-		divider = ACCESS_FBINFO(curr.final_bppShift);
-	}
-	while (divider & 3) {
-		hd >>= 1;
-		hs >>= 1;
-		he >>= 1;
-		ht >>= 1;
-		divider <<= 1;
-	}
-	divider = divider / 4;
-	/* divider can be from 1 to 8 */
-	while (divider > 8) {
-		hd <<= 1;
-		hs <<= 1;
-		he <<= 1;
-		ht <<= 1;
-		divider >>= 1;
-	}
-	hd = hd - 1;
-	hs = hs - 1;
-	he = he - 1;
-	ht = ht - 1;
-	vd = m->VDisplay - 1;
-	vs = m->VSyncStart - 1;
-	ve = m->VSyncEnd - 1;
-	vt = m->VTotal - 2;
-	/* G200 cannot work with (ht & 7) == 6 */
-	if (((ht & 0x07) == 0x06) || ((ht & 0x0F) == 0x04))
-		ht++;
-	if (text) {
-		hbe = ht - 1;
-		wd = p->var.xres_virtual / (fwidth * 2);
-	} else {
-		hbe = ht;
-		wd = p->var.xres_virtual * ACCESS_FBINFO(curr.final_bppShift) / 64;
-	}
-
-	hw->CRTCEXT[0] = 0;
-	hw->CRTCEXT[5] = 0;
-	if (m->interlaced) {
-		hw->CRTCEXT[0] = 0x80;
-		hw->CRTCEXT[5] = (hs + he - ht) >> 1;
-		if (!m->dblscan)
-			wd <<= 1;
-		vt &= ~1;
-	}
-	hw->CRTCEXT[0] |=  (wd & 0x300) >> 4;
-	hw->CRTCEXT[1] = (((ht - 4) & 0x100) >> 8) |
-			  ((hd      & 0x100) >> 7) | /* blanking */
-			  ((hs      & 0x100) >> 6) | /* sync start */
-			   (hbe     & 0x040);	 /* end hor. blanking */
-	hw->CRTCEXT[2] =  ((vt & 0xC00) >> 10) |
-			  ((vd & 0x400) >>  8) |	/* disp end */
-			  ((vd & 0xC00) >>  7) |	/* vblanking start */
-			  ((vs & 0xC00) >>  5);
-	if (text)
-		hw->CRTCEXT[3] = 0x00;
-	else
-		hw->CRTCEXT[3] = (divider - 1) | 0x80;
-	hw->CRTCEXT[4] = 0;
-
-	hw->CRTC[0] = ht-4;
-	hw->CRTC[1] = hd;
-	hw->CRTC[2] = hd;
-	hw->CRTC[3] = (hbe & 0x1F) | 0x80;
-	hw->CRTC[4] = hs;
-	hw->CRTC[5] = ((hbe & 0x20) << 2) | (he & 0x1F);
-	if (text)
-		hw->CRTC[5] |= 0x60;	/* delay sync for 3 clocks (to same picture position on MGA and VGA) */
-	hw->CRTC[6] = vt & 0xFF;
-	hw->CRTC[7] = ((vt & 0x100) >> 8) |
-		      ((vd & 0x100) >> 7) |
-		      ((vs & 0x100) >> 6) |
-		      ((vd & 0x100) >> 5) |
-		      0x10                |
-		      ((vt & 0x200) >> 4) |
-		      ((vd & 0x200) >> 3) |
-		      ((vs & 0x200) >> 2);
-	hw->CRTC[8] = 0x00;
-	hw->CRTC[9] = ((vd & 0x200) >> 4) | 0x40;
-	if (text)
-		hw->CRTC[9] |= fontheight(p) - 1;
-	if (m->dblscan && !m->interlaced)
-		hw->CRTC[9] |= 0x80;
-	for (i = 10; i < 16; i++)
-		hw->CRTC[i] = 0x00;
-	hw->CRTC[16] = vs /* & 0xFF */;
-	hw->CRTC[17] = (ve & 0x0F) | 0x20;
-	hw->CRTC[18] = vd /* & 0xFF */;
-	hw->CRTC[19] = wd /* & 0xFF */;
-	hw->CRTC[20] = 0x00;
-	hw->CRTC[21] = vd /* & 0xFF */;
-	hw->CRTC[22] = (vt + 1) /* & 0xFF */;
-	if (text) {
-		if (ACCESS_FBINFO(devflags.textmode) == 1)
-			hw->CRTC[23] = 0xC3;
-		else
-			hw->CRTC[23] = 0xA3;
-		if (ACCESS_FBINFO(devflags.textmode) == 4)
-			hw->CRTC[20] = 0x5F;
-		else
-			hw->CRTC[20] = 0x1F;
-	} else
-		hw->CRTC[23] = 0xC3;
-	hw->CRTC[24] = 0xFF;
-	return 0;
-};
-
-#ifdef NEED_DAC1064
-
-static const unsigned char MGA1064_DAC_regs[] = {
-		M1064_XCURADDL, M1064_XCURADDH, M1064_XCURCTRL,
-		M1064_XCURCOL0RED, M1064_XCURCOL0GREEN, M1064_XCURCOL0BLUE,
-		M1064_XCURCOL1RED, M1064_XCURCOL1GREEN, M1064_XCURCOL1BLUE,
-		M1064_XCURCOL2RED, M1064_XCURCOL2GREEN, M1064_XCURCOL2BLUE, 
-		DAC1064_XVREFCTRL, M1064_XMULCTRL, M1064_XPIXCLKCTRL, M1064_XGENCTRL, 
-		M1064_XMISCCTRL,
-		M1064_XGENIOCTRL, M1064_XGENIODATA, M1064_XZOOMCTRL, M1064_XSENSETEST, 
-		M1064_XCRCBITSEL,
-		M1064_XCOLKEYMASKL, M1064_XCOLKEYMASKH, M1064_XCOLKEYL, M1064_XCOLKEYH };
-
-#define POS1064_XCURADDL		 0
-#define POS1064_XCURADDH		 1
-#define POS1064_XVREFCTRL		12
-#define POS1064_XMULCTRL		13
-#define POS1064_XGENCTRL		15
-#define POS1064_XMISCCTRL		16
-
-static const unsigned char MGA1064_DAC[] = {
-		0x00, 0x00, M1064_XCURCTRL_DIS,
-		0x00, 0x00, 0x00, 	/* black */
-		0xFF, 0xFF, 0xFF,	/* white */
-		0xFF, 0x00, 0x00,	/* red */ 
-		0x00, 0,  
-		M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL, 
-		M1064_XGENCTRL_VS_0 | M1064_XGENCTRL_ALPHA_DIS | M1064_XGENCTRL_BLACK_0IRE | M1064_XGENCTRL_NO_SYNC_ON_GREEN, 
-		M1064_XMISCCTRL_DAC_EN | M1064_XMISCCTRL_MFC_DIS | M1064_XMISCCTRL_DAC_8BIT | M1064_XMISCCTRL_LUT_EN,
-		0x10, 0x3F, M1064_XZOOMCTRL_1, M1064_XSENSETEST_BCOMP | M1064_XSENSETEST_GCOMP | M1064_XSENSETEST_RCOMP | M1064_XSENSETEST_PDOWN, 
-		0x00,
-		0x00, 0x00, 0xFF, 0xFF};
-
-static void DAC1064_setpclk(CPMINFO struct matrox_hw_state* hw, unsigned long fout) {
-	unsigned int m, n, p;
-
-	DBG("DAC1064_setpclk")
-	
-	DAC1064_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
-	hw->DACclk[0] = m;
-	hw->DACclk[1] = n;
-	hw->DACclk[2] = p;
-}
-
-static void __init DAC1064_setmclk(CPMINFO struct matrox_hw_state* hw, int oscinfo, unsigned long fmem){
-	u_int32_t mx;
-
-	DBG("DAC1064_setmclk")
-
-	if (ACCESS_FBINFO(devflags.noinit)) {
-		/* read MCLK and give up... */
-		hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);
-		hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);
-		hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);
-		return;
-	}
-	mx = hw->MXoptionReg | 0x00000004;
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
-	mx &= ~0x000000BB;
-	if (oscinfo & DAC1064_OPT_GDIV1)
-		mx |= 0x00000008;
-	if (oscinfo & DAC1064_OPT_MDIV1)
-		mx |= 0x00000010;
-	if (oscinfo & DAC1064_OPT_RESERVED)
-		mx |= 0x00000080;
-	if ((oscinfo & DAC1064_OPT_SCLK_MASK) == DAC1064_OPT_SCLK_PLL) {
-		/* select PCI clock until we have setup oscilator... */
-		int clk;
-		unsigned int m, n, p;
-
-		/* powerup system PLL, select PCI clock */
-		mx |= 0x00000020;
-		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
-		mx &= ~0x00000004;
-		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
-
-		/* !!! you must not access device if MCLK is not running !!!
-		   Doing so cause immediate PCI lockup :-( Maybe they should
-		   generate ABORT or I/O (parity...) error and Linux should 
-		   recover from this... (kill driver/process). But world is not
-		   perfect... */
-		/* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not
-		   select PLL... because of PLL can be stopped at this time) */
-		DAC1064_calcclock(PMINFO fmem, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
-		outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3] = m);
-		outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4] = n);
-		outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5] = p);
-		for (clk = 65536; clk; --clk) {
-			if (inDAC1064(PMINFO DAC1064_XSYSPLLSTAT) & 0x40)
-				break;
-		}
-		if (!clk)
-			printk(KERN_ERR "matroxfb: aiee, SYSPLL not locked\n");
-		/* select PLL */
-		mx |= 0x00000005;
-	} else {
-		/* select specified system clock source */
-		mx |= oscinfo & DAC1064_OPT_SCLK_MASK;
-	}
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
-	mx &= ~0x00000004;
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
-	hw->MXoptionReg = mx;
-}
-
-static int DAC1064_init_1(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display *p) {
-	
-	DBG("DAC1064_init_1")
-	
-	memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs));
-	if (p->type == FB_TYPE_TEXT) {
-		hw->DACreg[POS1064_XMISCCTRL] = M1064_XMISCCTRL_DAC_EN
-					      | M1064_XMISCCTRL_MFC_DIS
-					      | M1064_XMISCCTRL_DAC_6BIT
-					      | M1064_XMISCCTRL_LUT_EN;
-		hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP 
-				             | M1064_XMULCTRL_GRAPHICS_PALETIZED;
-	} else {
-		switch (p->var.bits_per_pixel) {
-		/* case 4: not supported by MGA1064 DAC */
-		case 8:	
-			hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
-			break;
-		case 16:
-			if (p->var.green.length == 5)
-				hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
-			else
-				hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
-			break;
-		case 24: 
-			hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_24BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
-			break;
-		case 32:
-			hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_32BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
-			break;
-		default:
-			return 1;	/* unsupported depth */
-		}
-	}
-	hw->DACreg[POS1064_XVREFCTRL] = ACCESS_FBINFO(features.DAC1064.xvrefctrl);
-	hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK;
-	hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN;
-	hw->DACreg[POS1064_XCURADDL] = ACCESS_FBINFO(features.DAC1064.cursorimage) >> 10;
-	hw->DACreg[POS1064_XCURADDH] = ACCESS_FBINFO(features.DAC1064.cursorimage) >> 18;
-	return 0;
-}
-
-static int DAC1064_init_2(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
-	
-	DBG("DAC1064_init_2")
-	
-	DAC1064_setpclk(PMINFO hw, m->pixclock);
-	if (p->var.bits_per_pixel > 16) {	/* 256 entries */
-		int i;
-
-		for (i = 0; i < 256; i++) {
-			hw->DACpal[i * 3 + 0] = i;
-			hw->DACpal[i * 3 + 1] = i;
-			hw->DACpal[i * 3 + 2] = i;
-		}
-	} else if (p->var.bits_per_pixel > 8) {
-		if (p->var.green.length == 5) {	/* 0..31, 128..159 */
-			int i;
-
-			for (i = 0; i < 32; i++) {
-				/* with p15 == 0 */
-				hw->DACpal[i * 3 + 0] = i << 3;
-				hw->DACpal[i * 3 + 1] = i << 3;
-				hw->DACpal[i * 3 + 2] = i << 3;
-				/* with p15 == 1 */
-				hw->DACpal[(i + 128) * 3 + 0] = i << 3;
-				hw->DACpal[(i + 128) * 3 + 1] = i << 3;
-				hw->DACpal[(i + 128) * 3 + 2] = i << 3;
-			}
-		} else {
-			int i;
-
-			for (i = 0; i < 64; i++) {		/* 0..63 */
-				hw->DACpal[i * 3 + 0] = i << 3;
-				hw->DACpal[i * 3 + 1] = i << 2;
-				hw->DACpal[i * 3 + 2] = i << 3;
-			}
-		}
-	} else {
-		memset(hw->DACpal, 0, 768);
-	}
-	return 0;
-}
-
-static void DAC1064_restore_1(CPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw) {
-	
-	DBG("DAC1064_restore_1")
-
-	outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]);
-	outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]);
-	outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]);
-	if (!oldhw || memcmp(hw->DACreg, oldhw->DACreg, sizeof(MGA1064_DAC_regs))) {
-		unsigned int i;
-
-		for (i = 0; i < sizeof(MGA1064_DAC_regs); i++)
-			outDAC1064(PMINFO MGA1064_DAC_regs[i], hw->DACreg[i]);
-	}
-}
-
-static void DAC1064_restore_2(WPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw, struct display* p) {
-	unsigned int i;
-	unsigned int tmout;
-	
-	DBG("DAC1064_restore_2")
-
-	for (i = 0; i < 3; i++)
-		outDAC1064(PMINFO M1064_XPIXPLLCM + i, hw->DACclk[i]);
-	for (tmout = 500000; tmout; tmout--) {
-		if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
-			break;
-		udelay(10);
-	}
-
-	if (!tmout)
-		printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
-
-	if (p && p->conp) {
-		if (p->type == FB_TYPE_TEXT) {
-			matrox_text_createcursor(PMINFO p);
-			matrox_text_loadfont(PMINFO p);
-			i = 0;
-		} else {
-			matroxfb_DAC1064_createcursor(PMINFO p);
-			i = matroxfb_fastfont_tryset(PMINFO p);
-		}
-	} else
-		i = 0;
-	if (i) {
-		ACCESS_FBINFO(curr.putc) = matrox_cfbX_fastputc;
-		ACCESS_FBINFO(curr.putcs) = matrox_cfbX_fastputcs;
-	} else {
-		ACCESS_FBINFO(curr.putc) = matrox_cfbX_putc;
-		ACCESS_FBINFO(curr.putcs) = matrox_cfbX_putcs;
-	}
-#ifdef DEBUG
-	dprintk(KERN_DEBUG "DAC1064regs ");
-	for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
-		dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], hw->DACreg[i]);
-		if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
-	}
-	dprintk("\n" KERN_DEBUG "DAC1064clk ");
-	for (i = 0; i < 6; i++)
-		dprintk("C%02X=%02X ", i, hw->DACclk[i]);
-	dprintk("\n");
-#endif
-}
-#endif /* NEED_DAC1064 */
-
-#ifdef CONFIG_FB_MATROX_MYSTIQUE
-static int MGA1064_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
-	
-	DBG("MGA1064_init")
-	
-	if (DAC1064_init_1(PMINFO hw, m, p)) return 1;
-	if (vgaHWinit(PMINFO hw, m, p)) return 1;
-
-	hw->MiscOutReg = 0xCB;
-	if (m->sync & FB_SYNC_HOR_HIGH_ACT)
-		hw->MiscOutReg &= ~0x40;
-	if (m->sync & FB_SYNC_VERT_HIGH_ACT)
-		hw->MiscOutReg &= ~0x80;
-	if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
-		hw->CRTCEXT[3] |= 0x40;
-
-	if (DAC1064_init_2(PMINFO hw, m, p)) return 1;
-	return 0;		
-}
-#endif
-
-#ifdef CONFIG_FB_MATROX_G100
-static int MGAG100_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
-
-	DBG("MGAG100_init")
-
-	if (DAC1064_init_1(PMINFO hw, m, p)) return 1;
-	hw->MXoptionReg &= ~0x2000;
-	if (vgaHWinit(PMINFO hw, m, p)) return 1;
-
-	hw->MiscOutReg = 0xEF;
-	if (m->sync & FB_SYNC_HOR_HIGH_ACT)
-		hw->MiscOutReg &= ~0x40;
-	if (m->sync & FB_SYNC_VERT_HIGH_ACT)
-		hw->MiscOutReg &= ~0x80;
-	if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
-		hw->CRTCEXT[3] |= 0x40;
-
-	if (DAC1064_init_2(PMINFO hw, m, p)) return 1;
-	return 0;		
-}
-#endif	/* G100 */
-
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-static int Ti3026_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
-	u_int8_t muxctrl = isInterleave(MINFO) ? TVP3026_XMUXCTRL_MEMORY_64BIT : TVP3026_XMUXCTRL_MEMORY_32BIT;
-
-	DBG("Ti3026_init")
-
-	memcpy(hw->DACreg, MGADACbpp32, sizeof(hw->DACreg));
-	if (p->type == FB_TYPE_TEXT) {
-		hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_8_1;
-		hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
-		hw->DACreg[POS3026_XMUXCTRL] = TVP3026_XMUXCTRL_VGA;
-		hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | 
-					       TVP3026_XCLKCTRL_DIV4;
-		hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_6BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
-	} else {
-		switch (p->var.bits_per_pixel) {
-		case 4:	hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1;	/* or _8_1, they are same */
-			hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
-			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_4BIT;
-			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV8;
-			hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
-			break;
-		case 8: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_8_1;	/* or _4_1, they are same */
-			hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
-			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_8BIT;
-			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;
-			hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
-			break;
-		case 16:
-			/* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used everytime) */
-			hw->DACreg[POS3026_XTRUECOLORCTRL] = (p->var.green.length == 5)? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555 ) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565);
-			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT;
-			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2;
-			break;
-		case 24:
-			/* XLATCHCTRL is: for (A) use _4_3 (?_8_3 is same? TBD), for (B) it is set in setpclk */
-			hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_888;
-			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;
-			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;
-			break;
-		case 32:
-			/* XLATCHCTRL should be _2_1 / _1_1... Why is not? (_2_1 is used everytime) */
-			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;
-			break;
-		default:
-			return 1;	/* TODO: failed */
-		}
-	}
-	if (vgaHWinit(PMINFO hw, m, p)) return 1;
-
-	/* set SYNC */
-	hw->MiscOutReg = 0xCB;
-	if (m->sync & FB_SYNC_HOR_HIGH_ACT)
-		hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_HSYNC_NEG;
-	if (m->sync & FB_SYNC_VERT_HIGH_ACT)
-		hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_VSYNC_NEG;
-	if (m->sync & FB_SYNC_ON_GREEN)
-		hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_SYNC_ON_GREEN;
-
-	/* set DELAY */
-	if (ACCESS_FBINFO(video.len) < 0x400000)
-		hw->CRTCEXT[3] |= 0x08;
-	else if (ACCESS_FBINFO(video.len) > 0x400000)
-		hw->CRTCEXT[3] |= 0x10;
-
-	/* set HWCURSOR */
-	if (m->interlaced) {
-		hw->DACreg[POS3026_XCURCTRL] |= TVP3026_XCURCTRL_INTERLACED;
-	}
-	if (m->HTotal >= 1536)
-		hw->DACreg[POS3026_XCURCTRL] |= TVP3026_XCURCTRL_BLANK4096;
-
-	/* set interleaving */
-	hw->MXoptionReg &= ~0x00001000;
-	if ((p->type != FB_TYPE_TEXT) && isInterleave(MINFO)) hw->MXoptionReg |= 0x00001000;
-
-	/* set DAC */
-	Ti3026_setpclk(PMINFO hw, m->pixclock, p);
-	return 0;
-}
-#endif	/* CONFIG_FB_MATROX_MILLENIUM */
-
-static int matroxfb_get_cmap_len(struct fb_var_screeninfo *var) {
-
-	DBG("matroxfb_get_cmap_len")
-
-	switch (var->bits_per_pixel) {
-#ifdef FBCON_HAS_VGATEXT
-		case 0:
-			return 16;	/* pseudocolor... 16 entries HW palette */
-#endif
-#ifdef FBCON_HAS_CFB4
-		case 4:
-			return 16;	/* pseudocolor... 16 entries HW palette */
-#endif
-#ifdef FBCON_HAS_CFB8
-		case 8:
-			return 256;	/* pseudocolor... 256 entries HW palette */
-#endif
-#ifdef FBCON_HAS_CFB16
-		case 16:
-			return 16;	/* directcolor... 16 entries SW palette */
-					/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
-#endif
-#ifdef FBCON_HAS_CFB24
-		case 24:
-			return 16;	/* directcolor... 16 entries SW palette */
-					/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
-#endif
-#ifdef FBCON_HAS_CFB32
-		case 32:
-			return 16;	/* directcolor... 16 entries SW palette */
-					/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
-#endif
-	}
-	return 16;	/* return something reasonable... or panic()? */
-}
-
-static int matroxfb_decode_var(CPMINFO struct display* p, struct fb_var_screeninfo *var, int *visual, int *video_cmap_len, unsigned int* ydstorg) {
-	unsigned int vramlen;
-	unsigned int memlen;
-
-	DBG("matroxfb_decode_var")
-	
-	switch (var->bits_per_pixel) {
-#ifdef FBCON_HAS_VGATEXT
-		case 0:	 if (!ACCESS_FBINFO(capable.text)) return -EINVAL;
-			 break;
-#endif
-#ifdef FBCON_HAS_CFB4
-		case 4:	 if (!ACCESS_FBINFO(capable.cfb4)) return -EINVAL;
-			 break;
-#endif
-#ifdef FBCON_HAS_CFB8
-		case 8:	 break;
-#endif
-#ifdef FBCON_HAS_CFB16
-		case 16: break;
-#endif
-#ifdef FBCON_HAS_CFB24
-		case 24: break;
-#endif
-#ifdef FBCON_HAS_CFB32
-		case 32: break;
-#endif
-		default: return -EINVAL;
-	}
-	*ydstorg = 0;
-	vramlen = ACCESS_FBINFO(video.len_usable);
-	if (var->bits_per_pixel) {
-		var->xres_virtual = matroxfb_pitch_adjust(PMINFO var->xres_virtual, var->bits_per_pixel);
-		memlen = var->xres_virtual * var->bits_per_pixel * var->yres_virtual / 8;
-		if (memlen > vramlen) {
-			var->yres_virtual = vramlen * 8 / (var->xres_virtual * var->bits_per_pixel);
-			memlen = var->xres_virtual * var->bits_per_pixel * var->yres_virtual / 8;
-		}
-		/* There is hardware bug that no line can cross 4MB boundary */
-		/* give up for CFB24, it is impossible to easy workaround it */
-		/* for other try to do something */
-		if (!ACCESS_FBINFO(capable.cross4MB) && (memlen > 0x400000)) {
-			if (var->bits_per_pixel == 24) {
-				/* sorry */
-			} else {
-				unsigned int linelen;
-				unsigned int m1 = linelen = var->xres_virtual * var->bits_per_pixel / 8;
-				unsigned int m2 = PAGE_SIZE;	/* or 128 if you do not need PAGE ALIGNED address */
-				unsigned int max_yres;
-
-				while (m1) {
-					int t;
-
-					while (m2 >= m1) m2 -= m1;
-					t = m1;
-					m1 = m2;
-					m2 = t;
-				}
-				m2 = linelen * PAGE_SIZE / m2;
-				*ydstorg = m2 = 0x400000 % m2;
-				max_yres = (vramlen - m2) / linelen;
-				if (var->yres_virtual > max_yres)
-					var->yres_virtual = max_yres;
-			}
-		}
-	} else {
-		matrox_text_round(PMINFO var, p);
-#if 0
-/* we must limit pixclock by mclk... 
-   Millenium I:    66 MHz = 15000
-   Millenium II:   61 MHz = 16300
-   Millenium G200: 83 MHz = 12000 */
-		if (var->pixclock < 15000)
-			var->pixclock = 15000;	/* limit for "normal" gclk & mclk */
-#endif
-	}
-	/* YDSTLEN contains only signed 16bit value */
-	if (var->yres_virtual > 32767)
-		var->yres_virtual = 32767;
-	if (var->yres_virtual < var->yres)
-		var->yres = var->yres_virtual;
-	if (var->xres_virtual < var->xres)
-		var->xres = var->xres_virtual;
-	if (var->xoffset + var->xres > var->xres_virtual)
-		var->xoffset = var->xres_virtual - var->xres;
-	if (var->yoffset + var->yres > var->yres_virtual)
-		var->yoffset = var->yres_virtual - var->yres;
-
-	if (var->bits_per_pixel == 0) {
-		var->red.offset = 0;
-		var->red.length = 6;
-		var->green.offset = 0;
-		var->green.length = 6;
-		var->blue.offset = 0;
-		var->blue.length = 6;
-		var->transp.offset = 0;
-		var->transp.length = 0;
-		*visual = MX_VISUAL_PSEUDOCOLOR;
-	} else if (var->bits_per_pixel == 4) {
-		var->red.offset = 0;
-		var->red.length = 8;
-		var->green.offset = 0;
-		var->green.length = 8;
-		var->blue.offset = 0;
-		var->blue.length = 8;
-		var->transp.offset = 0;
-		var->transp.length = 0;
-		*visual = MX_VISUAL_PSEUDOCOLOR;
-	} else if (var->bits_per_pixel <= 8) {
-		var->red.offset = 0;
-		var->red.length = 8;
-		var->green.offset = 0;
-		var->green.length = 8;
-		var->blue.offset = 0;
-		var->blue.length = 8;
-		var->transp.offset = 0;
-		var->transp.length = 0;
-		*visual = MX_VISUAL_PSEUDOCOLOR;
-	} else {
-		if (var->bits_per_pixel <= 16) {
-			if (var->green.length == 5) {
-				var->red.offset    = 10;
-				var->red.length    = 5;
-				var->green.offset  = 5;
-				var->green.length  = 5;
-				var->blue.offset   = 0;
-				var->blue.length   = 5;
-				var->transp.offset = 15;
-				var->transp.length = 1;
-			} else {
-				var->red.offset    = 11;
-				var->red.length    = 5;
-				var->green.offset  = 5;
-				var->green.length  = 6;
-				var->blue.offset   = 0;
-				var->blue.length   = 5;
-				var->transp.offset = 0;
-				var->transp.length = 0;
-			}
-		} else if (var->bits_per_pixel <= 24) {
-			var->red.offset    = 16;
-			var->red.length    = 8;
-			var->green.offset  = 8;
-			var->green.length  = 8;
-			var->blue.offset   = 0;
-			var->blue.length   = 8;
-			var->transp.offset = 0;
-			var->transp.length = 0;
-		} else {
-			var->red.offset    = 16;
-			var->red.length    = 8;
-			var->green.offset  = 8;
-			var->green.length  = 8;
-			var->blue.offset   = 0;
-			var->blue.length   = 8;
-			var->transp.offset = 24;
-			var->transp.length = 8;
-		}
-		dprintk("matroxfb: truecolor: "
-		       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
-		       var->transp.length,
-		       var->red.length,
-		       var->green.length,
-		       var->blue.length,
-		       var->transp.offset,
-		       var->red.offset,
-		       var->green.offset,
-		       var->blue.offset);
-		*visual = MX_VISUAL_DIRECTCOLOR;
-	}
-	*video_cmap_len = matroxfb_get_cmap_len(var);
-	dprintk(KERN_INFO "requested %d*%d/%dbpp (%d*%d)\n", var->xres, var->yres, var->bits_per_pixel,
-				var->xres_virtual, var->yres_virtual);
-	return 0;
-}
-
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-static void __init ti3026_setMCLK(CPMINFO struct matrox_hw_state* hw, int fout){
-	unsigned int f_pll;
-	unsigned int pclk_m, pclk_n, pclk_p;
-	unsigned int mclk_m, mclk_n, mclk_p;
-	unsigned int rfhcnt, mclk_ctl;
-	int tmout;
-
-	DBG("ti3026_setMCLK")
-	
-	f_pll = Ti3026_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &mclk_n, &mclk_m, &mclk_p);
-
-	/* save pclk */
-	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC);
-	pclk_n = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
-	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFD);
-	pclk_m = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
-	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE);
-	pclk_p = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
-	
-	/* stop pclk */
-	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE);
-	outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00);
-
-	/* set pclk to new mclk */
-	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC);
-	outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_n | 0xC0);
-	outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_m);
-	outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_p | 0xB0);
-	
-	/* wait for PLL to lock */
-	for (tmout = 500000; tmout; tmout--) {
-		if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40)
-			break;
-		udelay(10);
-	};
-	if (!tmout)
-		printk(KERN_ERR "matroxfb: Temporary pixel PLL not locked after 5 secs\n");
-
-	/* output pclk on mclk pin */
-	mclk_ctl = inTi3026(PMINFO TVP3026_XMEMPLLCTRL);
-	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, mclk_ctl & 0xE7);
-	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_STROBEMKC4);
-
-	/* stop MCLK */
-	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFB);
-	outTi3026(PMINFO TVP3026_XMEMPLLDATA, 0x00);
-
-	/* set mclk to new freq */
-	outTi3026(PMINFO TVP3026_XPLLADDR, 0xF3);
-	outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_n | 0xC0);
-	outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_m);
-	outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_p | 0xB0);
-
-	/* wait for PLL to lock */
-	for (tmout = 500000; tmout; tmout--) {
-		if (inTi3026(PMINFO TVP3026_XMEMPLLDATA) & 0x40) 
-			break;
-		udelay(10);
-	}
-	if (!tmout)
-		printk(KERN_ERR "matroxfb: Memory PLL not locked after 5 secs\n");
-
-	f_pll = f_pll * 333 / (10000 << mclk_p);	
-	if (isMilleniumII(MINFO)) {
-		rfhcnt = (f_pll - 128) / 256;
-		if (rfhcnt > 15)
-			rfhcnt = 15;
-	} else {
-		rfhcnt = (f_pll - 64) / 128;
-		if (rfhcnt > 15)
-			rfhcnt = 0;
-	}
-	hw->MXoptionReg = (hw->MXoptionReg & ~0x000F0000) | (rfhcnt << 16);
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); 
-
-	/* output MCLK to MCLK pin */	
-	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);
-	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl       ) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_STROBEMKC4);
-
-	/* stop PCLK */
-	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE);
-	outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00);
-
-	/* restore pclk */
-	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC);
-	outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_n);
-	outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_m);
-	outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_p);
-
-	/* wait for PLL to lock */
-	for (tmout = 500000; tmout; tmout--) {
-		if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40)
-			break;
-		udelay(10);
-	}
-	if (!tmout)
-		printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
-}
-
-static void __init ti3026_ramdac_init(WPMINFO struct matrox_hw_state* hw){
-
-	DBG("ti3026_ramdac_init")
-
-	ACCESS_FBINFO(features.pll.vco_freq_min) = 110000; 
-	ACCESS_FBINFO(features.pll.ref_freq)     = 114545;
-	ACCESS_FBINFO(features.pll.feed_div_min) = 2;
-	ACCESS_FBINFO(features.pll.feed_div_max) = 24;
-	ACCESS_FBINFO(features.pll.in_div_min)   = 2;
-	ACCESS_FBINFO(features.pll.in_div_max)   = 63;
-	ACCESS_FBINFO(features.pll.post_shift_max) = 3;
-	if (ACCESS_FBINFO(devflags.noinit))
-		return;
-	ti3026_setMCLK(PMINFO hw, 60000);
-}
-#endif
-
-static void matroxfb_fastfont_init(struct matrox_fb_info* minfo){
-	unsigned int size;
-
-	size = ACCESS_FBINFO(fastfont.size);
-	ACCESS_FBINFO(fastfont.size) = 0;
-	if (size) {
-		unsigned int end = ACCESS_FBINFO(video.len_usable);
-
-		if (size < end) {
-			unsigned int start;
-
-			start = (end - size) & PAGE_MASK;
-			if (start >= 0x00100000) {
-				ACCESS_FBINFO(video.len_usable) = start;
-				ACCESS_FBINFO(fastfont.mgabase) = start * 8;
-				ACCESS_FBINFO(fastfont.vbase) = ACCESS_FBINFO(video.vbase);
-				vaddr_add(&ACCESS_FBINFO(fastfont.vbase), start);
-				ACCESS_FBINFO(fastfont.size) = end - start;
-			}
-		}
-	}
-}
-
-#ifdef CONFIG_FB_MATROX_MYSTIQUE
-static void __init MGA1064_ramdac_init(WPMINFO struct matrox_hw_state* hw){
-
-	DBG("MGA1064_ramdac_init");
-
-	/* ACCESS_FBINFO(features.DAC1064.vco_freq_min) = 120000; */
-	ACCESS_FBINFO(features.pll.vco_freq_min) = 62000; 
-	ACCESS_FBINFO(features.pll.ref_freq)     = 14318;
-	ACCESS_FBINFO(features.pll.feed_div_min) = 100;
-	ACCESS_FBINFO(features.pll.feed_div_max) = 127;
-	ACCESS_FBINFO(features.pll.in_div_min)   = 1;
-	ACCESS_FBINFO(features.pll.in_div_max)   = 31;
-	ACCESS_FBINFO(features.pll.post_shift_max) = 3;
-	ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_EXTERNAL;
-	/* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
-	DAC1064_setmclk(PMINFO hw, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
-}
-
-static int __init MGA1064_preinit(WPMINFO struct matrox_hw_state* hw){
-	static const int vxres_mystique[] = { 512,        640, 768,  800,  832,  960, 
-					     1024, 1152, 1280,      1600, 1664, 1920, 
-					     2048,    0};
-	DBG("MGA1064_preinit")
-
-	/* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
-	ACCESS_FBINFO(capable.text) = 1;
-	ACCESS_FBINFO(capable.vxres) = vxres_mystique;
-	ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
-	ACCESS_FBINFO(cursor.timer.function) = matroxfb_DAC1064_flashcursor;
-
-	if (ACCESS_FBINFO(devflags.noinit)) 
-		return 0;	/* do not modify settings */
-	hw->MXoptionReg &= 0xC0000100;
-	hw->MXoptionReg |= 0x00094E20;
-	if (ACCESS_FBINFO(devflags.novga))
-		hw->MXoptionReg &= ~0x00000100;
-	if (ACCESS_FBINFO(devflags.nobios))
-		hw->MXoptionReg &= ~0x40000000;
-	if (ACCESS_FBINFO(devflags.nopciretry))
-		hw->MXoptionReg |=  0x20000000;
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
-	mga_setr(M_SEQ_INDEX, 0x01, 0x20);
-	mga_outl(M_CTLWTST, 0x00000000);
-	udelay(200);
-	mga_outl(M_MACCESS, 0x00008000);
-	udelay(100);
-	mga_outl(M_MACCESS, 0x0000C000);
-	return 0;
-}
-
-static void __init MGA1064_reset(WPMINFO struct matrox_hw_state* hw){
-
-	DBG("MGA1064_reset");
-
-	ACCESS_FBINFO(features.DAC1064.cursorimage) = ACCESS_FBINFO(video.len_usable) - 1024;
-	if (ACCESS_FBINFO(devflags.hwcursor)) 
-		ACCESS_FBINFO(video.len_usable) -= 1024;
-	matroxfb_fastfont_init(MINFO);
-	MGA1064_ramdac_init(PMINFO hw);
-}
-#endif
-
-#ifdef CONFIG_FB_MATROX_G100
-/* BIOS environ */
-static int x7AF4 = 0x10;    /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
-			/* G100 wants 0x10, G200 SGRAM does not care... */
-#if 0 
-static int def50 = 0;	/* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
-#endif
-
-static void __init MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p){
-	int reg;
-	int selClk;
-	int clk;
-
-	DBG("MGAG100_progPixClock")
-	
-	outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS |
-	           M1064_XPIXCLKCTRL_PLL_UP);
-	switch (flags & 3) {
-		case 0:		reg = M1064_XPIXPLLAM; break;
-		case 1:		reg = M1064_XPIXPLLBM; break;
-		default:	reg = M1064_XPIXPLLCM; break;
-	}
-	outDAC1064(PMINFO reg++, m);
-	outDAC1064(PMINFO reg++, n);
-	outDAC1064(PMINFO reg, p);
-	selClk = mga_inb(M_MISC_REG_READ) & ~0xC;
-	/* there should be flags & 0x03 & case 0/1/else */
-	/* and we should first select source and after that we should wait for PLL */
-	/* and we are waiting for PLL with oscilator disabled... Is it right? */
-	switch (flags & 0x03) {
-		case 0x00:	break;
-		case 0x01:	selClk |= 4; break;
-		default:	selClk |= 0x0C; break;
-	}
-	mga_outb(M_MISC_REG, selClk);
-	for (clk = 500000; clk; clk--) {
-		if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
-			break;
-		udelay(10);
-	};
-	if (!clk)
-		printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A');
-	selClk = inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK;
-	switch (flags & 0x0C) {
-		case 0x00:	selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break;
-		case 0x04:	selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break;
-		default:	selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break;
-	}
-	outDAC1064(PMINFO M1064_XPIXCLKCTRL, selClk);
-	outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);
-}
-
-static void __init MGAG100_setPixClock(CPMINFO int flags, int freq){
-	unsigned int m, n, p;
-
-	DBG("MGAG100_setPixClock")
-	
-	DAC1064_calcclock(PMINFO freq, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
-	MGAG100_progPixClock(PMINFO flags, m, n, p);
-}
-
-static int __init MGAG100_preinit(WPMINFO struct matrox_hw_state* hw){
-	static const int vxres_g100[] = {  512,        640, 768,  800,  832,  960, 
-                                          1024, 1152, 1280,      1600, 1664, 1920, 
-                                          2048, 0};
-        u_int32_t reg50;
-#if 0
-	u_int32_t q;
-#endif
-
-	DBG("MGAG100_preinit")
-	
-	/* there are some instabilities if in_div > 19 && vco < 61000 */
-	ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
-	ACCESS_FBINFO(features.pll.ref_freq)     = 27000;
-	ACCESS_FBINFO(features.pll.feed_div_min) = 7;
-	ACCESS_FBINFO(features.pll.feed_div_max) = 127;
-	ACCESS_FBINFO(features.pll.in_div_min)   = 1;
-	ACCESS_FBINFO(features.pll.in_div_max)   = 31;
-	ACCESS_FBINFO(features.pll.post_shift_max) = 3;
-	ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_G100_DEFAULT;
-	/* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
-	ACCESS_FBINFO(capable.text) = 1;
-	ACCESS_FBINFO(capable.vxres) = vxres_g100;
-	ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
-	ACCESS_FBINFO(cursor.timer.function) = matroxfb_DAC1064_flashcursor;
-	ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) != FB_ACCEL_MATROX_MGAG100;
-
-	if (ACCESS_FBINFO(devflags.noinit))
-		return 0;
-	hw->MXoptionReg &= 0xC0000100;
-	hw->MXoptionReg |= 0x00078020;
-	if (ACCESS_FBINFO(devflags.novga))
-		hw->MXoptionReg &= ~0x00000100;
-	if (ACCESS_FBINFO(devflags.nobios))
-		hw->MXoptionReg &= ~0x40000000;
-	if (ACCESS_FBINFO(devflags.nopciretry))
-		hw->MXoptionReg |=  0x20000000;
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
-	pci_read_config_dword(ACCESS_FBINFO(pcidev), 0x50, &reg50);
-	reg50 &= ~0x3000;
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
-
-	DAC1064_setmclk(PMINFO hw, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333);
-
-	if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100) {
-		hw->MXoptionReg |= 0x1080;
-		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
-		mga_outl(M_CTLWTST, 0x00000300);
-		/* mga_outl(M_CTLWTST, 0x03258A31); */ 
-		udelay(100);
-		mga_outb(0x1C05, 0x00);
-		mga_outb(0x1C05, 0x80);
-		udelay(100);
-		mga_outb(0x1C05, 0x40);
-		mga_outb(0x1C05, 0xC0);
-		udelay(100);
-		reg50 &= ~0xFF;
-		reg50 |=  0x07;
-		pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
-		/* it should help with G100 */
-		mga_outb(M_GRAPHICS_INDEX, 6);
-		mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4);
-		mga_setr(M_EXTVGA_INDEX, 0x03, 0x81);
-		mga_setr(M_EXTVGA_INDEX, 0x04, 0x00);
-		mga_writeb(ACCESS_FBINFO(video.vbase), 0x0000, 0xAA);
-		mga_writeb(ACCESS_FBINFO(video.vbase), 0x0800, 0x55);
-		mga_writeb(ACCESS_FBINFO(video.vbase), 0x4000, 0x55);
-#if 0
-		if (mga_readb(ACCESS_FBINFO(video.vbase), 0x0000) != 0xAA) {
-			hw->MXoptionReg &= ~0x1000;
-		}
-#endif
-	} else {
-		hw->MXoptionReg |= 0x00000C00;
-		if (ACCESS_FBINFO(devflags.sgram))
-			hw->MXoptionReg |= 0x4000;
-		mga_outl(M_CTLWTST, 0x042450A1);
-		mga_outb(0x1E47, 0x00);
-		mga_outb(0x1E46, 0x00);
-		udelay(10);
-		mga_outb(0x1C05, 0x00);
-		mga_outb(0x1C05, 0x80);
-		udelay(100);
-		mga_outw(0x1E44, 0x0108);
-	}
-	hw->MXoptionReg = (hw->MXoptionReg & ~0x1F8000) | 0x78000;
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
-	return 0;
-}
-	
-static void __init MGAG100_reset(WPMINFO struct matrox_hw_state* hw){
-	u_int8_t b;
-
-	DBG("MGAG100_reset")
-
-	ACCESS_FBINFO(features.DAC1064.cursorimage) = ACCESS_FBINFO(video.len_usable) - 1024;
-	if (ACCESS_FBINFO(devflags.hwcursor)) 
-		ACCESS_FBINFO(video.len_usable) -= 1024;
-	matroxfb_fastfont_init(MINFO);
-
-	{
-#ifdef G100_BROKEN_IBM_82351
-		u_int32_t d;
-
-		find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */
-		pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b);
-		if (b == ACCESS_FBINFO(pcidev)->bus->number) {
-			pci_write_config_byte(ibm, PCI_COMMAND+1, 0);	/* disable back-to-back & SERR */
-			pci_write_config_byte(ibm, 0x41, 0xF4);		/* ??? */
-			pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0);	/* ??? */
-			pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00);	/* ??? */
-		}
-#endif
-		if (!ACCESS_FBINFO(devflags.noinit)) {
-			if (x7AF4 & 8) {
-				hw->MXoptionReg |= 0x40;
-				pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
-			}
-			mga_setr(M_EXTVGA_INDEX, 0x06, 0x50);
-		}
-	}
-	DAC1064_setmclk(PMINFO hw, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
-	if (ACCESS_FBINFO(devflags.noinit))
-		return;
-	MGAG100_setPixClock(PMINFO 4, 25175);
-	MGAG100_setPixClock(PMINFO 5, 28322);
-	if (x7AF4 & 0x10) {
-		b = inDAC1064(PMINFO M1064_XGENIODATA) & ~1;
-		outDAC1064(PMINFO M1064_XGENIODATA, b);
-		b = inDAC1064(PMINFO M1064_XGENIOCTRL) | 1;
-		outDAC1064(PMINFO M1064_XGENIOCTRL, b);
-	}
-}
-#endif
-
-static void vgaHWrestore(CPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw) {
-	int i;
-
-	DBG("vgaHWrestore")
-	
-	dprintk(KERN_INFO "MiscOutReg: %02X\n", hw->MiscOutReg);
-	dprintk(KERN_INFO "SEQ regs:   ");
-	for (i = 0; i < 5; i++)
-		dprintk("%02X:", hw->SEQ[i]);
-	dprintk("\n");
-	dprintk(KERN_INFO "GDC regs:   ");
-	for (i = 0; i < 9; i++)
-		dprintk("%02X:", hw->GCTL[i]);
-	dprintk("\n");
-	dprintk(KERN_INFO "CRTC regs: ");
-	for (i = 0; i < 25; i++)
-		dprintk("%02X:", hw->CRTC[i]);
-	dprintk("\n");
-	dprintk(KERN_INFO "ATTR regs: ");
-	for (i = 0; i < 21; i++)
-		dprintk("%02X:", hw->ATTR[i]);
-	dprintk("\n");
-
-	mga_inb(M_ATTR_RESET);
-	mga_outb(M_ATTR_INDEX, 0);
-	mga_outb(M_MISC_REG, hw->MiscOutReg);
-	for (i = 1; i < 5; i++)
-		mga_setr(M_SEQ_INDEX, i, hw->SEQ[i]);
-	mga_setr(M_CRTC_INDEX, 17, hw->CRTC[17] & 0x7F);
-	for (i = 0; i < 25; i++)
-		mga_setr(M_CRTC_INDEX, i, hw->CRTC[i]);
-	for (i = 0; i < 9; i++)
-		mga_setr(M_GRAPHICS_INDEX, i, hw->GCTL[i]);
-	for (i = 0; i < 21; i++) {
-		mga_inb(M_ATTR_RESET);
-		mga_outb(M_ATTR_INDEX, i);
-		mga_outb(M_ATTR_INDEX, hw->ATTR[i]);
-	}
-	mga_outb(M_PALETTE_MASK, 0xFF);
-	mga_outb(M_DAC_REG, 0x00);
-	for (i = 0; i < 768; i++)
-		mga_outb(M_DAC_VAL, hw->DACpal[i]);
-	mga_inb(M_ATTR_RESET);
-	mga_outb(M_ATTR_INDEX, 0x20);
-}
-
-static int matrox_setcolreg(unsigned regno, unsigned red, unsigned green,
-			    unsigned blue, unsigned transp,
-			    struct fb_info *fb_info)
-{
-	struct display* p;
-#ifdef CONFIG_FB_MATROX_MULTIHEAD
-	struct matrox_fb_info* minfo = (struct matrox_fb_info*)fb_info;
-#endif
-
-	DBG("matrox_setcolreg")
-	
-	/*
-	 *  Set a single color register. The values supplied are
-	 *  already rounded down to the hardware's capabilities
-	 *  (according to the entries in the `var' structure). Return
-	 *  != 0 for invalid regno.
-	 */
-	
-	if (regno >= ACCESS_FBINFO(curr.cmap_len))
-		return 1;
-	
-	ACCESS_FBINFO(palette[regno].red)   = red;
-	ACCESS_FBINFO(palette[regno].green) = green;
-	ACCESS_FBINFO(palette[regno].blue)  = blue;
-	ACCESS_FBINFO(palette[regno].transp) = transp;
-
-	p = ACCESS_FBINFO(currcon_display);
-	if (p->var.grayscale) {
-		/* gray = 0.30*R + 0.59*G + 0.11*B */
-		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
-	}
-
-	red = CNVT_TOHW(red, p->var.red.length);
-	green = CNVT_TOHW(green, p->var.green.length);
-	blue = CNVT_TOHW(blue, p->var.blue.length);
-	transp = CNVT_TOHW(transp, p->var.transp.length);
-
-	switch (p->var.bits_per_pixel) {
-#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB4) || defined(FBCON_HAS_VGATEXT)
-#ifdef FBCON_HAS_VGATEXT
-	case 0:
-#endif
-#ifdef FBCON_HAS_CFB4
-	case 4:
-#endif
-#ifdef FBCON_HAS_CFB8
-	case 8:
-#endif
-		mga_outb(M_DAC_REG, regno);
-		mga_outb(M_DAC_VAL, red);
-		mga_outb(M_DAC_VAL, green);
-		mga_outb(M_DAC_VAL, blue);
-		break;
-#endif
-#ifdef FBCON_HAS_CFB16	
-	case 16:
-		ACCESS_FBINFO(cmap.cfb16[regno]) =
-			(red << p->var.red.offset)     | 
-			(green << p->var.green.offset) | 
-			(blue << p->var.blue.offset)   |
-			(transp << p->var.transp.offset); /* for 1:5:5:5 */
-		break;
-#endif
-#ifdef FBCON_HAS_CFB24
-	case 24:
-		ACCESS_FBINFO(cmap.cfb24[regno]) =
-			(red   << p->var.red.offset)   |
-			(green << p->var.green.offset) |
-			(blue  << p->var.blue.offset);
-		break;
-#endif
-#ifdef FBCON_HAS_CFB32
-	case 32:
-		ACCESS_FBINFO(cmap.cfb32[regno]) =
-			(red   << p->var.red.offset)   |
-			(green << p->var.green.offset) |
-			(blue  << p->var.blue.offset)  |
-			(transp << p->var.transp.offset);	/* 8:8:8:8 */
-		break;
-#endif
-	}
-	return 0;
-}
-
-static void do_install_cmap(WPMINFO struct display* dsp)
-{
-	DBG("do_install_cmap")
-
-	if (dsp->cmap.len)
-		fb_set_cmap(&dsp->cmap, 1, matrox_setcolreg, &ACCESS_FBINFO(fbcon));
-	else
-		fb_set_cmap(fb_default_cmap(ACCESS_FBINFO(curr.cmap_len)),
-			    1, matrox_setcolreg, &ACCESS_FBINFO(fbcon));
-}
-
-#ifdef CONFIG_FB_MATROX_MYSTIQUE
-static void MGA1064_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) {
-	int i;
-
-	DBG("MGA1064_restore")
-
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
-	mga_outb(M_IEN, 0x00);
-	mga_outb(M_CACHEFLUSH, 0x00);
-
-	DAC1064_restore_1(PMINFO hw, oldhw);
-	vgaHWrestore(PMINFO hw, oldhw);
-	for (i = 0; i < 6; i++)
-		mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
-	DAC1064_restore_2(PMINFO hw, oldhw, p);
-}
-#endif
-
-#ifdef CONFIG_FB_MATROX_G100
-static void MGAG100_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) {
-	int i;
-
-	DBG("MGAG100_restore")
-
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
-
-	DAC1064_restore_1(PMINFO hw, oldhw);
-	vgaHWrestore(PMINFO hw, oldhw);
-#ifdef CONFIG_FB_MATROX_32MB
-	if (ACCESS_FBINFO(devflags.support32MB))
-		mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
-#endif
-	for (i = 0; i < 6; i++)
-		mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
-	DAC1064_restore_2(PMINFO hw, oldhw, p);
-}
-#endif
-
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-static void Ti3026_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) {
-	int i;
-
-	DBG("Ti3026_restore")
-
-	dprintk(KERN_INFO "EXTVGA regs: ");
-	for (i = 0; i < 6; i++)
-		dprintk("%02X:", hw->CRTCEXT[i]);
-	dprintk("\n");
-
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
-
-	vgaHWrestore(PMINFO hw, oldhw);
-
-	for (i = 0; i < 6; i++)
-		mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
-
-	for (i = 0; i < 21; i++) {
-		outTi3026(PMINFO DACseq[i], hw->DACreg[i]);
-	}
-	if (oldhw) {
-		outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
-		oldhw->DACclk[0] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
-		oldhw->DACclk[3] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
-		outTi3026(PMINFO TVP3026_XPLLADDR, 0x15);
-		oldhw->DACclk[1] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
-		oldhw->DACclk[4] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
-		outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
-		oldhw->DACclk[2] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
-		oldhw->DACclk[5] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
-	}
-	if (!oldhw || memcmp(hw->DACclk, oldhw->DACclk, 6)) {
-		/* agrhh... setting up PLL is very slow on Millenium... */
-		/* Mystique PLL is locked in few ms, but Millenium PLL lock takes about 0.15 s... */
-		/* Maybe even we should call schedule() ? */
-
-		outTi3026(PMINFO TVP3026_XCLKCTRL, hw->DACreg[POS3026_XCLKCTRL]);
-		outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
-		outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0);
-		outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0);
-
-		outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
-		for (i = 0; i < 3; i++)
-			outTi3026(PMINFO TVP3026_XPIXPLLDATA, hw->DACclk[i]);
-		/* wait for PLL only if PLL clock requested (always for PowerMode, never for VGA) */
-		if (hw->MiscOutReg & 0x08) {
-			int tmout;
-			outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F);
-			for (tmout = 500000; tmout; --tmout) {
-				if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40) 
-					break;
-				udelay(10);
-			}
-
-			if (!tmout)
-				printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
-			else
-				dprintk(KERN_INFO "PixelPLL: %d\n", 500000-tmout);
-		}
-		outTi3026(PMINFO TVP3026_XMEMPLLCTRL, hw->DACreg[POS3026_XMEMPLLCTRL]);
-		outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
-		for (i = 3; i < 6; i++)
-			outTi3026(PMINFO TVP3026_XLOOPPLLDATA, hw->DACclk[i]);
-		if ((hw->MiscOutReg & 0x08) && ((hw->DACclk[5] & 0x80) == 0x80)) {
-			int tmout;
-
-			outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F);
-			for (tmout = 500000; tmout; --tmout) {
-				if (inTi3026(PMINFO TVP3026_XLOOPPLLDATA) & 0x40) 
-					break;
-				udelay(10);
-			}
-			if (!tmout)
-				printk(KERN_ERR "matroxfb: Loop PLL not locked after 5 secs\n");
-			else
-				dprintk(KERN_INFO "LoopPLL: %d\n", 500000-tmout);
-		}
-	}
-	if (p && p->conp) {
-		if (p->type == FB_TYPE_TEXT) {
-			matrox_text_createcursor(PMINFO p);
-			matrox_text_loadfont(PMINFO p);
-			i = 0;
-		} else {
-			matroxfb_ti3026_createcursor(PMINFO p);
-			i = matroxfb_fastfont_tryset(PMINFO p);
-		}
-	} else
-		i = 0;
-	if (i) {
-		ACCESS_FBINFO(curr.putc) = matrox_cfbX_fastputc;
-		ACCESS_FBINFO(curr.putcs) = matrox_cfbX_fastputcs;
-	} else {
-		ACCESS_FBINFO(curr.putc) = matrox_cfbX_putc;
-		ACCESS_FBINFO(curr.putcs) = matrox_cfbX_putcs;
-	}
-
-	dprintk(KERN_DEBUG "3026DACregs ");
-	for (i = 0; i < 21; i++) {
-		dprintk("R%02X=%02X ", DACseq[i], hw->DACreg[i]);
-		if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
-	}
-	dprintk("\n" KERN_DEBUG "DACclk ");
-	for (i = 0; i < 6; i++)
-		dprintk("C%02X=%02X ", i, hw->DACclk[i]);
-	dprintk("\n");
-}
-#endif
-
-static int matroxfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *info)
-{
-	struct display* p;
-	DBG("matroxfb_get_fix")
-
-#define minfo ((struct matrox_fb_info*)info)
-
-	if (con >= 0)
-		p = fb_display + con;
-	else
-		p = ACCESS_FBINFO(fbcon.disp);
-
-	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-	strcpy(fix->id,"MATROX");
-
-	fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes);
-	fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes);
-	fix->type = p->type;
-	fix->type_aux = p->type_aux;
-	fix->visual = p->visual;
-	fix->xpanstep = 8; /* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */
-	fix->ypanstep = 1;
-	fix->ywrapstep = 0;
-	fix->line_length = p->line_length;
-	fix->mmio_start = ACCESS_FBINFO(mmio.base);
-	fix->mmio_len = ACCESS_FBINFO(mmio.len);
-	fix->accel = ACCESS_FBINFO(devflags.accelerator);
-	return 0;
-#undef minfo
-}
-
-static int matroxfb_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
-{
-#define minfo ((struct matrox_fb_info*)info)
-	DBG("matroxfb_get_var")
-	
-	if(con < 0)
-		*var=ACCESS_FBINFO(fbcon.disp)->var;
-	else
-		*var=fb_display[con].var;
-	return 0;
-#undef minfo
-}
-
-static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
-{
-#define minfo ((struct matrox_fb_info*)info)
-	int err;
-	int visual;
-	int cmap_len;
-	unsigned int ydstorg;
-	struct display* display;
-	int chgvar;
-
-	DBG("matroxfb_set_var")
-
-	if (con >= 0)
-		display = fb_display + con;
-	else
-		display = ACCESS_FBINFO(fbcon.disp);
-	if ((err = matroxfb_decode_var(PMINFO display, var, &visual, &cmap_len, &ydstorg)) != 0) 
-		return err;
-	switch (var->activate & FB_ACTIVATE_MASK) {
-		case FB_ACTIVATE_TEST:	return 0;
-		case FB_ACTIVATE_NXTOPEN:	/* ?? */
-		case FB_ACTIVATE_NOW:   break;	/* continue */
-		default:		return -EINVAL; /* unknown */
-	}
-	if (con >= 0) {
-		chgvar = ((display->var.xres != var->xres) || 
-		    (display->var.yres != var->yres) || 
-                    (display->var.xres_virtual != var->xres_virtual) ||
-		    (display->var.yres_virtual != var->yres_virtual) || 
-		    (display->var.bits_per_pixel != var->bits_per_pixel) ||
-		    memcmp(&display->var.red, &var->red, sizeof(var->red)) || 
-		    memcmp(&display->var.green, &var->green, sizeof(var->green)) ||
-		    memcmp(&display->var.blue, &var->blue, sizeof(var->blue)));
-	} else {
-		chgvar = 0;
-	}
-	display->var = *var;
-	/* cmap */
-	display->screen_base = vaddr_va(ACCESS_FBINFO(video.vbase)) + ydstorg;
-	display->visual = visual;
-	display->ypanstep = 1;
-	display->ywrapstep = 0;
-	if (var->bits_per_pixel) {
-		display->type = FB_TYPE_PACKED_PIXELS;
-		display->type_aux = 0;
-		display->next_line = display->line_length = (var->xres_virtual * var->bits_per_pixel) >> 3;
-	} else {
-		display->type = FB_TYPE_TEXT;
-		display->type_aux = ACCESS_FBINFO(devflags.text_type_aux);
-		display->next_line = display->line_length = (var->xres_virtual / (fontwidth(display)?fontwidth(display):8)) * ACCESS_FBINFO(devflags.textstep);
-	}
-	display->can_soft_blank = 1;
-	display->inverse = ACCESS_FBINFO(devflags.inverse);
-	/* conp, fb_info, vrows, cursor_x, cursor_y, fgcol, bgcol */
-	/* next_plane, fontdata, _font*, userfont */
-	initMatrox(PMINFO display);	/* dispsw */
-	/* dispsw, scrollmode, yscroll */
-	/* fgshift, bgshift, charmask */
-	if (chgvar && info && info->changevar)
-		info->changevar(con);
-	if (con == ACCESS_FBINFO(currcon)) {
-		unsigned int pos;
-
-		ACCESS_FBINFO(curr.cmap_len) = cmap_len;
-		if (display->type == FB_TYPE_TEXT) {
-			/* textmode must be in first megabyte, so no ydstorg allowed */
-			ACCESS_FBINFO(curr.ydstorg.bytes) = 0;
-			ACCESS_FBINFO(curr.ydstorg.chunks) = 0;
-			ACCESS_FBINFO(curr.ydstorg.pixels) = 0;
-		} else {
-			ydstorg += ACCESS_FBINFO(devflags.ydstorg);
-			ACCESS_FBINFO(curr.ydstorg.bytes) = ydstorg;
-			ACCESS_FBINFO(curr.ydstorg.chunks) = ydstorg >> (isInterleave(MINFO)?3:2);
-			if (var->bits_per_pixel == 4)
-				ACCESS_FBINFO(curr.ydstorg.pixels) = ydstorg;
-			else
-				ACCESS_FBINFO(curr.ydstorg.pixels) = (ydstorg * 8) / var->bits_per_pixel;
-		}
-		ACCESS_FBINFO(curr.final_bppShift) = matroxfb_get_final_bppShift(PMINFO var->bits_per_pixel);
-		if (visual == MX_VISUAL_PSEUDOCOLOR) {
-			int i;
-
-			for (i = 0; i < 16; i++) {
-				int j;
-
-				j = color_table[i];
-				ACCESS_FBINFO(palette[i].red)   = default_red[j];
-				ACCESS_FBINFO(palette[i].green) = default_grn[j];
-				ACCESS_FBINFO(palette[i].blue)  = default_blu[j];
-			}
-		}
-
-		{	struct my_timming mt;
-			struct matrox_hw_state* hw;
-			struct matrox_hw_state* ohw;
-
-			var2my(var, &mt);
-			hw = ACCESS_FBINFO(newhw);
-			ohw = ACCESS_FBINFO(currenthw);
-
-			/* MXoptionReg is not set from scratch */
-			hw->MXoptionReg = ohw->MXoptionReg;
-			/* DACclk[3]..[5] are not initialized with DAC1064 */
-			memcpy(hw->DACclk, ohw->DACclk, sizeof(hw->DACclk));
-			/* others are initialized by init() */
-
-			del_timer(&ACCESS_FBINFO(cursor.timer));
-			ACCESS_FBINFO(cursor.state) = CM_ERASE;
-
-			ACCESS_FBINFO(hw_switch->init(PMINFO hw, &mt, display));
-			if (display->type == FB_TYPE_TEXT) {
-				if (fontheight(display))
-					pos = var->yoffset / fontheight(display) * display->next_line / ACCESS_FBINFO(devflags.textstep) + var->xoffset / (fontwidth(display)?fontwidth(display):8);
-				else
-					pos = 0;
-			} else {
-				pos = (var->yoffset * var->xres_virtual + var->xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32;
-				pos += ACCESS_FBINFO(curr.ydstorg.chunks);
-			}
-
-			hw->CRTC[0x0D] = pos & 0xFF;
-			hw->CRTC[0x0C] = (pos & 0xFF00) >> 8;
-			hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
-			hw->CRTCEXT[8] = pos >> 21;
-			ACCESS_FBINFO(hw_switch->restore(PMINFO hw, ohw, display));
-			ACCESS_FBINFO(cursor.redraw) = 1;
-			ACCESS_FBINFO(currenthw) = hw;
-			ACCESS_FBINFO(newhw) = ohw;
-			matrox_cfbX_init(PMINFO display);
-			do_install_cmap(PMINFO display);
-#if defined(CONFIG_FB_OF) && defined(CONFIG_FB_COMPAT_XPMAC)
-			if (console_fb_info == &ACCESS_FBINFO(fbcon)) {
-				int vmode, cmode;
-
-				display_info.width = var->xres;
-				display_info.height = var->yres;
-				display_info.depth = var->bits_per_pixel;
-				display_info.pitch = (var->xres_virtual)*(var->bits_per_pixel)/8;
-				if (mac_var_to_vmode(var, &vmode, &cmode))
-					display_info.mode = 0;
-				else
-					display_info.mode = vmode;
-				strcpy(display_info.name, ACCESS_FBINFO(matrox_name));
-				display_info.fb_address = ACCESS_FBINFO(video.base);
-				display_info.cmap_adr_address = 0;
-				display_info.cmap_data_address = 0;
-				display_info.disp_reg_address = ACCESS_FBINFO(mmio.base);
-			}
-#endif /* CONFIG_FB_OF && CONFIG_FB_COMPAT_XPMAC */
-		}
-	}
-	return 0;
-#undef minfo
-}
-
-static int matrox_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-			    unsigned *blue, unsigned *transp,
-			    struct fb_info *info)
-{
-
-	DBG("matrox_getcolreg")
-
-#define minfo ((struct matrox_fb_info*)info)
-	/*
-	 *  Read a single color register and split it into colors/transparent.
-	 *  Return != 0 for invalid regno.
-	 */
-
-	if (regno >= ACCESS_FBINFO(curr.cmap_len))
-		return 1;
-
-	*red   = ACCESS_FBINFO(palette[regno].red);
-	*green = ACCESS_FBINFO(palette[regno].green);
-	*blue  = ACCESS_FBINFO(palette[regno].blue);
-	*transp = ACCESS_FBINFO(palette[regno].transp);
-	return 0;
-#undef minfo
-}
-
-static int matroxfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     struct fb_info *info)
-{
-#define minfo ((struct matrox_fb_info*)info)
-	struct display* dsp = (con < 0) ? ACCESS_FBINFO(fbcon.disp) 
-					: fb_display + con;
-
-	DBG("matroxfb_get_cmap")
-
-	if (con == ACCESS_FBINFO(currcon)) /* current console? */
-		return fb_get_cmap(cmap, kspc, matrox_getcolreg, info);
-	else if (dsp->cmap.len) /* non default colormap? */
-		fb_copy_cmap(&dsp->cmap, cmap, kspc ? 0 : 2);
-	else
-		fb_copy_cmap(fb_default_cmap(matroxfb_get_cmap_len(&dsp->var)),
-			     cmap, kspc ? 0 : 2);
-	return 0;
-#undef minfo
-}
-
-static int matroxfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     struct fb_info *info)
-{
-	unsigned int cmap_len;
-	struct display* dsp = (con < 0) ? info->disp : (fb_display + con);
-#define minfo ((struct matrox_fb_info*)info)
-
-	DBG("matroxfb_set_cmap")
-
-	cmap_len = matroxfb_get_cmap_len(&dsp->var);
-	if (dsp->cmap.len != cmap_len) {
-		int err;
-
-		err = fb_alloc_cmap(&dsp->cmap, cmap_len, 0);
-		if (err)
-			return err;
-	}
-	if (con == ACCESS_FBINFO(currcon)) {			/* current console? */
-		return fb_set_cmap(cmap, kspc, matrox_setcolreg, info);
-	} else
-		fb_copy_cmap(cmap, &dsp->cmap, kspc ? 0 : 1);
-	return 0;
-#undef minfo	
-}
-
-static int matroxfb_ioctl(struct inode *inode, struct file *file, 
-			  unsigned int cmd, unsigned long arg, int con,
-			  struct fb_info *info)
-{
-
-	DBG("matroxfb_ioctl")
-
-	return -EINVAL;
-}
-
-static struct fb_ops matroxfb_ops = {
-	matroxfb_open,
-	matroxfb_release,
-	matroxfb_get_fix,
-	matroxfb_get_var,
-	matroxfb_set_var,
-	matroxfb_get_cmap,
-	matroxfb_set_cmap,
-	matroxfb_pan_display,
-	matroxfb_ioctl,
-	NULL			/* mmap */
-};
-
-static int matroxfb_switch(int con, struct fb_info *info)
-{
-#define minfo ((struct matrox_fb_info*)info)
-	struct fb_cmap* cmap;
-
-	DBG("matroxfb_switch");
-
-	if (ACCESS_FBINFO(currcon) >= 0) {
-		/* Do we have to save the colormap? */
-		cmap = &(ACCESS_FBINFO(currcon_display)->cmap);
-		dprintk(KERN_DEBUG "switch1: con = %d, cmap.len = %d\n", ACCESS_FBINFO(currcon), cmap->len);
-
-		if (cmap->len) {
-			dprintk(KERN_DEBUG "switch1a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp);
-			fb_get_cmap(cmap, 1, matrox_getcolreg, info);
-#ifdef DEBUG
-			if (cmap->red) {
-				dprintk(KERN_DEBUG "switch1r: %X\n", cmap->red[0]);
-			}
-#endif
-		}
-	}
-	ACCESS_FBINFO(currcon) = con;
-	ACCESS_FBINFO(currcon_display) = fb_display + con;
-	fb_display[con].var.activate = FB_ACTIVATE_NOW;
-#ifdef DEBUG
-	cmap = &fb_display[con].cmap;
-	dprintk(KERN_DEBUG "switch2: con = %d, cmap.len = %d\n", con, cmap->len);
-	dprintk(KERN_DEBUG "switch2a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp);
-	if (fb_display[con].cmap.red) {
-		dprintk(KERN_DEBUG "switch2r: %X\n", cmap->red[0]);
-	}
-#endif
-	matroxfb_set_var(&fb_display[con].var, con, info);
-#ifdef DEBUG
-	dprintk(KERN_DEBUG "switch3: con = %d, cmap.len = %d\n", con, cmap->len);
-	dprintk(KERN_DEBUG "switch3a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp);
-	if (fb_display[con].cmap.red) {
-		dprintk(KERN_DEBUG "switch3r: %X\n", cmap->red[0]);
-	}
-#endif
-	return 0;
-#undef minfo
-}
-
-/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
-
-static void matroxfb_blank(int blank, struct fb_info *info)
-{
-#define minfo ((struct matrox_fb_info*)info)
-	int seq;
-	int crtc;
-
-	DBG("matroxfb_blank")
-
-	switch (blank) {
-		case 1:  seq = 0x20; crtc = 0x00; break; /* works ??? */
-		case 2:  seq = 0x20; crtc = 0x10; break;
-		case 3:  seq = 0x20; crtc = 0x20; break;
-		case 4:  seq = 0x20; crtc = 0x30; break;
-		default: seq = 0x00; crtc = 0x00; break;
-	}
-
-	mga_outb(M_SEQ_INDEX, 1);
-	mga_outb(M_SEQ_DATA, (mga_inb(M_SEQ_DATA) & ~0x20) | seq);
-	mga_outb(M_EXTVGA_INDEX, 1);
-	mga_outb(M_EXTVGA_DATA, (mga_inb(M_EXTVGA_DATA) & ~0x30) | crtc);
-
-#undef minfo
-}
-
-#define RSResolution(X)	((X) & 0x0F)
-#define RS640x400	1
-#define RS640x480	2
-#define RS800x600	3
-#define RS1024x768	4
-#define RS1280x1024	5
-#define RS1600x1200	6
-#define RS768x576	7
-#define RS960x720	8
-#define RS1152x864	9
-#define RS1408x1056	10
-#define RS640x350	11
-#define RS1056x344	12	/* 132 x 43 text */
-#define RS1056x400	13	/* 132 x 50 text */
-#define RS1056x480	14	/* 132 x 60 text */
-#define RSNoxNo		15
-/* 10-FF */
-static struct { int xres, yres, left, right, upper, lower, hslen, vslen, vfreq; } timmings[] __initdata = {
-	{  640,  400,  48, 16, 39,  8,  96, 2, 70 },
-	{  640,  480,  48, 16, 33, 10,  96, 2, 60 },
-	{  800,  600, 144, 24, 28,  8, 112, 6, 60 },
-	{ 1024,  768, 160, 32, 30,  4, 128, 4, 60 },
-	{ 1280, 1024, 224, 32, 32,  4, 136, 4, 60 },
-	{ 1600, 1200, 272, 48, 32,  5, 152, 5, 60 },
-	{  768,  576, 144, 16, 28,  6, 112, 4, 60 },
-	{  960,  720, 144, 24, 28,  8, 112, 4, 60 },
-	{ 1152,  864, 192, 32, 30,  4, 128, 4, 60 },
-	{ 1408, 1056, 256, 40, 32,  5, 144, 5, 60 },
-	{  640,  350,  48, 16, 39,  8,  96, 2, 70 },
-	{ 1056,  344,  96, 24, 59, 44, 160, 2, 70 },
-	{ 1056,  400,  96, 24, 39,  8, 160, 2, 70 },
-	{ 1056,  480,  96, 24, 36, 12, 160, 3, 60 },
-	{    0,    0,  ~0, ~0, ~0, ~0,   0, 0,  0 }
-};
-
-#define RSDepth(X)	(((X) >> 8) & 0x0F)
-#define RS8bpp		0x1
-#define RS15bpp		0x2
-#define RS16bpp		0x3
-#define RS32bpp		0x4
-#define RS4bpp		0x5
-#define RS24bpp		0x6
-#define RSText		0x7
-#define RSText8		0x8
-/* 9-F */
-static struct { struct fb_bitfield red, green, blue, transp; int bits_per_pixel; } colors[] __initdata = {
-	{ {  0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, {  0, 0, 0},  8 },
-	{ { 10, 5, 0}, { 5, 5, 0}, { 0, 5, 0}, { 15, 1, 0}, 16 },
-	{ { 11, 5, 0}, { 6, 5, 0}, { 0, 5, 0}, {  0, 0, 0}, 16 },
-	{ { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 24, 8, 0}, 32 },
-	{ {  0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, {  0, 0, 0},  4 },
-	{ { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, {  0, 0, 0}, 24 },
-	{ {  0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, {  0, 0, 0},  0 },	/* textmode with (default) VGA8x16 */
-	{ {  0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, {  0, 0, 0},  0 },	/* textmode hardwired to VGA8x8 */
-};
-
-#define RSCreate(X,Y)	((X) | ((Y) << 8))
-static struct { unsigned int vesa; unsigned int info; } *RSptr, vesamap[] __initdata = {
-/* default must be first */
-#ifdef FBCON_HAS_CFB8
-	{    ~0, RSCreate(RSNoxNo,     RS8bpp ) },
-	{ 0x101, RSCreate(RS640x480,   RS8bpp ) },
-	{ 0x100, RSCreate(RS640x400,   RS8bpp ) },
-	{ 0x180, RSCreate(RS768x576,   RS8bpp ) },
-	{ 0x103, RSCreate(RS800x600,   RS8bpp ) },
-	{ 0x188, RSCreate(RS960x720,   RS8bpp ) },
-	{ 0x105, RSCreate(RS1024x768,  RS8bpp ) },
-	{ 0x190, RSCreate(RS1152x864,  RS8bpp ) },
-	{ 0x107, RSCreate(RS1280x1024, RS8bpp ) },
-	{ 0x198, RSCreate(RS1408x1056, RS8bpp ) },
-	{ 0x11C, RSCreate(RS1600x1200, RS8bpp ) },
-#endif
-#ifdef FBCON_HAS_CFB16
-	{    ~0, RSCreate(RSNoxNo,     RS15bpp) },
-	{ 0x110, RSCreate(RS640x480,   RS15bpp) },
-	{ 0x181, RSCreate(RS768x576,   RS15bpp) },
-	{ 0x113, RSCreate(RS800x600,   RS15bpp) },
-	{ 0x189, RSCreate(RS960x720,   RS15bpp) },
-	{ 0x116, RSCreate(RS1024x768,  RS15bpp) },
-	{ 0x191, RSCreate(RS1152x864,  RS15bpp) },
-	{ 0x119, RSCreate(RS1280x1024, RS15bpp) },
-	{ 0x199, RSCreate(RS1408x1056, RS15bpp) },
-	{ 0x11D, RSCreate(RS1600x1200, RS15bpp) },
-	{ 0x111, RSCreate(RS640x480,   RS16bpp) },
-	{ 0x182, RSCreate(RS768x576,   RS16bpp) },
-	{ 0x114, RSCreate(RS800x600,   RS16bpp) },
-	{ 0x18A, RSCreate(RS960x720,   RS16bpp) },
-	{ 0x117, RSCreate(RS1024x768,  RS16bpp) },
-	{ 0x192, RSCreate(RS1152x864,  RS16bpp) },
-	{ 0x11A, RSCreate(RS1280x1024, RS16bpp) },
-	{ 0x19A, RSCreate(RS1408x1056, RS16bpp) },
-	{ 0x11E, RSCreate(RS1600x1200, RS16bpp) },
-#endif
-#ifdef FBCON_HAS_CFB24
-	{    ~0, RSCreate(RSNoxNo,     RS24bpp) },
-	{ 0x1B2, RSCreate(RS640x480,   RS24bpp) },
-	{ 0x184, RSCreate(RS768x576,   RS24bpp) },
-	{ 0x1B5, RSCreate(RS800x600,   RS24bpp) },
-	{ 0x18C, RSCreate(RS960x720,   RS24bpp) },
-	{ 0x1B8, RSCreate(RS1024x768,  RS24bpp) },
-	{ 0x194, RSCreate(RS1152x864,  RS24bpp) },
-	{ 0x1BB, RSCreate(RS1280x1024, RS24bpp) },
-	{ 0x19C, RSCreate(RS1408x1056, RS24bpp) },
-	{ 0x1BF, RSCreate(RS1600x1200, RS24bpp) },
-#endif
-#ifdef FBCON_HAS_CFB32
-	{    ~0, RSCreate(RSNoxNo,     RS32bpp) },
-	{ 0x112, RSCreate(RS640x480,   RS32bpp) },
-	{ 0x183, RSCreate(RS768x576,   RS32bpp) },
-	{ 0x115, RSCreate(RS800x600,   RS32bpp) },
-	{ 0x18B, RSCreate(RS960x720,   RS32bpp) },
-	{ 0x118, RSCreate(RS1024x768,  RS32bpp) },
-	{ 0x193, RSCreate(RS1152x864,  RS32bpp) },
-	{ 0x11B, RSCreate(RS1280x1024, RS32bpp) },
-	{ 0x19B, RSCreate(RS1408x1056, RS32bpp) },
-	{ 0x11F, RSCreate(RS1600x1200, RS32bpp) },
-#endif
-#ifdef FBCON_HAS_VGATEXT
-	{    ~0, RSCreate(RSNoxNo,     RSText)  },
-	{ 0x002, RSCreate(RS640x400,   RSText)  },	/* 80x25 */
-	{ 0x003, RSCreate(RS640x400,   RSText)  },	/* 80x25 */
-	{ 0x007, RSCreate(RS640x400,   RSText)  },	/* 80x25 */
-	{ 0x1C0, RSCreate(RS640x400,   RSText8) },	/* 80x50 */
-	{ 0x108, RSCreate(RS640x480,   RSText8) },	/* 80x60 */
-	{ 0x109, RSCreate(RS1056x400,  RSText)  },	/* 132x25 */
-	{ 0x10A, RSCreate(RS1056x344,  RSText8) },	/* 132x43 */
-	{ 0x10B, RSCreate(RS1056x400,  RSText8) },	/* 132x50 */
-	{ 0x10C, RSCreate(RS1056x480,  RSText8) },	/* 132x60 */
-#endif
-#ifdef FBCON_HAS_CFB4
-	{    ~0, RSCreate(RSNoxNo,     RS4bpp ) },
-	{ 0x010, RSCreate(RS640x350,   RS4bpp ) },
-	{ 0x012, RSCreate(RS640x480,   RS4bpp ) },
-	{ 0x102, RSCreate(RS800x600,   RS4bpp ) },
-	{ 0x104, RSCreate(RS1024x768,  RS4bpp ) },
-	{ 0x106, RSCreate(RS1280x1024, RS4bpp ) },
-#endif
-	{     0, 0                                 }};
-
-/* initialized by setup, see explanation at end of file (search for MODULE_PARM_DESC) */
-static unsigned int mem = 0;		/* "matrox:mem:xxxxxM" */
-static int option_precise_width = 1;	/* cannot be changed, option_precise_width==0 must imply noaccel */
-static int inv24 = 0;			/* "matrox:inv24" */
-static int cross4MB = -1;		/* "matrox:cross4MB" */
-static int disabled = 0;		/* "matrox:disabled" */
-static int noaccel = 0;			/* "matrox:noaccel" */
-static int nopan = 0;			/* "matrox:nopan" */
-static int no_pci_retry = 0;		/* "matrox:nopciretry" */
-static int novga = 0;			/* "matrox:novga" */
-static int nobios = 0;			/* "matrox:nobios" */
-static int noinit = 1;			/* "matrox:init" */
-static int inverse = 0;			/* "matrox:inverse" */
-static int hwcursor = 1;		/* "matrox:nohwcursor" */
-static int blink = 1;			/* "matrox:noblink" */
-static int sgram = 0;			/* "matrox:sgram" */
-#ifdef CONFIG_MTRR
-static int mtrr = 1;			/* "matrox:nomtrr" */
-#endif
-static int grayscale = 0;		/* "matrox:grayscale" */
-static unsigned int fastfont = 0;	/* "matrox:fastfont:xxxxx" */
-static int dev = -1;			/* "matrox:dev:xxxxx" */
-static unsigned int vesa = ~0;		/* "matrox:vesa:xxxxx" */
-static int depth = -1;			/* "matrox:depth:xxxxx" */
-static unsigned int xres = 0;		/* "matrox:xres:xxxxx" */
-static unsigned int yres = 0;		/* "matrox:yres:xxxxx" */
-static unsigned int upper = ~0;		/* "matrox:upper:xxxxx" */
-static unsigned int lower = ~0;		/* "matrox:lower:xxxxx" */
-static unsigned int vslen = 0;		/* "matrox:vslen:xxxxx" */
-static unsigned int left = ~0;		/* "matrox:left:xxxxx" */
-static unsigned int right = ~0;		/* "matrox:right:xxxxx" */
-static unsigned int hslen = 0;		/* "matrox:hslen:xxxxx" */
-static unsigned int pixclock = 0;	/* "matrox:pixclock:xxxxx" */
-static int sync = -1;			/* "matrox:sync:xxxxx" */
-static unsigned int fv = 0;		/* "matrox:fv:xxxxx" */
-static unsigned int fh = 0;		/* "matrox:fh:xxxxxk" */
-static unsigned int maxclk = 0;		/* "matrox:maxclk:xxxxM" */
-static char fontname[64];		/* "matrox:font:xxxxx" */
-
-#ifndef MODULE
-static char videomode[64];		/* "matrox:mode:xxxxx" or "matrox:xxxxx" */
-#endif
-
-#ifndef MODULE
-int __init matroxfb_setup(char *options) {
-	char *this_opt;
-	
-	DBG("matroxfb_setup")
-	
-	fontname[0] = '\0';
-	
-	if (!options || !*options)
-		return 0;
-	
-	for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
-		if (!*this_opt) continue;
-		
-		dprintk("matroxfb_setup: option %s\n", this_opt);
-
-		if (!strncmp(this_opt, "dev:", 4))
-			dev = simple_strtoul(this_opt+4, NULL, 0);
-		else if (!strncmp(this_opt, "depth:", 6)) {
-			switch (simple_strtoul(this_opt+6, NULL, 0)) {
-				case 0: depth = RSText; break;
-				case 4: depth = RS4bpp; break;
-				case 8: depth = RS8bpp; break;
-				case 15:depth = RS15bpp; break;
-				case 16:depth = RS16bpp; break;
-				case 24:depth = RS24bpp; break;
-				case 32:depth = RS32bpp; break;
-				default:
-					printk(KERN_ERR "matroxfb: unsupported color depth\n");
-			}
-		} else if (!strncmp(this_opt, "xres:", 5))
-			xres = simple_strtoul(this_opt+5, NULL, 0);
-		else if (!strncmp(this_opt, "yres:", 5))
-			yres = simple_strtoul(this_opt+5, NULL, 0);
-		else if (!strncmp(this_opt, "vslen:", 6))
-			vslen = simple_strtoul(this_opt+6, NULL, 0);
-		else if (!strncmp(this_opt, "hslen:", 6))
-			hslen = simple_strtoul(this_opt+6, NULL, 0);
-		else if (!strncmp(this_opt, "left:", 5))
-			left = simple_strtoul(this_opt+5, NULL, 0);
-		else if (!strncmp(this_opt, "right:", 6))
-			right = simple_strtoul(this_opt+6, NULL, 0);
-		else if (!strncmp(this_opt, "upper:", 6))
-			upper = simple_strtoul(this_opt+6, NULL, 0);
-		else if (!strncmp(this_opt, "lower:", 6))
-			lower = simple_strtoul(this_opt+6, NULL, 0);
-		else if (!strncmp(this_opt, "pixclock:", 9))
-			pixclock = simple_strtoul(this_opt+9, NULL, 0);
-		else if (!strncmp(this_opt, "sync:", 5))
-			sync = simple_strtoul(this_opt+5, NULL, 0);
-		else if (!strncmp(this_opt, "vesa:", 5)) 
-			vesa = simple_strtoul(this_opt+5, NULL, 0);
-		else if (!strncmp(this_opt, "font:", 5))
-			strncpy(fontname, this_opt+5, sizeof(fontname)-1);
-		else if (!strncmp(this_opt, "maxclk:", 7))
-			maxclk = simple_strtoul(this_opt+7, NULL, 0);
-		else if (!strncmp(this_opt, "fh:", 3))
-			fh = simple_strtoul(this_opt+3, NULL, 0);
-		else if (!strncmp(this_opt, "fv:", 3)) 
-			fv = simple_strtoul(this_opt+3, NULL, 0);
-		else if (!strncmp(this_opt, "mem:", 4)) 
-			mem = simple_strtoul(this_opt+4, NULL, 0);
-		else if (!strncmp(this_opt, "mode:", 5))
-			strncpy(videomode, this_opt+5, sizeof(videomode)-1);
-#ifdef CONFIG_FB_OF
-		else if (!strncmp(this_opt, "vmode:", 6)) {
-			unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
-            		if (vmode > 0 && vmode <= VMODE_MAX)
-				default_vmode = vmode;
-		} else if (!strncmp(this_opt, "cmode:", 6)) {
-			unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
-			switch (cmode) {
-				case 0:
-				case 8:
-					default_cmode = CMODE_8;
-					break;
-				case 15:
-				case 16:
-					default_cmode = CMODE_16;
-					break;
-				case 24:
-				case 32:
-					default_cmode = CMODE_32;
-					break;
-			}
-		}
-#endif
-		else if (!strncmp(this_opt, "fastfont:", 9))
-			fastfont = simple_strtoul(this_opt+9, NULL, 0);
-		else if (!strcmp(this_opt, "nofastfont"))	/* fastfont:N and nofastfont (nofastfont = fastfont:0) */
-			fastfont = 0;
-		else if (!strcmp(this_opt, "disabled"))	/* nodisabled does not exist */
-			disabled = 1;
-		else if (!strcmp(this_opt, "enabled"))	/* noenabled does not exist */
-			disabled = 0;
-		else if (!strcmp(this_opt, "sgram"))	/* nosgram == sdram */
-			sgram = 1;
-		else if (!strcmp(this_opt, "sdram"))
-			sgram = 0;
-		else {
-			int value = 1;
-	
-			if (!strncmp(this_opt, "no", 2)) {
-				value = 0;
-				this_opt += 2;
-			}		
-			if (! strcmp(this_opt, "inverse"))
-				inverse = value;
-			else if (!strcmp(this_opt, "accel"))
-				noaccel = !value;
-			else if (!strcmp(this_opt, "pan"))
-				nopan = !value;
-			else if (!strcmp(this_opt, "pciretry"))
-				no_pci_retry = !value;
-			else if (!strcmp(this_opt, "vga"))
-				novga = !value;
-			else if (!strcmp(this_opt, "bios"))
-				nobios = !value;
-			else if (!strcmp(this_opt, "init"))
-				noinit = !value;
-#ifdef CONFIG_MTRR
-			else if (!strcmp(this_opt, "mtrr"))
-				mtrr = value;
-#endif
-			else if (!strcmp(this_opt, "inv24"))
-				inv24 = value;
-			else if (!strcmp(this_opt, "cross4MB"))
-				cross4MB = value;
-			else if (!strcmp(this_opt, "hwcursor"))
-				hwcursor = value;
-			else if (!strcmp(this_opt, "blink"))
-				blink = value;
-			else if (!strcmp(this_opt, "grayscale"))
-				grayscale = value;
-			else {
-				strncpy(videomode, this_opt, sizeof(videomode)-1);
-			}
-		}
-	}
-	return 0;
-}
-#endif /* !MODULE */
-
-static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int* realOffset, unsigned int *realSize){
-	vaddr_t vm;
-	unsigned int offs;
-	unsigned int offs2;
-	unsigned char store;
-	unsigned char bytes[32];
-	unsigned char* tmp;
-	unsigned long cbase;
-	unsigned long mbase;
-	unsigned int clen;
-	unsigned int mlen;
-
-	DBG("matroxfb_getmemory")
-
-	vm = ACCESS_FBINFO(video.vbase);
-	maxSize &= ~0x1FFFFF;	/* must be X*2MB (really it must be 2 or X*4MB) */
-	/* at least 2MB */
-	if (maxSize < 0x0200000) return 0;
-	if (maxSize > 0x2000000) maxSize = 0x2000000;
-
-	mga_outb(M_EXTVGA_INDEX, 0x03);
-	mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) | 0x80);
-
-	store = mga_readb(vm, 0x1234);
-	tmp = bytes;
-	for (offs = 0x100000; offs < maxSize; offs += 0x200000)
-		*tmp++ = mga_readb(vm, offs);			
-	for (offs = 0x100000; offs < maxSize; offs += 0x200000)
-		mga_writeb(vm, offs, 0x02);
-	if (ACCESS_FBINFO(features.accel.has_cacheflush))
-		mga_outb(M_CACHEFLUSH, 0x00);
-	else
-		mga_writeb(vm, 0x1234, 0x99);
-	cbase = mbase = 0;
-	clen = mlen = 0;
-	for (offs = 0x100000; offs < maxSize; offs += 0x200000) {
-		if (mga_readb(vm, offs) != 0x02) 
-			continue;
-		mga_writeb(vm, offs, mga_readb(vm, offs) - 0x02);
-		if (mga_readb(vm, offs)) 
-			continue;
-		if (offs - 0x100000 == cbase + clen) {
-			clen += 0x200000;
-		} else {
-			cbase = offs - 0x100000;
-			clen = 0x200000;
-		}
-		if ((clen > mlen)
-#ifndef MATROX_2MB_WITH_4MB_ADDON
-		    && (cbase == 0)
-#endif
-		   ) {
-			mbase = cbase;
-			mlen = clen;
-		}
-	}
-	tmp = bytes;
-	for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000)
-		mga_writeb(vm, offs2, *tmp++);
-	mga_writeb(vm, 0x1234, store);
-
-	mga_outb(M_EXTVGA_INDEX, 0x03);
-	mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) & ~0x80);
-
-	*realOffset = mbase;
-	*realSize = mlen;
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-	ACCESS_FBINFO(interleave) = !(!isMillenium(MINFO) || (mbase & 0x3FFFFF) || (mlen & 0x3FFFFF));
-#endif
-	return 1;
-}
-
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-static int __init Ti3026_preinit(WPMINFO struct matrox_hw_state* hw){
-	static const int vxres_mill2[] = { 512,        640, 768,  800,  832,  960, 
-					  1024, 1152, 1280,      1600, 1664, 1920, 
-					  2048, 0};
-	static const int vxres_mill1[] = {             640, 768,  800,        960, 
-					  1024, 1152, 1280,      1600,       1920, 
-					  2048, 0};
-	
-	DBG("Ti3026_preinit")
-
-	ACCESS_FBINFO(millenium) = 1;
-	ACCESS_FBINFO(milleniumII) = (ACCESS_FBINFO(pcidev)->device != PCI_DEVICE_ID_MATROX_MIL);
-	ACCESS_FBINFO(capable.cfb4) = 1;
-	ACCESS_FBINFO(capable.text) = 1; /* isMilleniumII(MINFO); */
-	ACCESS_FBINFO(capable.vxres) = isMilleniumII(MINFO)?vxres_mill2:vxres_mill1;
-	ACCESS_FBINFO(cursor.timer.function) = matroxfb_ti3026_flashcursor;
-
-	if (ACCESS_FBINFO(devflags.noinit))
-		return 0;
-	/* preserve VGA I/O, BIOS and PPC */
-	hw->MXoptionReg &= 0xC0000100;
-	hw->MXoptionReg |= 0x002C0000;
-	if (ACCESS_FBINFO(devflags.novga))
-		hw->MXoptionReg &= ~0x00000100;
-	if (ACCESS_FBINFO(devflags.nobios))
-		hw->MXoptionReg &= ~0x40000000;
-	if (ACCESS_FBINFO(devflags.nopciretry))
-		hw->MXoptionReg |=  0x20000000;
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
-
-	ACCESS_FBINFO(accel.ramdac_rev) = inTi3026(PMINFO TVP3026_XSILICONREV);
-
-	outTi3026(PMINFO TVP3026_XCLKCTRL, TVP3026_XCLKCTRL_SRC_CLK0VGA | TVP3026_XCLKCTRL_CLKSTOPPED);
-	outTi3026(PMINFO TVP3026_XTRUECOLORCTRL, TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR);
-	outTi3026(PMINFO TVP3026_XMUXCTRL, TVP3026_XMUXCTRL_VGA);
-	
-	outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
-	outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0x00);
-	outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00);
-
-	mga_outb(M_MISC_REG, 0x67);
-
-	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, TVP3026_XMEMPLLCTRL_STROBEMKC4 | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);
-
-	mga_outl(M_RESET, 1);
-	udelay(250);
-	mga_outl(M_RESET, 0);
-	udelay(250);
-	mga_outl(M_MACCESS, 0x00008000);
-	udelay(10);
-	return 0;
-}
-
-static void __init Ti3026_reset(WPMINFO struct matrox_hw_state* hw){
-	
-	DBG("Ti3026_reset")
-	
-	matroxfb_fastfont_init(MINFO);
-
-	ti3026_ramdac_init(PMINFO hw);
-}
-#endif
-
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-static struct matrox_switch matrox_millenium = { 
-	Ti3026_preinit, Ti3026_reset, Ti3026_init, Ti3026_restore 
-};
-#endif
-
-#ifdef CONFIG_FB_MATROX_MYSTIQUE
-static struct matrox_switch matrox_mystique = {
-	MGA1064_preinit, MGA1064_reset, MGA1064_init, MGA1064_restore
-};
-#endif
-
-#ifdef CONFIG_FB_MATROX_G100
-static struct matrox_switch matrox_G100 = {
-	MGAG100_preinit, MGAG100_reset, MGAG100_init, MGAG100_restore
-};
-#endif
-
-struct video_board {
-	int maxvram;
-	int maxdisplayable;
-	int accelID;
-	struct matrox_switch* lowlevel;
-		 };
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-static struct video_board vbMillenium __initdata   = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA2064W,	  &matrox_millenium};
-static struct video_board vbMillenium2 __initdata  = {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W,	  &matrox_millenium};
-static struct video_board vbMillenium2A __initdata = {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W_AGP, &matrox_millenium};
-#endif	/* CONFIG_FB_MATROX_MILLENIUM */
-#ifdef CONFIG_FB_MATROX_MYSTIQUE
-static struct video_board vbMystique __initdata    = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA1064SG,	  &matrox_mystique};
-#endif	/* CONFIG_FB_MATROX_MYSTIQUE */
-#ifdef CONFIG_FB_MATROX_G100
-static struct video_board vbG100 __initdata	   = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100,	  &matrox_G100};
-static struct video_board vbG200 __initdata	   = {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200,	  &matrox_G100};
-#ifdef CONFIG_FB_MATROX_32MB
-/* from doc it looks like that accelerator can draw only to low 16MB :-( Direct accesses & displaying are OK for
-   whole 32MB */
-static struct video_board vbG400 __initdata	   = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400,	  &matrox_G100};
-#else
-static struct video_board vbG400 __initdata	   = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400,	  &matrox_G100};
-#endif
-#endif
-
-#define DEVF_VIDEO64BIT	0x01
-#define	DEVF_SWAPS	0x02
-#define DEVF_MILLENIUM	0x04
-#define	DEVF_MILLENIUM2	0x08
-#define DEVF_CROSS4MB	0x10
-#define DEVF_TEXT4B	0x20
-#define DEVF_DDC_8_2	0x40
-#define DEVF_DMA	0x80
-#define DEVF_SUPPORT32MB	0x100
-#define DEVF_ANY_VXRES		0x200
-#define DEVF_TEXT16B		0x400
-
-#define DEVF_G100	(DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2) /* no doc, no vxres... */
-#define DEVF_G200	(DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2 | DEVF_ANY_VXRES)
-#define DEVF_G400	(DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2 | DEVF_ANY_VXRES | DEVF_SUPPORT32MB | DEVF_TEXT16B)
-
-static struct board {
-	unsigned short vendor, device, rev, svid, sid;
-	unsigned int flags;
-	unsigned int maxclk;
-	struct video_board* base;
-	const char* name;
-		} dev_list[] __initdata = {
-#ifdef CONFIG_FB_MATROX_MILLENIUM
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL,	0xFF,
-		0,			0,
-		DEVF_MILLENIUM | DEVF_TEXT4B,
-		230000,
-		&vbMillenium,
-		"Millennium (PCI)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL_2,	0xFF,
-		0,			0,
-		DEVF_MILLENIUM | DEVF_MILLENIUM2 | DEVF_SWAPS,
-		220000,
-		&vbMillenium2,
-		"Millennium II (PCI)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL_2_AGP,	0xFF,
-		0,			0,
-		DEVF_MILLENIUM | DEVF_MILLENIUM2 | DEVF_SWAPS,
-		250000,
-		&vbMillenium2A,
-		"Millennium II (AGP)"},
-#endif
-#ifdef CONFIG_FB_MATROX_MYSTIQUE
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MYS,	0x02,
-		0,			0,
-		DEVF_VIDEO64BIT,
-		180000,
-		&vbMystique,
-		"Mystique (PCI)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MYS,	0xFF,
-		0,			0,
-		DEVF_VIDEO64BIT | DEVF_SWAPS,
-		220000,
-		&vbMystique,
-		"Mystique 220 (PCI)"},
-#endif
-#ifdef CONFIG_FB_MATROX_G100
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100,	0xFF,
-		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MGA_G100_PCI,
-		DEVF_G100,
-		230000,
-		&vbG100,
-		"MGA-G100 (PCI)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100,	0xFF,
-		0,			0,
-		DEVF_G100,
-		230000,
-		&vbG100,
-		"unknown G100 (PCI)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_GENERIC,
-		DEVF_G100,
-		230000,
-		&vbG100,
-		"MGA-G100 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MGA_G100_AGP,
-		DEVF_G100,
-		230000,
-		&vbG100,
-		"MGA-G100 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_SIEMENS_NIXDORF,	PCI_SS_ID_SIEMENS_MGA_G100_AGP,
-		DEVF_G100,
-		230000,
-		&vbG100,
-		"MGA-G100 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP,
-		DEVF_G100,
-		230000,
-		&vbG100,
-		"Productiva G100 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
-		0,			0,
-		DEVF_G100,
-		230000,
-		&vbG100,
-		"unknown G100 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_PCI,	0xFF,
-		0,			0,
-		DEVF_G200,
-		250000,
-		&vbG200,
-		"unknown G200 (PCI)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_GENERIC,
-		DEVF_G200,
-		220000,
-		&vbG200,
-		"MGA-G200 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MYSTIQUE_G200_AGP,
-		DEVF_G200,
-		230000,
-		&vbG200,
-		"Mystique G200 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MILLENIUM_G200_AGP,
-		DEVF_G200,
-		250000,
-		&vbG200,
-		"Millennium G200 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MARVEL_G200_AGP,
-		DEVF_G200,
-		230000,
-		&vbG200,
-		"Marvel G200 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_SIEMENS_NIXDORF,	PCI_SS_ID_SIEMENS_MGA_G200_AGP,
-		DEVF_G200,
-		230000,
-		&vbG200,
-		"MGA-G200 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
-		0,			0,
-		DEVF_G200,
-		230000,
-		&vbG200,
-		"unknown G200 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G400_AGP,	0xFF,
-		0,			0,
-		DEVF_G400,
-		360000,
-		&vbG400,
-		"unknown G400 (AGP)"},
-#endif
-	{0,			0,				0xFF,
-		0,			0,
-		0,
-		0,
-		NULL,
-		NULL}};
-	
-#ifndef MODULE
-		/* it cannot be static const struct due to __initdata
-		marker */
-		static struct fb_videomode defaultmode __initdata = {
-			/* 640x480 @ 60Hz, 31.5 kHz */
-			NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
-			0, FB_VMODE_NONINTERLACED
-		};
-#endif /* !MODULE */
-
-static int __init initMatrox2(WPMINFO struct display* d, struct board* b){
-	unsigned long ctrlptr_phys = 0;
-	unsigned long video_base_phys = 0;
-	unsigned int memsize;
-	struct matrox_hw_state* hw = ACCESS_FBINFO(currenthw);
-
-	DBG("initMatrox2")
-
-	/* set default values... */
-	vesafb_defined.accel_flags = FB_ACCELF_TEXT;
-
-	ACCESS_FBINFO(hw_switch) = b->base->lowlevel;
-	ACCESS_FBINFO(devflags.accelerator) = b->base->accelID;
-	ACCESS_FBINFO(max_pixel_clock) = b->maxclk;
-
-	printk(KERN_INFO "matroxfb: Matrox %s detected\n", b->name);
-	ACCESS_FBINFO(capable.plnwt) = 1;
-	ACCESS_FBINFO(devflags.video64bits) = b->flags & DEVF_VIDEO64BIT;
-	if (b->flags & DEVF_TEXT4B) {
-		ACCESS_FBINFO(devflags.vgastep) = 4;
-		ACCESS_FBINFO(devflags.textmode) = 4;
-		ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP16;
-	} else if (b->flags & DEVF_TEXT16B) {
-		ACCESS_FBINFO(devflags.vgastep) = 16;
-		ACCESS_FBINFO(devflags.textmode) = 1;
-		ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP16;
-	} else {
-		ACCESS_FBINFO(devflags.vgastep) = 8;
-		ACCESS_FBINFO(devflags.textmode) = 1;
-		ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP8;
-	}
-#ifdef CONFIG_FB_MATROX_32MB
-	ACCESS_FBINFO(devflags.support32MB) = b->flags & DEVF_SUPPORT32MB;
-#endif
-	ACCESS_FBINFO(devflags.precise_width) = !(b->flags & DEVF_ANY_VXRES);
-	ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode);
-	ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode);
-
-	if (ACCESS_FBINFO(capable.cross4MB) < 0)
-		ACCESS_FBINFO(capable.cross4MB) = b->flags & DEVF_CROSS4MB;
-	if (b->flags & DEVF_SWAPS) {
-		ctrlptr_phys = ACCESS_FBINFO(pcidev)->resource[1].start;
-		video_base_phys = ACCESS_FBINFO(pcidev)->resource[0].start;
-	} else {
-		ctrlptr_phys = ACCESS_FBINFO(pcidev)->resource[0].start;
-		video_base_phys = ACCESS_FBINFO(pcidev)->resource[1].start;
-	}
-	if (!ctrlptr_phys) {
-		printk(KERN_ERR "matroxfb: control registers are not available, matroxfb disabled\n");
-		return -EINVAL;
-	}
-	if (!video_base_phys) {
-		printk(KERN_ERR "matroxfb: video RAM is not available in PCI address space, matroxfb disabled\n");
-		return -EINVAL;
-	}
-	if (mga_ioremap(ctrlptr_phys, 16384, MGA_IOREMAP_MMIO, &ACCESS_FBINFO(mmio.vbase))) {
-		printk(KERN_ERR "matroxfb: cannot ioremap(%lX, 16384), matroxfb disabled\n", ctrlptr_phys);
-		return -ENOMEM;
-	}
-	ACCESS_FBINFO(mmio.base) = ctrlptr_phys;
-	ACCESS_FBINFO(mmio.len) = 16384;
-	memsize = b->base->maxvram;
-/* convert mem (autodetect k, M) */
-	if (mem < 1024) mem *= 1024;
-	if (mem < 0x00100000) mem *= 1024;
-
-	if (mem && (mem < memsize))
-		memsize = mem;
-	ACCESS_FBINFO(video.base) = video_base_phys;
-	if (mga_ioremap(video_base_phys, memsize, MGA_IOREMAP_FB, &ACCESS_FBINFO(video.vbase))) {
-		printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n", 
-			video_base_phys, memsize);
-		mga_iounmap(ACCESS_FBINFO(mmio.vbase));
-		return -ENOMEM;
-	}
-	{
-		u_int32_t cmd;
-		u_int32_t mga_option;
-
-		/* Matrox MilleniumII is deactivated on bootup, but address
-		   regions are assigned to board. So we have to enable it */
-		pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, &mga_option);
-		pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd);
-		mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */
-		if ((cmd & PCI_COMMAND_MEMORY) !=
-			   PCI_COMMAND_MEMORY) {
-			/* But if we have to enable it, we have probably to
-                           disable VGA I/O and BIOS... Sure? */
-			dprintk(KERN_WARNING "matroxfb: PCI BIOS did not enable device!\n");
-			cmd = (cmd | PCI_COMMAND_MEMORY) & ~PCI_COMMAND_VGA_PALETTE;
-			mga_option &=  0xBFFFFEFF; 
-			/* we must not enable VGA, BIOS if PCI BIOS did not enable device itself */
-			ACCESS_FBINFO(devflags.novga) = 1;
-			ACCESS_FBINFO(devflags.nobios) = 1;
-			/* we must initialize device if PCI BIOS did not enable it.
-			   It probably means that it is second head ... */
-			ACCESS_FBINFO(devflags.noinit) = 0;
-		}
-		mga_option |= MX_OPTION_BSWAP;
-		if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, NULL)) {
-			if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) {
-				printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n");
-			}
-			mga_option |= 0x20000000;
-			ACCESS_FBINFO(devflags.nopciretry) = 1;
-		}
-		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, cmd);
-		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mga_option);
-		hw->MXoptionReg = mga_option;
-
-		/* select non-DMA memory for PCI_MGA_DATA, otherwise dump of PCI cfg space can lock PCI bus */
-		/* maybe preinit() candidate, but it is same... for all devices... at this time... */
-		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MGA_INDEX, 0x00003C00);
-	}
-
-	if (ACCESS_FBINFO(hw_switch)->preinit(PMINFO hw)) {
-		mga_iounmap(ACCESS_FBINFO(video.vbase));
-		mga_iounmap(ACCESS_FBINFO(mmio.vbase));
-		return -ENXIO;
-	}
-
-	{
-		unsigned int offs;
-
-		if (!matroxfb_getmemory(PMINFO memsize, &offs, &ACCESS_FBINFO(video.len)) || !ACCESS_FBINFO(video.len)) {
-			printk(KERN_ERR "matroxfb: cannot determine memory size\n");
-			mga_iounmap(ACCESS_FBINFO(video.vbase));
-			mga_iounmap(ACCESS_FBINFO(mmio.vbase));
-			return -ENOMEM;
-		}
-#ifdef MATROX_2MB_WITH_4MB_ADDON
-#ifdef FBCON_HAS_CFB24
-		{
-			unsigned int end = offs + ACCESS_FBINFO(video.len);
-
-			if (offs)
-				offs = ((offs - 1) / (4096 * 3) + 1) * 4096 * 3;
-			ACCESS_FBINFO(video.len) = end - offs;
-		}
-#endif
-		ACCESS_FBINFO(devflags.ydstorg) = offs;
-		video_base_phys += offs;
-		if (offs)
-			ACCESS_FBINFO(capable.text) = 0;
-#else
-		ACCESS_FBINFO(devflags.ydstorg) = 0;
-#endif
-	}
-	ACCESS_FBINFO(currcon) = -1;
-	ACCESS_FBINFO(currcon_display) = d;
-	mga_iounmap(ACCESS_FBINFO(video.vbase));
-	ACCESS_FBINFO(video.base) = video_base_phys;
-	if (mga_ioremap(video_base_phys, ACCESS_FBINFO(video.len), MGA_IOREMAP_FB, &ACCESS_FBINFO(video.vbase))) {
-		printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n", 
-			video_base_phys, ACCESS_FBINFO(video.len));
-		mga_iounmap(ACCESS_FBINFO(mmio.vbase));
-		return -ENOMEM;
-	}
-	ACCESS_FBINFO(video.len_usable) = ACCESS_FBINFO(video.len);
-	if (ACCESS_FBINFO(video.len_usable) > b->base->maxdisplayable)
-		ACCESS_FBINFO(video.len_usable) = b->base->maxdisplayable;
-#ifdef CONFIG_MTRR
-	if (mtrr) {
-		ACCESS_FBINFO(mtrr.vram) = mtrr_add(video_base_phys, ACCESS_FBINFO(video.len), MTRR_TYPE_WRCOMB, 1);
-		ACCESS_FBINFO(mtrr.vram_valid) = 1;
-		printk(KERN_INFO "matroxfb: MTRR's turned on\n");
-	}
-#endif	/* CONFIG_MTRR */
-
-	if (!ACCESS_FBINFO(devflags.novga))
-		request_region(0x3C0, 32, "matrox");
-	ACCESS_FBINFO(hw_switch->reset(PMINFO hw));
-
-/* validate params, autodetect k, M */
-	if (fh < 1000) fh *= 1000;	/* 1kHz minimum */
-	if (maxclk < 1000) maxclk *= 1000;	/* kHz -> Hz, MHz -> kHz */
-	if (maxclk < 1000000) maxclk *= 1000;	/* kHz -> Hz, 1MHz minimum */
-	if (vesa != ~0)
-		vesa &= 0x1DFF;		/* mask out clearscreen, acceleration and so on */
-
-	ACCESS_FBINFO(fbcon.monspecs.hfmin) = 0;
-	ACCESS_FBINFO(fbcon.monspecs.hfmax) = fh;
-	ACCESS_FBINFO(fbcon.monspecs.vfmin) = 0;
-	ACCESS_FBINFO(fbcon.monspecs.vfmax) = fv;
-	ACCESS_FBINFO(fbcon.monspecs.dpms) = 0;	/* TBD */
-
-/* static settings */
-	for (RSptr = vesamap; RSptr->vesa; RSptr++) {
-		if (RSptr->vesa == vesa) break;
-	}
-	if (!RSptr->vesa) {
-		printk(KERN_ERR "Invalid vesa mode 0x%04X\n", vesa);
-		RSptr = vesamap;
-	}
-	{
-		int res = RSResolution(RSptr->info)-1;
-		if (left == ~0)
-			left = timmings[res].left;
-		if (!xres)
-			xres = timmings[res].xres;
-		if (right == ~0)
-			right = timmings[res].right;
-		if (!hslen)
-			hslen = timmings[res].hslen;
-		if (upper == ~0)
-			upper = timmings[res].upper;
-		if (!yres)
-			yres = timmings[res].yres;
-		if (lower == ~0)
-			lower = timmings[res].lower;
-		if (!vslen)
-			vslen = timmings[res].vslen;
-		if (!(fv||fh||maxclk||pixclock))
-			fv = timmings[res].vfreq;
-		if (depth == -1)
-			depth = RSDepth(RSptr->info);
-	}
-	if ((depth == RSText8) && (!*ACCESS_FBINFO(fbcon.fontname))) {
-		strcpy(ACCESS_FBINFO(fbcon.fontname), "VGA8x8");
-	}
-	vesafb_defined.red = colors[depth-1].red;
-	vesafb_defined.green = colors[depth-1].green;
-	vesafb_defined.blue = colors[depth-1].blue;
-	vesafb_defined.bits_per_pixel = colors[depth-1].bits_per_pixel;
-	vesafb_defined.grayscale = grayscale;
-	vesafb_defined.vmode = 0;
-	if (noaccel)
-		vesafb_defined.accel_flags &= ~FB_ACCELF_TEXT;
-
-	strcpy(ACCESS_FBINFO(fbcon.modename), "MATROX VGA");
-	ACCESS_FBINFO(fbcon.changevar) = NULL;
-	ACCESS_FBINFO(fbcon.node) = -1;
-	ACCESS_FBINFO(fbcon.fbops) = &matroxfb_ops;
-	ACCESS_FBINFO(fbcon.disp) = d;
-	ACCESS_FBINFO(fbcon.switch_con) = &matroxfb_switch;
-	ACCESS_FBINFO(fbcon.updatevar) = &matroxfb_updatevar;
-	ACCESS_FBINFO(fbcon.blank) = &matroxfb_blank;
-	ACCESS_FBINFO(fbcon.flags) = FBINFO_FLAG_DEFAULT;
-	ACCESS_FBINFO(video.len_usable) &= PAGE_MASK;
-
-#ifndef MODULE
-	/* mode database is marked __init ... */
-	{
-		fb_find_mode(&vesafb_defined, &ACCESS_FBINFO(fbcon), videomode[0]?videomode:NULL,
-		NULL, 0, &defaultmode, vesafb_defined.bits_per_pixel);
-	}
-#endif /* !MODULE */
-
-	/* mode modifiers */
-	if (hslen)
-		vesafb_defined.hsync_len = hslen;
-	if (vslen)
-		vesafb_defined.vsync_len = vslen;
-	if (left != ~0)
-		vesafb_defined.left_margin = left;
-	if (right != ~0)
-		vesafb_defined.right_margin = right;
-	if (upper != ~0)
-		vesafb_defined.upper_margin = upper;
-	if (lower != ~0)
-		vesafb_defined.lower_margin = lower;
-	if (xres)
-		vesafb_defined.xres = xres;
-	if (yres)
-		vesafb_defined.yres = yres;
-	if (sync != -1)
-		vesafb_defined.sync = sync;
-	else if (vesafb_defined.sync == ~0) {
-		vesafb_defined.sync = 0;
-		if (yres < 400)
-			vesafb_defined.sync |= FB_SYNC_HOR_HIGH_ACT;
-		else if (yres < 480)
-			vesafb_defined.sync |= FB_SYNC_VERT_HIGH_ACT;
-	}
-	
-	/* fv, fh, maxclk limits was specified */
-	{
-		unsigned int tmp;
-
-		if (fv) {
-			tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres 
-			          + vesafb_defined.lower_margin + vesafb_defined.vsync_len);
-			if ((tmp < fh) || (fh == 0)) fh = tmp;
-		}
-		if (fh) {
-			tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres 
-			          + vesafb_defined.right_margin + vesafb_defined.hsync_len);
-			if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp;
-		}
-		maxclk = (maxclk + 499) / 500;
-		if (maxclk) {
-			tmp = (2000000000 + maxclk) / maxclk;
-			if (tmp > pixclock) pixclock = tmp;
-		}
-	}
-	if (pixclock) {
-		if (pixclock < 2000)		/* > 500MHz */
-			pixclock = 4000;	/* 250MHz */
-		if (pixclock > 1000000)
-			pixclock = 1000000;	/* 1MHz */
-		vesafb_defined.pixclock = pixclock;
-	}
-		
-	/* FIXME: Where to move this?! */
-#if defined(CONFIG_FB_OF)
-#if defined(CONFIG_FB_COMPAT_XPMAC)
-	strcpy(ACCESS_FBINFO(matrox_name), "MTRX,");	/* OpenFirmware naming convension */
-	strncat(ACCESS_FBINFO(matrox_name), b->name, 26);
-	if (!console_fb_info)
-		console_fb_info = &ACCESS_FBINFO(fbcon);
-#endif
-	if ((xres <= 640) && (yres <= 480)) {
-		struct fb_var_screeninfo var;
-		if (default_vmode == VMODE_NVRAM) {
-			default_vmode = nvram_read_byte(NV_VMODE);
-			if (default_vmode <= 0 || default_vmode > VMODE_MAX)
-				default_vmode = VMODE_CHOOSE;
-		}
-		if (default_vmode <= 0 || default_vmode > VMODE_MAX)
-			default_vmode = VMODE_640_480_60;
-		if (default_cmode == CMODE_NVRAM)
-			default_cmode = nvram_read_byte(NV_CMODE);
-		if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
-			default_cmode = CMODE_8;
-		if (!mac_vmode_to_var(default_vmode, default_cmode, &var)) {
-			var.accel_flags = vesafb_defined.accel_flags;
-			var.xoffset = var.yoffset = 0;
-			vesafb_defined = var; /* Note: mac_vmode_to_var() doesnot set all parameters */
-              }
-	}
-#endif
-	vesafb_defined.xres_virtual = vesafb_defined.xres;
-	if (nopan) {
-		vesafb_defined.yres_virtual = vesafb_defined.yres;
-	} else {
-		vesafb_defined.yres_virtual = 65536; /* large enough to be INF, but small enough
-		                                        to yres_virtual * xres_virtual < 2^32 */
-	}
-	if (matroxfb_set_var(&vesafb_defined, -2, &ACCESS_FBINFO(fbcon))) {
-		printk(KERN_ERR "matroxfb: cannot set required parameters\n");
-		return -EINVAL;
-	}
-
-	printk(KERN_INFO "matroxfb: %dx%dx%dbpp (virtual: %dx%d)\n",
-		vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel,
-		vesafb_defined.xres_virtual, vesafb_defined.yres_virtual);
-	printk(KERN_INFO "matroxfb: framebuffer at 0x%lX, mapped to 0x%p, size %d\n",
-		ACCESS_FBINFO(video.base), vaddr_va(ACCESS_FBINFO(video.vbase)), ACCESS_FBINFO(video.len));
-	
-/* We do not have to set currcon to 0... register_framebuffer do it for us on first console
- * and we do not want currcon == 0 for subsequent framebuffers */
-
-	if (register_framebuffer(&ACCESS_FBINFO(fbcon)) < 0) {
-		return -EINVAL;
-	}
-	printk("fb%d: %s frame buffer device\n",
-	       GET_FB_IDX(ACCESS_FBINFO(fbcon.node)), ACCESS_FBINFO(fbcon.modename));
-	if (ACCESS_FBINFO(currcon) < 0) {
-		/* there is no console on this fb... but we have to initialize hardware 
-		 * until someone tells me what is proper thing to do */
-		printk(KERN_INFO "fb%d: initializing hardware\n",
-			GET_FB_IDX(ACCESS_FBINFO(fbcon.node)));
-		matroxfb_set_var(&vesafb_defined, -1, &ACCESS_FBINFO(fbcon));
-	}
-	return 0;
-}
-
-static struct matrox_fb_info* fb_list = NULL;
-
-static int __init matrox_init(void){
-	struct pci_dev* pdev = NULL;
-
-	DBG("matrox_init")
-
-	if (disabled)
-		return -ENXIO; 
-	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
-		struct board* b;
-		u_int8_t rev;
-		u_int16_t svid;
-		u_int16_t sid;
-
-		pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
-		svid = pdev->subsystem_vendor;
-		sid = pdev->subsystem_device;
-		for (b = dev_list; b->vendor; b++) {
-			if ((b->vendor != pdev->vendor) || (b->device != pdev->device) || (b->rev < rev)) continue;
-			if (b->svid)
-				if ((b->svid != svid) || (b->sid != sid)) continue;
-			if (dev <= 0) {
-				struct matrox_fb_info* minfo;
-				struct display* d;
-				int err;
-
-#ifdef CONFIG_FB_MATROX_MULTIHEAD
-				minfo = (struct matrox_fb_info*)kmalloc(sizeof(*minfo), GFP_KERNEL);
-				if (minfo) {
-					d = (struct display*)kmalloc(sizeof(*d), GFP_KERNEL);
-					if (d) {
-#else
-				minfo = &global_mxinfo;
-				d = &global_disp;
-#endif
-				memset(MINFO, 0, sizeof(*MINFO));
-				memset(d, 0, sizeof(*d));
-
-				ACCESS_FBINFO(currenthw) = &ACCESS_FBINFO(hw1);
-				ACCESS_FBINFO(newhw) = &ACCESS_FBINFO(hw2);
-				ACCESS_FBINFO(pcidev) = pdev;
-				/* CMDLINE */
-				memcpy(ACCESS_FBINFO(fbcon.fontname), fontname, sizeof(ACCESS_FBINFO(fbcon.fontname)));
-				/* DEVFLAGS */
-				ACCESS_FBINFO(devflags.inverse) = inverse;
-				ACCESS_FBINFO(devflags.novga) = novga;
-				ACCESS_FBINFO(devflags.nobios) = nobios;
-				ACCESS_FBINFO(devflags.noinit) = noinit;
-				ACCESS_FBINFO(devflags.nopciretry) = no_pci_retry;
-				ACCESS_FBINFO(devflags.mga_24bpp_fix) = inv24;
-				ACCESS_FBINFO(devflags.precise_width) = option_precise_width;
-				ACCESS_FBINFO(devflags.hwcursor) = hwcursor;
-				ACCESS_FBINFO(devflags.blink) = blink;
-				ACCESS_FBINFO(devflags.sgram) = sgram;
-				ACCESS_FBINFO(capable.cross4MB) = cross4MB;
-
-				ACCESS_FBINFO(fastfont.size) = fastfont;
-
-				ACCESS_FBINFO(cursor.state) = CM_ERASE;
-				ACCESS_FBINFO(cursor.timer.prev) = ACCESS_FBINFO(cursor.timer.next) = NULL;
-				ACCESS_FBINFO(cursor.timer.data) = (unsigned long)MINFO;
-				spin_lock_init(&ACCESS_FBINFO(lock.DAC));
-
-        			err = initMatrox2(PMINFO d, b);
-				if (!err) {
-					ACCESS_FBINFO(next_fb) = fb_list;
-					fb_list = MINFO;
-#ifdef CONFIG_FB_MATROX_MULTIHEAD
-					goto leave;
-#else
-					return 0;
-#endif
-				}
-#ifdef CONFIG_FB_MATROX_MULTIHEAD
-						kfree(d);
-					}
-					kfree(minfo);
-				}
-#endif
-			}
-#ifdef CONFIG_FB_MATROX_MULTIHEAD
-leave:;
-#endif
-			if (dev == 0) return 0;
-			if (dev > 0) dev--;
-			break;
-		}
-	}
-	return 0;
-}
-
-#ifndef MODULE
-static int __init initialized = 0;
-
-int __init matroxfb_init(void)
-{
-	DBG("matroxfb_init")
-	
-	if (!initialized) {
-		initialized = 1;
-		matrox_init();
-	}
-	if (!fb_list) return -ENXIO;
-	return 0;
-}
-
-#if defined(CONFIG_FB_OF)
-int __init matrox_of_init(struct device_node *dp){
-	DBG("matrox_of_init");
-	
-	if (!initialized) {
-		initialized = 1;
-		matrox_init();
-	}
-	if (!fb_list) return -ENXIO;
-	return 0;
-}
-#endif	/* CONFIG_FB_OF */
-
-#else
-
-MODULE_AUTHOR("(c) 1998,1999 Petr Vandrovec <vandrove@vc.cvut.cz>");
-MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400");
-MODULE_PARM(mem, "i");
-MODULE_PARM_DESC(mem, "Size of available memory in MB, KB or B (2,4,8,12,16MB, default=autodetect)");
-MODULE_PARM(disabled, "i");
-MODULE_PARM_DESC(disabled, "Disabled (0 or 1=disabled), meaningless for module (default=0)");
-MODULE_PARM(noaccel, "i");
-MODULE_PARM_DESC(noaccel, "Do not use accelerating engine (0 or 1=disabled) (default=0)");
-MODULE_PARM(nopan, "i");
-MODULE_PARM_DESC(nopan, "Disable pan on startup (0 or 1=disabled) (default=0)");
-MODULE_PARM(no_pci_retry, "i");
-MODULE_PARM_DESC(no_pci_retry, "PCI retries enabled (0 or 1=disabled) (default=0)");
-MODULE_PARM(novga, "i");
-MODULE_PARM_DESC(novga, "VGA I/O (0x3C0-0x3DF) disabled (0 or 1=disabled) (default=0)");
-MODULE_PARM(nobios, "i");
-MODULE_PARM_DESC(nobios, "Disables ROM BIOS (0 or 1=disabled) (default=do not change BIOS state)"); 
-MODULE_PARM(noinit, "i");
-MODULE_PARM_DESC(noinit, "Disables W/SG/SD-RAM and bus interface initialization (0 or 1=do not initialize) (default=0)");
-MODULE_PARM(mtrr, "i");
-MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)");
-MODULE_PARM(sgram, "i");
-MODULE_PARM_DESC(sgram, "Indicates that G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
-MODULE_PARM(inv24, "i");
-MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)");
-MODULE_PARM(inverse, "i");
-MODULE_PARM_DESC(inverse, "Inverse (0 or 1) (default=0)");
-#ifdef CONFIG_FB_MATROX_MULTIHEAD
-MODULE_PARM(dev, "i");
-MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=all working)");
-#else
-MODULE_PARM(dev, "i");
-MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=first working)");
-#endif
-MODULE_PARM(vesa, "i");
-MODULE_PARM_DESC(vesa, "Startup videomode (0x000-0x1FF) (default=0x101)");
-MODULE_PARM(xres, "i");
-MODULE_PARM_DESC(xres, "Horizontal resolutioni (px), overrides xres from vesa (default=vesa)");
-MODULE_PARM(yres, "i");
-MODULE_PARM_DESC(yres, "Vertical resolution (scans), overrides yres from vesa (default=vesa)");
-MODULE_PARM(upper, "i");
-MODULE_PARM_DESC(upper, "Upper blank space (scans), overrides upper from vesa (default=vesa)");
-MODULE_PARM(lower, "i");
-MODULE_PARM_DESC(lower, "Lower blank space (scans), overrides lower from vesa (default=vesa)");
-MODULE_PARM(vslen, "i");
-MODULE_PARM_DESC(vslen, "Vertical sync length (scans), overrides lower from vesa (default=vesa)");
-MODULE_PARM(left, "i");
-MODULE_PARM_DESC(left, "Left blank space (px), overrides left from vesa (default=vesa)");
-MODULE_PARM(right, "i");
-MODULE_PARM_DESC(right, "Right blank space (px), overrides right from vesa (default=vesa)");
-MODULE_PARM(hslen, "i");
-MODULE_PARM_DESC(hslen, "Horizontal sync length (px), overrides hslen from vesa (default=vesa)");
-MODULE_PARM(pixclock, "i");
-MODULE_PARM_DESC(pixclock, "Pixelclock (ns), overrides pixclock from vesa (default=vesa)");
-MODULE_PARM(sync, "i");
-MODULE_PARM_DESC(sync, "Sync polarity, overrides sync from vesa (default=vesa)");
-MODULE_PARM(depth, "i");
-MODULE_PARM_DESC(depth, "Color depth (0=text,8,15,16,24,32) (default=vesa)");
-MODULE_PARM(maxclk, "i");
-MODULE_PARM_DESC(maxclk, "Startup maximal clock, 0-999MHz, 1000-999999kHz, 1000000-INF Hz");
-MODULE_PARM(fh, "i");
-MODULE_PARM_DESC(fh, "Startup horizontal frequency, 0-999kHz, 1000-INF Hz");
-MODULE_PARM(fv, "i");
-MODULE_PARM_DESC(fv, "Startup vertical frequency, 0-INF Hz\n"
-"You should specify \"fv:max_monitor_vsync,fh:max_monitor_hsync,maxclk:max_monitor_dotclock\"\n");
-MODULE_PARM(hwcursor, "i");
-MODULE_PARM_DESC(hwcursor, "Enables hardware cursor (0 or 1) (default=0)");
-MODULE_PARM(blink, "i");
-MODULE_PARM_DESC(blink, "Enables hardware cursor blinking (0 or 1) (default=1)");
-MODULE_PARM(fastfont, "i");
-MODULE_PARM_DESC(fastfont, "Specifies, how much memory should be used for font data (0, 1024-65536 are reasonable) (default=0)");
-MODULE_PARM(grayscale, "i");
-MODULE_PARM_DESC(grayscale, "Sets display into grayscale. Works perfectly with paletized videomode (4, 8bpp), some limitations apply to 16, 24 and 32bpp videomodes (default=nograyscale)");
-MODULE_PARM(cross4MB, "i");
-MODULE_PARM_DESC(cross4MB, "Specifies that 4MB boundary can be in middle of line. (default=autodetected)");
-#ifdef CONFIG_FB_OF
-MODULE_PARM(vmode, "i");
-MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)");
-MODULE_PARM(cmode, "i");
-MODULE_PARM_DESC(cmode, "Specify the video depth that should be used (8bit default)");
-#endif
-
-int __init init_module(void){
-
-	DBG("init_module")
-
-#ifdef DEBUG
-	if( disabled )
-		return -ENXIO;
-#endif /* DEBUG */
-
-	if (depth == 0)
-		depth = RSText;
-	else if (depth == 4)
-		depth = RS4bpp;
-	else if (depth == 8)
-		depth = RS8bpp;
-	else if (depth == 15)
-		depth = RS15bpp;
-	else if (depth == 16)
-		depth = RS16bpp;
-	else if (depth == 24)
-		depth = RS24bpp;
-	else if (depth == 32)
-		depth = RS32bpp;
-	else if (depth != -1) {
-		printk(KERN_ERR "matroxfb: depth %d is not supported, using default\n", depth);
-		depth = -1;
-	}
-	matrox_init();
-	if (!fb_list) return -ENXIO;
-	return 0;
-}
-
-void cleanup_module(void) {
-
-	DBG("cleanup_module")
-
-#ifdef DEBUG
-	if( disabled )
-		return;
-#endif /* DEBUG */
-
-	while (fb_list) {
-		struct matrox_fb_info* minfo;
-
-		minfo = fb_list;
-		fb_list = fb_list->next_fb;
-		unregister_framebuffer(&ACCESS_FBINFO(fbcon));
-		del_timer(&ACCESS_FBINFO(cursor.timer));
-#ifdef CONFIG_MTRR
-		if (ACCESS_FBINFO(mtrr.vram_valid))
-			mtrr_del(ACCESS_FBINFO(mtrr.vram), ACCESS_FBINFO(video.base), ACCESS_FBINFO(video.len));
-#endif
-		mga_iounmap(ACCESS_FBINFO(mmio.vbase));
-		mga_iounmap(ACCESS_FBINFO(video.vbase));
-#ifdef CONFIG_FB_MATROX_MULTIHEAD
-		kfree_s(ACCESS_FBINFO(fbcon.disp), sizeof(struct display));
-		kfree_s(minfo, sizeof(struct matrox_fb_info));
-#endif
-	}
-}
-#endif	/* MODULE */
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff -u --recursive --new-file v2.3.47/linux/drivers/video/vgacon.c linux/drivers/video/vgacon.c
--- v2.3.47/linux/drivers/video/vgacon.c	Mon Oct  4 15:49:30 1999
+++ linux/drivers/video/vgacon.c	Thu Feb 24 10:14:29 2000
@@ -106,7 +106,14 @@
 static unsigned int    vga_default_font_height;	/* Height of default screen font */
 static unsigned char   vga_video_type;		/* Card type */
 static unsigned char   vga_hardscroll_enabled;
+#ifdef CONFIG_IA64_SOFTSDV_HACKS
+/*
+ * SoftSDV doesn't have hardware assist VGA scrolling 
+ */
+static unsigned char   vga_hardscroll_user_enable = 0;
+#else
 static unsigned char   vga_hardscroll_user_enable = 1;
+#endif
 static unsigned char   vga_font_is_default = 1;
 static int	       vga_vesa_blanked;
 static int	       vga_palette_blanked;
diff -u --recursive --new-file v2.3.47/linux/drivers/zorro/proc.c linux/drivers/zorro/proc.c
--- v2.3.47/linux/drivers/zorro/proc.c	Thu Feb 10 17:11:15 2000
+++ linux/drivers/zorro/proc.c	Sat Feb 26 20:33:03 2000
@@ -77,10 +77,6 @@
 	read:		proc_bus_zorro_read,
 };
 
-static struct inode_operations proc_bus_zorro_inode_operations = {
-	&proc_bus_zorro_operations, /* default base directory file-ops */
-};
-
 static int
 get_zorro_dev_info(char *buf, char **start, off_t pos, int count)
 {
@@ -118,7 +114,7 @@
 	entry = create_proc_entry(name, 0, proc_bus_zorro_dir);
 	if (!entry)
 		return -ENOMEM;
-	entry->ops = &proc_bus_zorro_inode_operations;
+	entry->proc_fops = &proc_bus_zorro_operations;
 	entry->data = &zorro_autocon[slot];
 	entry->size = sizeof(struct zorro_dev);
 	return 0;
diff -u --recursive --new-file v2.3.47/linux/fs/Config.in linux/fs/Config.in
--- v2.3.47/linux/fs/Config.in	Sun Feb 20 21:12:39 2000
+++ linux/fs/Config.in	Mon Feb 21 10:23:31 2000
@@ -24,7 +24,7 @@
 dep_tristate '  VFAT (Windows-95) fs support' CONFIG_VFAT_FS $CONFIG_FAT_FS
 dep_tristate 'EFS file system support (read only) (EXPERIMENTAL)' CONFIG_EFS_FS $CONFIG_EXPERIMENTAL
 
-tristate 'Compressed ROM file sytem support' CONFIG_CRAMFS
+tristate 'Compressed ROM file system support' CONFIG_CRAMFS
 
 tristate 'ISO 9660 CDROM file system support' CONFIG_ISO9660_FS
 if [ "$CONFIG_ISO9660_FS" != "n" ]; then
diff -u --recursive --new-file v2.3.47/linux/fs/adfs/adfs.h linux/fs/adfs/adfs.h
--- v2.3.47/linux/fs/adfs/adfs.h	Thu Feb 10 17:11:16 2000
+++ linux/fs/adfs/adfs.h	Sat Feb 26 20:33:03 2000
@@ -96,6 +96,7 @@
 
 /* dir_*.c */
 extern struct inode_operations adfs_dir_inode_operations;
+extern struct file_operations adfs_dir_operations;
 extern struct adfs_dir_ops adfs_f_dir_ops;
 extern struct adfs_dir_ops adfs_fplus_dir_ops;
 
@@ -103,6 +104,7 @@
 
 /* file.c */
 extern struct inode_operations adfs_file_inode_operations;
+extern struct file_operations adfs_file_operations;
 
 extern inline __u32 signed_asl(__u32 val, signed int shift)
 {
diff -u --recursive --new-file v2.3.47/linux/fs/adfs/dir.c linux/fs/adfs/dir.c
--- v2.3.47/linux/fs/adfs/dir.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/adfs/dir.c	Sat Feb 26 20:33:42 2000
@@ -188,14 +188,8 @@
 	return ret;
 }
 
-static ssize_t
-adfs_dir_no_read(struct file *filp, char *buf, size_t siz, loff_t *ppos)
-{
-	return -EISDIR;
-}
-
-static struct file_operations adfs_dir_operations = {
-	read:		adfs_dir_no_read,
+struct file_operations adfs_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	adfs_readdir,
 	fsync:		file_fsync,
 };
@@ -296,7 +290,6 @@
  * directories can handle most operations...
  */
 struct inode_operations adfs_dir_inode_operations = {
-	&adfs_dir_operations,	/* default directory file-ops */
-	NULL,			/* create		*/
-	adfs_lookup,		/* lookup		*/
+	lookup:		adfs_lookup,
+	setattr:	adfs_notify_change,
 };
diff -u --recursive --new-file v2.3.47/linux/fs/adfs/file.c linux/fs/adfs/file.c
--- v2.3.47/linux/fs/adfs/file.c	Sun Feb 13 19:29:04 2000
+++ linux/fs/adfs/file.c	Sat Feb 26 20:33:42 2000
@@ -33,7 +33,7 @@
  * We have mostly NULLs here: the current defaults are OK for
  * the adfs filesystem.
  */
-static struct file_operations adfs_file_operations = {
+struct file_operations adfs_file_operations = {
 	read:		generic_file_read,
 	mmap:		generic_file_mmap,
 	fsync:		file_fsync,
@@ -43,8 +43,9 @@
 };
 
 struct inode_operations adfs_file_inode_operations = {
-	&adfs_file_operations,	/* default file operations */
+	setattr:	adfs_notify_change,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
+	&adfs_file_operations,	/* default file operations */
 	readpage:	generic_readpage,
 	bmap:		adfs_bmap,
 #endif
diff -u --recursive --new-file v2.3.47/linux/fs/adfs/inode.c linux/fs/adfs/inode.c
--- v2.3.47/linux/fs/adfs/inode.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/adfs/inode.c	Sat Feb 26 20:33:04 2000
@@ -283,10 +283,12 @@
 	inode->i_atime	 =
 	inode->i_ctime	 = adfs_adfs2unix_time(inode);
 
-	if (S_ISDIR(inode->i_mode))
+	if (S_ISDIR(inode->i_mode)) {
 		inode->i_op	= &adfs_dir_inode_operations;
-	else if (S_ISREG(inode->i_mode)) {
+		inode->i_fop	= &adfs_dir_operations;
+	} else if (S_ISREG(inode->i_mode)) {
 		inode->i_op	= &adfs_file_inode_operations;
+		inode->i_fop	= &adfs_file_operations;
 		inode->i_mapping->a_ops = &adfs_aops;
 		inode->u.adfs_i.mmu_private = inode->i_size;
 	}
@@ -295,17 +297,6 @@
 
 out:
 	return inode;
-}
-
-/*
- * This is no longer a valid way to obtain the metadata associated with the
- * inode number on this filesystem.  This means that this filesystem cannot
- * be shared via NFS.
- */
-void adfs_read_inode(struct inode *inode)
-{
-	adfs_error(inode->i_sb, "unsupported method of reading inode");
-	make_bad_inode(inode);
 }
 
 /*
diff -u --recursive --new-file v2.3.47/linux/fs/adfs/super.c linux/fs/adfs/super.c
--- v2.3.47/linux/fs/adfs/super.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/adfs/super.c	Sat Feb 26 20:33:42 2000
@@ -231,17 +231,10 @@
 }
 
 static struct super_operations adfs_sops = {
-	adfs_read_inode,	/* read_inode		*/
-	adfs_write_inode,	/* write_inode		*/
-	NULL,			/* put_inode		*/
-	NULL,			/* delete_inode		*/
-	adfs_notify_change,	/* notify_change	*/
-	adfs_put_super,		/* put_super		*/
-	NULL,			/* write_super		*/
-	adfs_statfs,		/* statfs		*/
-	adfs_remount,		/* remount_fs		*/
-	NULL,			/* clear_inode		*/
-	NULL			/* umount_begin		*/
+	write_inode:	adfs_write_inode,
+	put_super:	adfs_put_super,
+	statfs:		adfs_statfs,
+	remount_fs:	adfs_remount,
 };
 
 static struct adfs_discmap *adfs_read_map(struct super_block *sb, struct adfs_discrecord *dr)
diff -u --recursive --new-file v2.3.47/linux/fs/affs/dir.c linux/fs/affs/dir.c
--- v2.3.47/linux/fs/affs/dir.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/affs/dir.c	Sat Feb 26 20:33:42 2000
@@ -25,10 +25,9 @@
 #include <linux/amigaffs.h>
 
 static int affs_readdir(struct file *, void *, filldir_t);
-static ssize_t affs_dir_read(struct file *, char *, size_t, loff_t *);
 
-static struct file_operations affs_dir_operations = {
-	read:		affs_dir_read,
+struct file_operations affs_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	affs_readdir,
 	fsync:		file_fsync,
 };
@@ -37,23 +36,16 @@
  * directories can handle most operations...
  */
 struct inode_operations affs_dir_inode_operations = {
-	&affs_dir_operations,	/* default directory file-ops */
-	affs_create,		/* create */
-	affs_lookup,		/* lookup */
-	affs_link,		/* link */
-	affs_unlink,		/* unlink */
-	affs_symlink,		/* symlink */
-	affs_mkdir,		/* mkdir */
-	affs_rmdir,		/* rmdir */
-	NULL,			/* mknod */
-	affs_rename,		/* rename */
+	create:		affs_create,
+	lookup:		affs_lookup,
+	link:		affs_link,
+	unlink:		affs_unlink,
+	symlink:	affs_symlink,
+	mkdir:		affs_mkdir,
+	rmdir:		affs_rmdir,
+	rename:		affs_rename,
+	setattr:	affs_notify_change,
 };
-
-static ssize_t
-affs_dir_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
-{
-	return -EISDIR;
-}
 
 static int
 affs_readdir(struct file *filp, void *dirent, filldir_t filldir)
diff -u --recursive --new-file v2.3.47/linux/fs/affs/file.c linux/fs/affs/file.c
--- v2.3.47/linux/fs/affs/file.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/affs/file.c	Sat Feb 26 20:33:42 2000
@@ -43,7 +43,7 @@
 static ssize_t affs_file_write_ofs(struct file *filp, const char *buf, size_t cnt, loff_t *ppos);
 static int alloc_ext_cache(struct inode *inode);
 
-static struct file_operations affs_file_operations = {
+struct file_operations affs_file_operations = {
 	read:		generic_file_read,
 	write:		affs_file_write,
 	mmap:		generic_file_mmap,
@@ -51,45 +51,14 @@
 };
 
 struct inode_operations affs_file_inode_operations = {
-	&affs_file_operations,	/* default file operations */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	affs_truncate,		/* truncate */
-	NULL,			/* permission */
-	NULL			/* revalidate */
+	truncate:	affs_truncate,
+	setattr:	affs_notify_change,
 };
 
-static struct file_operations affs_file_operations_ofs = {
+struct file_operations affs_file_operations_ofs = {
 	read:		affs_file_read_ofs,
 	write:		affs_file_write_ofs,
 	fsync:		file_fsync,
-};
-
-struct inode_operations affs_file_inode_operations_ofs = {
-	&affs_file_operations_ofs,	/* default file operations */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	affs_truncate,		/* truncate */
-	NULL,			/* permission */
-	NULL			/* revalidate */
 };
 
 #define AFFS_ISINDEX(x)	((x < 129) ||				\
diff -u --recursive --new-file v2.3.47/linux/fs/affs/inode.c linux/fs/affs/inode.c
--- v2.3.47/linux/fs/affs/inode.c	Sun Feb 13 19:29:04 2000
+++ linux/fs/affs/inode.c	Sat Feb 26 20:33:42 2000
@@ -162,22 +162,24 @@
 			 sys_tz.tz_minuteswest * 60;
 	affs_brelse(bh);
 
-	inode->i_op = NULL;
 	if (S_ISREG(inode->i_mode)) {
 		if (inode->i_sb->u.affs_sb.s_flags & SF_OFS) {
-			inode->i_op = &affs_file_inode_operations_ofs;
+			inode->i_op = &affs_file_inode_operations;
+			inode->i_fop = &affs_file_operations_ofs;
 			return;
 		}
 		inode->i_op = &affs_file_inode_operations;
+		inode->i_fop = &affs_file_operations;
 		inode->i_mapping->a_ops = &affs_aops;
 		inode->u.affs_i.mmu_private = inode->i_size;
 	} else if (S_ISDIR(inode->i_mode)) {
 		/* Maybe it should be controlled by mount parameter? */
 		inode->i_mode |= S_ISVTX;
 		inode->i_op = &affs_dir_inode_operations;
+		inode->i_fop = &affs_dir_operations;
 	}
 	else if (S_ISLNK(inode->i_mode)) {
-		inode->i_op = &page_symlink_inode_operations;
+		inode->i_op = &affs_symlink_inode_operations;
 		inode->i_data.a_ops = &affs_symlink_aops;
 	}
 }
@@ -295,24 +297,16 @@
 
 	sb = dir->i_sb;
 	inode->i_sb    = sb;
-	inode->i_flags = 0;
 
 	if (!(block = affs_new_header((struct inode *)dir))) {
 		iput(inode);
 		return NULL;
 	}
 
-	inode->i_count   = 1;
-	inode->i_nlink   = 1;
 	inode->i_dev     = sb->s_dev;
 	inode->i_uid     = current->fsuid;
 	inode->i_gid     = current->fsgid;
 	inode->i_ino     = block;
-	inode->i_op      = NULL;
-	inode->i_blocks  = 0;
-	inode->i_size    = 0;
-	inode->i_mode    = 0;
-	inode->i_blksize = 0;
 	inode->i_mtime   = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 
 	inode->u.affs_i.i_original  = 0;
diff -u --recursive --new-file v2.3.47/linux/fs/affs/namei.c linux/fs/affs/namei.c
--- v2.3.47/linux/fs/affs/namei.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/affs/namei.c	Sat Feb 26 20:33:42 2000
@@ -274,9 +274,11 @@
 
 	pr_debug("AFFS: ino=%lu\n",inode->i_ino);
 	if (dir->i_sb->u.affs_sb.s_flags & SF_OFS)
-		inode->i_op = &affs_file_inode_operations_ofs;
+		inode->i_op = &affs_file_inode_operations;
+		inode->i_fop = &affs_file_operations_ofs;
 	else {
 		inode->i_op = &affs_file_inode_operations;
+		inode->i_fop = &affs_file_operations;
 		inode->i_mapping->a_ops = &affs_aops;
 		inode->u.affs_i.mmu_private = inode->i_size;
 	}
@@ -314,6 +316,7 @@
 		goto out;
 
 	inode->i_op = &affs_dir_inode_operations;
+	inode->i_fop = &affs_dir_operations;
 	error       = affs_add_entry(dir,NULL,inode,dentry,ST_USERDIR);
 	if (error)
 		goto out_iput;
@@ -403,7 +406,7 @@
 	if (!inode)
 		goto out;
 
-	inode->i_op = &page_symlink_inode_operations;
+	inode->i_op = &affs_symlink_inode_operations;
 	inode->i_data.a_ops = &affs_symlink_aops;
 	inode->i_mode = S_IFLNK | 0777;
 	inode->u.affs_i.i_protect = mode_to_prot(inode->i_mode);
@@ -495,6 +498,7 @@
 		goto out;
 
 	inode->i_op                = oldinode->i_op;
+	inode->i_fop               = oldinode->i_fop;
 	inode->u.affs_i.i_protect  = mode_to_prot(oldinode->i_mode);
 	inode->u.affs_i.i_original = oldinode->i_ino;
 	inode->u.affs_i.i_hlink    = 1;
diff -u --recursive --new-file v2.3.47/linux/fs/affs/super.c linux/fs/affs/super.c
--- v2.3.47/linux/fs/affs/super.c	Tue Aug 31 17:29:14 1999
+++ linux/fs/affs/super.c	Sat Feb 26 20:33:42 2000
@@ -98,15 +98,14 @@
 }
 
 static struct super_operations affs_sops = {
-	affs_read_inode,
-	affs_write_inode,
-	affs_put_inode,
-	affs_delete_inode,
-	affs_notify_change,
-	affs_put_super,
-	affs_write_super,
-	affs_statfs,
-	affs_remount
+	read_inode:	affs_read_inode,
+	write_inode:	affs_write_inode,
+	put_inode:	affs_put_inode,
+	delete_inode:	affs_delete_inode,
+	put_super:	affs_put_super,
+	write_super:	affs_write_super,
+	statfs:		affs_statfs,
+	remount_fs:	affs_remount,
 };
 
 static int
diff -u --recursive --new-file v2.3.47/linux/fs/affs/symlink.c linux/fs/affs/symlink.c
--- v2.3.47/linux/fs/affs/symlink.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/affs/symlink.c	Sat Feb 26 20:33:42 2000
@@ -74,3 +74,9 @@
 struct address_space_operations affs_symlink_aops = {
 	readpage:	affs_symlink_readpage,
 };
+
+struct inode_operations affs_symlink_inode_operations = {
+	readlink:	page_readlink,
+	follow_link:	page_follow_link,
+	setattr:	affs_notify_change,
+};
diff -u --recursive --new-file v2.3.47/linux/fs/attr.c linux/fs/attr.c
--- v2.3.47/linux/fs/attr.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/attr.c	Sat Feb 26 20:33:42 2000
@@ -92,8 +92,8 @@
 		attr->ia_mtime = now;
 
 	if (inode->i_sb && inode->i_sb->s_op &&
-	    inode->i_sb->s_op->notify_change) 
-		error = inode->i_sb->s_op->notify_change(dentry, attr);
+	    inode->i_op->setattr) 
+		error = inode->i_op->setattr(dentry, attr);
 	else {
 		error = inode_change_ok(inode, attr);
 		if (!error)
diff -u --recursive --new-file v2.3.47/linux/fs/autofs/autofs_i.h linux/fs/autofs/autofs_i.h
--- v2.3.47/linux/fs/autofs/autofs_i.h	Wed Aug 18 16:44:22 1999
+++ linux/fs/autofs/autofs_i.h	Sat Feb 26 20:33:04 2000
@@ -140,6 +140,8 @@
 extern struct inode_operations autofs_root_inode_operations;
 extern struct inode_operations autofs_symlink_inode_operations;
 extern struct inode_operations autofs_dir_inode_operations;
+extern struct file_operations autofs_root_operations;
+extern struct file_operations autofs_dir_operations;
 
 /* Initializing function */
 
diff -u --recursive --new-file v2.3.47/linux/fs/autofs/dir.c linux/fs/autofs/dir.c
--- v2.3.47/linux/fs/autofs/dir.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/autofs/dir.c	Sat Feb 26 20:33:04 2000
@@ -42,13 +42,12 @@
 	return NULL;
 }
 
-static struct file_operations autofs_dir_operations = {
+struct file_operations autofs_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	autofs_dir_readdir,
 };
 
 struct inode_operations autofs_dir_inode_operations = {
-	&autofs_dir_operations,	/* file operations */
-	NULL,			/* create */
-	autofs_dir_lookup,	/* lookup */
+	lookup:		autofs_dir_lookup,
 };
 
diff -u --recursive --new-file v2.3.47/linux/fs/autofs/inode.c linux/fs/autofs/inode.c
--- v2.3.47/linux/fs/autofs/inode.c	Tue Jun  8 10:47:58 1999
+++ linux/fs/autofs/inode.c	Sat Feb 26 20:33:04 2000
@@ -60,15 +60,12 @@
 static void autofs_write_inode(struct inode *inode);
 
 static struct super_operations autofs_sops = {
-	autofs_read_inode,
-	autofs_write_inode,
-	autofs_put_inode,
-	autofs_delete_inode,
-	NULL,			/* notify_change */
-	autofs_put_super,
-	NULL,			/* write_super */
-	autofs_statfs,
-	NULL
+	read_inode:	autofs_read_inode,
+	write_inode:	autofs_write_inode,
+	put_inode:	autofs_put_inode,
+	delete_inode:	autofs_delete_inode,
+	put_super:	autofs_put_super,
+	statfs:		autofs_statfs,
 };
 
 static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid_t *pgrp, int *minproto, int *maxproto)
@@ -300,8 +297,8 @@
 
 	/* Initialize to the default case (stub directory) */
 
-	inode->i_op = NULL;
 	inode->i_op = &autofs_dir_inode_operations;
+	inode->i_fop = &autofs_dir_operations;
 	inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
 	inode->i_nlink = 2;
 	inode->i_size = 0;
@@ -312,6 +309,7 @@
 	if ( ino == AUTOFS_ROOT_INO ) {
 		inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
 		inode->i_op = &autofs_root_inode_operations;
+		inode->i_fop = &autofs_root_operations;
 		inode->i_uid = inode->i_gid = 0; /* Changed in read_super */
 		return;
 	} 
diff -u --recursive --new-file v2.3.47/linux/fs/autofs/root.c linux/fs/autofs/root.c
--- v2.3.47/linux/fs/autofs/root.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/autofs/root.c	Sat Feb 26 20:33:04 2000
@@ -23,20 +23,18 @@
 static int autofs_root_mkdir(struct inode *,struct dentry *,int);
 static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long);
 
-static struct file_operations autofs_root_operations = {
+struct file_operations autofs_root_operations = {
+	read:		generic_read_dir,
 	readdir:	autofs_root_readdir,
 	ioctl:		autofs_root_ioctl,
 };
 
 struct inode_operations autofs_root_inode_operations = {
-        &autofs_root_operations, /* file operations */
-        NULL,                   /* create */
-        autofs_root_lookup,     /* lookup */
-        NULL,                   /* link */
-        autofs_root_unlink,     /* unlink */
-        autofs_root_symlink,    /* symlink */
-        autofs_root_mkdir,      /* mkdir */
-        autofs_root_rmdir,      /* rmdir */
+        lookup:		autofs_root_lookup,
+        unlink:		autofs_root_unlink,
+        symlink:	autofs_root_symlink,
+        mkdir:		autofs_root_mkdir,
+        rmdir:		autofs_root_rmdir,
 };
 
 static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
diff -u --recursive --new-file v2.3.47/linux/fs/autofs4/autofs_i.h linux/fs/autofs4/autofs_i.h
--- v2.3.47/linux/fs/autofs4/autofs_i.h	Thu Feb 10 17:11:16 2000
+++ linux/fs/autofs4/autofs_i.h	Sat Feb 26 20:54:18 2000
@@ -155,6 +155,8 @@
 extern struct inode_operations autofs4_symlink_inode_operations;
 extern struct inode_operations autofs4_dir_inode_operations;
 extern struct inode_operations autofs4_root_inode_operations;
+extern struct file_operations autofs4_dir_operations;
+extern struct file_operations autofs4_root_operations;
 
 /* Initializing function */
 
diff -u --recursive --new-file v2.3.47/linux/fs/autofs4/inode.c linux/fs/autofs4/inode.c
--- v2.3.47/linux/fs/autofs4/inode.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/autofs4/inode.c	Sat Feb 26 20:33:04 2000
@@ -410,10 +410,13 @@
 
 	if (S_ISDIR(inf->mode)) {
 		inode->i_nlink = 2;
-		if (inode->i_ino == AUTOFS_ROOT_INO)
+		if (inode->i_ino == AUTOFS_ROOT_INO) {
 			inode->i_op = &autofs4_root_inode_operations;
-		else
+			inode->i_fop = &autofs4_root_operations;
+		} else {
 			inode->i_op = &autofs4_dir_inode_operations;
+			inode->i_fop = &autofs4_dir_operations;
+		}
 	} else if (S_ISLNK(inf->mode)) {
 		inode->i_op = &autofs4_symlink_inode_operations;
 	}
diff -u --recursive --new-file v2.3.47/linux/fs/autofs4/root.c linux/fs/autofs4/root.c
--- v2.3.47/linux/fs/autofs4/root.c	Fri Jan 28 15:09:08 2000
+++ linux/fs/autofs4/root.c	Sat Feb 26 20:33:04 2000
@@ -25,33 +25,31 @@
 static int autofs4_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long);
 static struct dentry *autofs4_root_lookup(struct inode *,struct dentry *);
 
-static struct file_operations autofs4_root_operations = {
-	readdir:	autofs4_dir_readdir,	/* readdir */
-	ioctl:		autofs4_root_ioctl,	/* ioctl */
+struct file_operations autofs4_root_operations = {
+	read:		generic_read_dir,
+	readdir:	autofs4_dir_readdir,
+	ioctl:		autofs4_root_ioctl,
 };
 
-struct inode_operations autofs4_root_inode_operations = {
-        &autofs4_root_operations,		/* file operations */
-
-	lookup:		autofs4_root_lookup,	/* lookup */
-	unlink:		autofs4_dir_unlink,      /* unlink */
-	symlink:	autofs4_dir_symlink,     /* symlink */
-	mkdir:		autofs4_dir_mkdir,       /* mkdir */
-	rmdir:		autofs4_dir_rmdir,       /* rmdir */
+struct file_operations autofs4_dir_operations = {
+	read:		generic_read_dir,
+	readdir:	autofs4_dir_readdir,
 };
 
-static struct file_operations autofs4_dir_operations = {
-        readdir:	autofs4_dir_readdir,     /* readdir */
+struct inode_operations autofs4_root_inode_operations = {
+	lookup:		autofs4_root_lookup,
+	unlink:		autofs4_dir_unlink,
+	symlink:	autofs4_dir_symlink,
+	mkdir:		autofs4_dir_mkdir,
+	rmdir:		autofs4_dir_rmdir,
 };
 
 struct inode_operations autofs4_dir_inode_operations = {
-        &autofs4_dir_operations, /* file operations */
-
-	lookup:		autofs4_dir_lookup,	/* lookup */
-        unlink:		autofs4_dir_unlink,      /* unlink */
-        symlink:	autofs4_dir_symlink,     /* symlink */
-        mkdir:		autofs4_dir_mkdir,       /* mkdir */
-        rmdir:		autofs4_dir_rmdir,       /* rmdir */
+	lookup:		autofs4_dir_lookup,
+	unlink:		autofs4_dir_unlink,
+	symlink:	autofs4_dir_symlink,
+	mkdir:		autofs4_dir_mkdir,
+	rmdir:		autofs4_dir_rmdir,
 };
 
 static inline struct dentry *nth_child(struct dentry *dir, int nr)
diff -u --recursive --new-file v2.3.47/linux/fs/bad_inode.c linux/fs/bad_inode.c
--- v2.3.47/linux/fs/bad_inode.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/bad_inode.c	Sat Feb 26 20:33:04 2000
@@ -47,21 +47,20 @@
 
 struct inode_operations bad_inode_ops =
 {
-	&bad_file_ops,		/* default file operations */
-	EIO_ERROR,		/* create */
-	EIO_ERROR,		/* lookup */
-	EIO_ERROR,		/* link */
-	EIO_ERROR,		/* unlink */
-	EIO_ERROR,		/* symlink */
-	EIO_ERROR,		/* mkdir */
-	EIO_ERROR,		/* rmdir */
-	EIO_ERROR,		/* mknod */
-	EIO_ERROR,		/* rename */
-	EIO_ERROR,		/* readlink */
-	bad_follow_link,	/* follow_link */
-	EIO_ERROR,		/* truncate */
-	EIO_ERROR,		/* permission */
-	EIO_ERROR		/* revalidate */
+	create:		EIO_ERROR,
+	lookup:		EIO_ERROR,
+	link:		EIO_ERROR,
+	unlink:		EIO_ERROR,
+	symlink:	EIO_ERROR,
+	mkdir:		EIO_ERROR,
+	rmdir:		EIO_ERROR,
+	mknod:		EIO_ERROR,
+	rename:		EIO_ERROR,
+	readlink:	EIO_ERROR,
+	follow_link:	bad_follow_link,
+	truncate:	EIO_ERROR,
+	permission:	EIO_ERROR,
+	revalidate:	EIO_ERROR,
 };
 
 
@@ -78,6 +77,7 @@
 	inode->i_mode = S_IFREG;
 	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	inode->i_op = &bad_inode_ops;	
+	inode->i_fop = &bad_file_ops;	
 }
 
 /*
diff -u --recursive --new-file v2.3.47/linux/fs/bfs/dir.c linux/fs/bfs/dir.c
--- v2.3.47/linux/fs/bfs/dir.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/bfs/dir.c	Sat Feb 26 20:33:04 2000
@@ -23,11 +23,6 @@
 static struct buffer_head * bfs_find_entry(struct inode * dir, 
 	const char * name, int namelen, struct bfs_dirent ** res_dir);
 
-static ssize_t bfs_dir_read(struct file * f, char * buf, size_t count, loff_t *ppos)
-{
-	return -EISDIR;
-}
-
 static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
 {
 	struct inode * dir = f->f_dentry->d_inode;
@@ -75,10 +70,10 @@
 	return 0;	
 }
 
-static struct file_operations bfs_dir_operations = {
-	read:			bfs_dir_read,
-	readdir:		bfs_readdir,
-	fsync:			file_fsync,
+struct file_operations bfs_dir_operations = {
+	read:		generic_read_dir,
+	readdir:	bfs_readdir,
+	fsync:		file_fsync,
 };
 
 extern void dump_imap(const char *, struct super_block *);
@@ -107,6 +102,7 @@
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	inode->i_blocks = inode->i_blksize = 0;
 	inode->i_op = &bfs_file_inops;
+	inode->i_fop = &bfs_file_operations;
 	inode->i_mapping->a_ops = &bfs_aops;
 	inode->i_mode = mode;
 	inode->i_ino = inode->iu_dsk_ino = ino;
@@ -256,15 +252,10 @@
 }
 
 struct inode_operations bfs_dir_inops = {
-	default_file_ops:	&bfs_dir_operations,
 	create:			bfs_create,
 	lookup:			bfs_lookup,
 	link:			bfs_link,
 	unlink:			bfs_unlink,
-	symlink:		NULL,
-	mkdir:			NULL,
-	rmdir:			NULL,
-	mknod:			NULL,
 	rename:			bfs_rename,
 };
 
diff -u --recursive --new-file v2.3.47/linux/fs/bfs/file.c linux/fs/bfs/file.c
--- v2.3.47/linux/fs/bfs/file.c	Wed Feb 16 17:03:52 2000
+++ linux/fs/bfs/file.c	Sat Feb 26 20:33:04 2000
@@ -18,7 +18,7 @@
 #define dprintf(x...)
 #endif
 
-static struct file_operations bfs_file_operations = {
+struct file_operations bfs_file_operations = {
 	read:	generic_file_read,
 	write:	generic_file_write,
 	mmap:	generic_file_mmap,
@@ -156,5 +156,4 @@
 };
 
 struct inode_operations bfs_file_inops = {
-	default_file_ops:	&bfs_file_operations,
 };
diff -u --recursive --new-file v2.3.47/linux/fs/bfs/inode.c linux/fs/bfs/inode.c
--- v2.3.47/linux/fs/bfs/inode.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/bfs/inode.c	Sat Feb 26 20:33:04 2000
@@ -59,12 +59,13 @@
 	if (di->i_vtype == BFS_VDIR) {
 		inode->i_mode |= S_IFDIR;
 		inode->i_op = &bfs_dir_inops;
+		inode->i_fop = &bfs_dir_operations;
 	} else if (di->i_vtype == BFS_VREG) {
 		inode->i_mode |= S_IFREG;
 		inode->i_op = &bfs_file_inops;
+		inode->i_fop = &bfs_file_operations;
 		inode->i_mapping->a_ops = &bfs_aops;
-	} else 
-		inode->i_op = NULL;
+	}
 
 	inode->i_uid = di->i_uid;
 	inode->i_gid = di->i_gid;
@@ -209,15 +210,10 @@
 static struct super_operations bfs_sops = {
 	read_inode:	bfs_read_inode,
 	write_inode:	bfs_write_inode,
-	put_inode:	NULL,
 	delete_inode:	bfs_delete_inode,
-	notify_change:	NULL,
 	put_super:	bfs_put_super,
 	write_super:	bfs_write_super,
 	statfs:		bfs_statfs,
-	remount_fs:	NULL,
-	clear_inode:	NULL,
-	umount_begin:	NULL
 };
 
 void dump_imap(const char *prefix, struct super_block * s)
@@ -337,7 +333,6 @@
 	name:		"bfs",
 	fs_flags:	FS_REQUIRES_DEV,
 	read_super:	bfs_read_super,
-	next:		NULL
 };
 
 #ifdef MODULE
diff -u --recursive --new-file v2.3.47/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- v2.3.47/linux/fs/binfmt_elf.c	Wed Feb 16 17:03:52 2000
+++ linux/fs/binfmt_elf.c	Sat Feb 26 20:33:04 2000
@@ -225,8 +225,8 @@
 		goto out;
 	if (!elf_check_arch(interp_elf_ex->e_machine))
 		goto out;
-	if (!interpreter_dentry->d_inode->i_op ||
-	    !interpreter_dentry->d_inode->i_op->default_file_ops->mmap)
+	if (!interpreter_dentry->d_inode->i_fop ||
+	    !interpreter_dentry->d_inode->i_fop->mmap)
 		goto out;
 
 	/*
@@ -424,9 +424,7 @@
 		goto out;
 	}
 #endif
-	if (!bprm->dentry->d_inode->i_op		   ||
-	    !bprm->dentry->d_inode->i_op->default_file_ops ||
-	    !bprm->dentry->d_inode->i_op->default_file_ops->mmap)
+	if (!bprm->dentry->d_inode->i_fop||!bprm->dentry->d_inode->i_fop->mmap)
 		goto out;
 
 	/* Now read in all of the header information */
@@ -830,7 +828,7 @@
 	/* First of all, some simple consistency checks */
 	if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
 	   !elf_check_arch(elf_ex.e_machine) ||
-	   (!inode->i_op || !inode->i_op->default_file_ops->mmap))
+	   (!inode->i_fop || !inode->i_fop->mmap))
 		goto out_putf;
 
 	/* Now read in all of the header information */
diff -u --recursive --new-file v2.3.47/linux/fs/binfmt_em86.c linux/fs/binfmt_em86.c
--- v2.3.47/linux/fs/binfmt_em86.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/binfmt_em86.c	Sat Feb 26 20:33:04 2000
@@ -36,9 +36,8 @@
 	/* First of all, some simple consistency checks */
 	if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
 		(!((elf_ex.e_machine == EM_386) || (elf_ex.e_machine == EM_486))) ||
-		(!bprm->dentry->d_inode->i_op || 
-		!bprm->dentry->d_inode->i_op->default_file_ops ||
-		!bprm->dentry->d_inode->i_op->default_file_ops->mmap)) {
+		(!bprm->dentry->d_inode->i_fop || 
+		!bprm->dentry->d_inode->i_fop->mmap)) {
 			return -ENOEXEC;
 	}
 
diff -u --recursive --new-file v2.3.47/linux/fs/block_dev.c linux/fs/block_dev.c
--- v2.3.47/linux/fs/block_dev.c	Wed Feb 16 17:03:52 2000
+++ linux/fs/block_dev.c	Sat Feb 26 20:33:04 2000
@@ -193,7 +193,7 @@
 	if (blk_size[MAJOR(dev)])
 		size = (loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
 	else
-		size = INT_MAX;
+		size = (loff_t) INT_MAX << BLOCK_SIZE_BITS;
 
 	if (offset > size)
 		left = 0;
@@ -670,10 +670,6 @@
 	write:		block_write,
 	fsync:		block_fsync,
 	ioctl:		blkdev_ioctl,
-};
-
-struct inode_operations blkdev_inode_operations = {
-	&def_blk_fops,		/* default file operations */
 };
 
 const char * bdevname(kdev_t dev)
diff -u --recursive --new-file v2.3.47/linux/fs/buffer.c linux/fs/buffer.c
--- v2.3.47/linux/fs/buffer.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/buffer.c	Tue Feb 22 22:31:53 2000
@@ -1532,10 +1532,10 @@
  * mark_buffer_uptodate() functions propagate buffer state into the
  * page struct once IO has completed.
  */
-static inline int __block_read_full_page(struct inode *inode, struct page *page,
-		get_block_t *get_block)
+int block_read_full_page(struct page *page, get_block_t *get_block)
 {
-	unsigned long iblock;
+	struct inode *inode = (struct inode*)page->mapping->host;
+	unsigned long iblock, lblock;
 	struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
 	unsigned int blocksize, blocks;
 	unsigned long kaddr = 0;
@@ -1550,6 +1550,7 @@
 
 	blocks = PAGE_CACHE_SIZE >> inode->i_sb->s_blocksize_bits;
 	iblock = page->index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
+	lblock = (inode->i_size+blocksize-1) >> inode->i_sb->s_blocksize_bits;
 	bh = head;
 	nr = 0;
 	i = 0;
@@ -1559,7 +1560,8 @@
 			continue;
 
 		if (!buffer_mapped(bh)) {
-			get_block(inode, iblock, bh, 0);
+			if (iblock < lblock)
+				get_block(inode, iblock, bh, 0);
 			if (!buffer_mapped(bh)) {
 				if (!kaddr)
 					kaddr = kmap(page);
@@ -1704,13 +1706,30 @@
 int block_write_full_page(struct page *page, get_block_t *get_block)
 {
 	struct inode *inode = (struct inode*)page->mapping->host;
-	return __block_write_full_page(inode, page, get_block);
-}
-
-int block_read_full_page(struct page *page, get_block_t *get_block)
-{
-	struct inode *inode = (struct inode*)page->mapping->host;
-	return __block_read_full_page(inode, page, get_block);
+	unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
+	unsigned offset;
+	int err;
+
+	/* easy case */
+	if (page->index < end_index)
+		return __block_write_full_page(inode, page, get_block);
+
+	/* things got complicated... */
+	offset = inode->i_size & (PAGE_CACHE_SIZE-1);
+	/* OK, are we completely out? */
+	if (page->index >= end_index+1 || !offset)
+		return -EIO;
+	/* Sigh... will have to work, then... */
+	err = __block_prepare_write(inode, page, 0, offset, get_block);
+	if (!err) {
+		memset((char *)page_address(page)+offset, 0, PAGE_CACHE_SIZE-offset);
+		__block_commit_write(inode,page,0,offset);
+done:
+		kunmap(page);
+		return err;
+	}
+	ClearPageUptodate(page);
+	goto done;
 }
 
 int generic_block_bmap(struct address_space *mapping, long block, get_block_t *get_block)
@@ -1735,10 +1754,10 @@
 	mark_buffer_uptodate(bh, uptodate);
 
 	kiobuf = bh->b_kiobuf;
-	if (atomic_dec_and_test(&kiobuf->io_count))
-		kiobuf->end_io(kiobuf);
 	if (!uptodate)
 		kiobuf->errno = -EIO;
+	if (atomic_dec_and_test(&kiobuf->io_count))
+		kiobuf->end_io(kiobuf);
 }
 
 
diff -u --recursive --new-file v2.3.47/linux/fs/coda/cnode.c linux/fs/coda/cnode.c
--- v2.3.47/linux/fs/coda/cnode.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/coda/cnode.c	Sat Feb 26 20:33:42 2000
@@ -25,6 +25,12 @@
 	return 1;
 }
 
+static struct inode_operations coda_symlink_inode_operations = {
+	readlink:	page_readlink,
+	follow_link:	page_follow_link,
+	setattr:	coda_notify_change,
+};
+
 /* cnode.c */
 static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
 {
@@ -35,12 +41,14 @@
 
         coda_vattr_to_iattr(inode, attr);
 
-        if (S_ISREG(inode->i_mode))
+        if (S_ISREG(inode->i_mode)) {
                 inode->i_op = &coda_file_inode_operations;
-        else if (S_ISDIR(inode->i_mode))
+                inode->i_fop = &coda_file_operations;
+        } else if (S_ISDIR(inode->i_mode)) {
                 inode->i_op = &coda_dir_inode_operations;
-        else if (S_ISLNK(inode->i_mode)) {
-		inode->i_op = &page_symlink_inode_operations;
+                inode->i_fop = &coda_dir_operations;
+        } else if (S_ISLNK(inode->i_mode)) {
+		inode->i_op = &coda_symlink_inode_operations;
 		inode->i_data.a_ops = &coda_symlink_aops;
 	} else
                 init_special_inode(inode, inode->i_mode, attr->va_rdev);
@@ -259,6 +267,7 @@
     *inode = iget(sb, CTL_INO);
     if ( *inode ) {
 	(*inode)->i_op = &coda_ioctl_inode_operations;
+	(*inode)->i_fop = &coda_ioctl_operations;
 	(*inode)->i_mode = 00444;
 	error = 0;
     } else { 
diff -u --recursive --new-file v2.3.47/linux/fs/coda/dir.c linux/fs/coda/dir.c
--- v2.3.47/linux/fs/coda/dir.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/coda/dir.c	Sat Feb 26 20:33:42 2000
@@ -65,24 +65,22 @@
 
 struct inode_operations coda_dir_inode_operations =
 {
-	&coda_dir_operations,
-	coda_create,	        /* create */
-	coda_lookup,	        /* lookup */
-	coda_link,	        /* link */
-	coda_unlink,            /* unlink */
-	coda_symlink,	        /* symlink */
-	coda_mkdir,	        /* mkdir */
-	coda_rmdir,   	        /* rmdir */
-	coda_mknod,	        /* mknod */
-	coda_rename,	        /* rename */
-	NULL,	                /* readlink */
-	NULL,	                /* follow_link */
-	NULL,	                /* truncate */
-	coda_permission,        /* permission */
-        coda_revalidate_inode   /* revalidate */
+	create:		coda_create,
+	lookup:		coda_lookup,
+	link:		coda_link,
+	unlink:		coda_unlink,
+	symlink:	coda_symlink,
+	mkdir:		coda_mkdir,
+	rmdir:		coda_rmdir,
+	mknod:		coda_mknod,
+	rename:		coda_rename,
+	permission:	coda_permission,
+        revalidate:	coda_revalidate_inode,
+	setattr:	coda_notify_change,
 };
 
 struct file_operations coda_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	coda_readdir,
 	open:		coda_open,
 	release:	coda_release,
diff -u --recursive --new-file v2.3.47/linux/fs/coda/file.c linux/fs/coda/file.c
--- v2.3.47/linux/fs/coda/file.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/coda/file.c	Sat Feb 26 20:33:42 2000
@@ -33,21 +33,9 @@
 int coda_fsync(struct file *, struct dentry *dentry);
 
 struct inode_operations coda_file_inode_operations = {
-	&coda_file_operations,	/* default file operations */
-	NULL,			/* create */
-	NULL,		        /* lookup */
-	NULL,			/* link */
-	NULL,		        /* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,		        /* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* truncate */
-        coda_permission,        /* permission */
-        coda_revalidate_inode   /* revalidate */
+        permission:	coda_permission,
+        revalidate:	coda_revalidate_inode,
+	setattr:	coda_notify_change,
 };
 
 struct file_operations coda_file_operations = {
@@ -133,7 +121,7 @@
         cont_file->f_flags = coda_file->f_flags;
         atomic_set(&cont_file->f_count, atomic_read(&coda_file->f_count));
         cont_file->f_owner  = coda_file->f_owner;
-	cont_file->f_op = cont_inode->i_op->default_file_ops;
+	cont_file->f_op = cont_inode->i_fop;
 	cont_file->f_dentry = cont_dentry;
         cont_file->f_dentry->d_inode = cont_inode;
         return ;
diff -u --recursive --new-file v2.3.47/linux/fs/coda/inode.c linux/fs/coda/inode.c
--- v2.3.47/linux/fs/coda/inode.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/coda/inode.c	Sat Feb 26 20:33:42 2000
@@ -34,7 +34,6 @@
 /* VFS super_block ops */
 static struct super_block *coda_read_super(struct super_block *, void *, int);
 static void coda_read_inode(struct inode *);
-static int  coda_notify_change(struct dentry *dentry, struct iattr *attr);
 static void coda_put_inode(struct inode *);
 static void coda_delete_inode(struct inode *);
 static void coda_put_super(struct super_block *);
@@ -44,17 +43,11 @@
 /* exported operations */
 struct super_operations coda_super_operations =
 {
-	coda_read_inode,        /* read_inode */
-	NULL,                   /* write_inode */
-	coda_put_inode,	        /* put_inode */
-	coda_delete_inode,      /* delete_inode */
-	coda_notify_change,	/* notify_change */
-	coda_put_super,	        /* put_super */
-	NULL,			/* write_super */
-	coda_statfs,   		/* statfs */
-	NULL,			/* remount_fs */
-	NULL,			/* no clear inode */
-	NULL			/* umount attempt begin */
+	read_inode:	coda_read_inode,
+	put_inode:	coda_put_inode,
+	delete_inode:	coda_delete_inode,
+	put_super:	coda_put_super,
+	statfs:		coda_statfs,
 };
 
 static struct super_block * coda_read_super(struct super_block *sb, 
@@ -213,7 +206,7 @@
 	EXIT;
 }
 
-static int coda_notify_change(struct dentry *de, struct iattr *iattr)
+int coda_notify_change(struct dentry *de, struct iattr *iattr)
 {
 	struct inode *inode = de->d_inode;
         struct coda_inode_info *cii;
diff -u --recursive --new-file v2.3.47/linux/fs/coda/pioctl.c linux/fs/coda/pioctl.c
--- v2.3.47/linux/fs/coda/pioctl.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/coda/pioctl.c	Sat Feb 26 20:33:42 2000
@@ -34,21 +34,8 @@
 /* exported from this file */
 struct inode_operations coda_ioctl_inode_operations =
 {
-	&coda_ioctl_operations,
-	NULL,	                /* create */
-	NULL,	                /* lookup */
-	NULL,	                /* link */
-	NULL,	                /* unlink */
-	NULL,	                /* symlink */
-	NULL,	                /* mkdir */
-	NULL,	                /* rmdir */
-	NULL,		        /* mknod */
-	NULL,		        /* rename */
-	NULL,	                /* readlink */
-	NULL,	                /* follow_link */
-	NULL,	                /* truncate */
-	coda_ioctl_permission,  /* permission */
-        NULL                    /* revalidate */
+	permission:	coda_ioctl_permission,
+	setattr:	coda_notify_change,
 };
 
 struct file_operations coda_ioctl_operations = {
diff -u --recursive --new-file v2.3.47/linux/fs/cramfs/inode.c linux/fs/cramfs/inode.c
--- v2.3.47/linux/fs/cramfs/inode.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/cramfs/inode.c	Sat Feb 26 20:33:05 2000
@@ -23,8 +23,8 @@
 #include "cramfs.h"
 
 static struct super_operations cramfs_ops;
-static struct inode_operations cramfs_file_inode_operations;
 static struct inode_operations cramfs_dir_inode_operations;
+static struct file_operations cramfs_directory_operations;
 static struct address_space_operations cramfs_aops;
 
 /* These two macros may change in future, to provide better st_ino
@@ -52,11 +52,12 @@
 				       without -noleaf option. */
 		insert_inode_hash(inode);
 		if (S_ISREG(inode->i_mode)) {
-			inode->i_op = &cramfs_file_inode_operations;
+			inode->i_fop = &generic_ro_fops;
 			inode->i_data.a_ops = &cramfs_aops;
-		} else if (S_ISDIR(inode->i_mode))
+		} else if (S_ISDIR(inode->i_mode)) {
 			inode->i_op = &cramfs_dir_inode_operations;
-		else if (S_ISLNK(inode->i_mode)) {
+			inode->i_fop = &cramfs_directory_operations;
+		} else if (S_ISLNK(inode->i_mode)) {
 			inode->i_op = &page_symlink_inode_operations;
 			inode->i_data.a_ops = &cramfs_aops;
 		} else {
@@ -352,41 +353,23 @@
 
 /*
  * Our operations:
- *
- * A regular file can be read and mmap'ed.
  */
-static struct file_operations cramfs_file_operations = {
-	read:		generic_file_read,
-	mmap:		generic_file_mmap,
-};
 
 /*
  * A directory can only readdir
  */
 static struct file_operations cramfs_directory_operations = {
+	read:		generic_read_dir,
 	readdir:	cramfs_readdir,
 };
 
-static struct inode_operations cramfs_file_inode_operations = {
-	&cramfs_file_operations,
-};
-
 static struct inode_operations cramfs_dir_inode_operations = {
-	&cramfs_directory_operations,
-	NULL,			/* create */
-	cramfs_lookup,		/* lookup */
+	lookup:		cramfs_lookup,
 };
 
 static struct super_operations cramfs_ops = {
-	NULL,			/* read inode */
-	NULL,			/* write inode */
-	NULL,			/* put inode */
-	NULL,			/* delete inode */
-	NULL,			/* notify change */
-	cramfs_put_super,		/* put super */
-	NULL,			/* write super */
-	cramfs_statfs,		/* statfs */
-	NULL			/* remount */
+	put_super:	cramfs_put_super,
+	statfs:		cramfs_statfs,
 };
 
 static struct file_system_type cramfs_fs_type = {
diff -u --recursive --new-file v2.3.47/linux/fs/devfs/base.c linux/fs/devfs/base.c
--- v2.3.47/linux/fs/devfs/base.c	Wed Feb 16 17:03:52 2000
+++ linux/fs/devfs/base.c	Sat Feb 26 20:33:42 2000
@@ -729,7 +729,6 @@
     return search_for_entry (parent,
 			     curr->u.symlink.linkname, curr->u.symlink.length,
 			     FALSE, FALSE, NULL, TRUE);
-    return curr;
 }   /*  End Function search_for_entry_in_dir  */
 
 static struct devfs_entry *create_entry (struct devfs_entry *parent,
@@ -2185,6 +2184,7 @@
 /*  Superblock operations follow  */
 
 extern struct inode_operations devfs_iops;
+static struct file_operations devfs_fops;
 
 static void devfs_read_inode (struct inode *inode)
 {
@@ -2206,6 +2206,7 @@
     inode->i_blocks = 0;
     inode->i_blksize = 1024;
     inode->i_op = &devfs_iops;
+    inode->i_fop = &devfs_fops;
     inode->i_rdev = NODEV;
     if ( S_ISCHR (di->mode) )
 	inode->i_rdev = MKDEV (di->de->u.fcb.u.device.major,
@@ -2219,7 +2220,7 @@
 	else printk ("%s: read_inode(%d): no block device from bdget()\n",
 		     DEVFS_NAME, (int) inode->i_ino);
     }
-    else if ( S_ISFIFO (di->mode) ) inode->i_op = &fifo_inode_operations;
+    else if ( S_ISFIFO (di->mode) ) inode->i_fop = &def_fifo_fops;
     else if ( S_ISREG (di->mode) ) inode->i_size = di->de->u.fcb.u.file.size;
     inode->i_mode = di->mode;
     inode->i_uid = di->uid;
@@ -2322,7 +2323,6 @@
 { 
     read_inode:    devfs_read_inode,
     write_inode:   devfs_write_inode,
-    notify_change: devfs_notify_change,
     put_super:     devfs_put_super,
     statfs:        devfs_statfs,
 };
@@ -3126,16 +3126,16 @@
 
 static struct inode_operations devfs_iops =
 {
-    default_file_ops: &devfs_fops,
-    lookup:           devfs_lookup,
-    link:             devfs_link,
-    unlink:           devfs_unlink,
-    symlink:          devfs_symlink,
-    mkdir:            devfs_mkdir,
-    rmdir:            devfs_rmdir,
-    mknod:            devfs_mknod,
-    readlink:         devfs_readlink,
-    follow_link:      devfs_follow_link,
+	lookup:		devfs_lookup,
+	link:		devfs_link,
+	unlink:		devfs_unlink,
+	symlink:	devfs_symlink,
+	mkdir:		devfs_mkdir,
+	rmdir:		devfs_rmdir,
+	mknod:		devfs_mknod,
+	readlink:	devfs_readlink,
+	follow_link:	devfs_follow_link,
+	setattr:	devfs_notify_change,
 };
 
 static struct super_block *devfs_read_super (struct super_block *sb,
diff -u --recursive --new-file v2.3.47/linux/fs/devices.c linux/fs/devices.c
--- v2.3.47/linux/fs/devices.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/devices.c	Sat Feb 26 20:33:05 2000
@@ -160,10 +160,6 @@
 	open:		chrdev_open,
 };
 
-static struct inode_operations chrdev_inode_operations = {
-	&def_chr_fops		/* default file operations */
-};
-
 /*
  * Print device name (in decimal, hexadecimal or symbolic)
  * Note: returns pointer to static data!
@@ -189,16 +185,15 @@
 void init_special_inode(struct inode *inode, umode_t mode, int rdev)
 {
 	inode->i_mode = mode;
-	inode->i_op = NULL;
 	if (S_ISCHR(mode)) {
-		inode->i_op = &chrdev_inode_operations;
+		inode->i_fop = &def_chr_fops;
 		inode->i_rdev = to_kdev_t(rdev);
 	} else if (S_ISBLK(mode)) {
-		inode->i_op = &blkdev_inode_operations;
+		inode->i_fop = &def_blk_fops;
 		inode->i_rdev = to_kdev_t(rdev);
 		inode->i_bdev = bdget(rdev);
 	} else if (S_ISFIFO(mode))
-		inode->i_op = &fifo_inode_operations;
+		inode->i_fop = &def_fifo_fops;
 	else if (S_ISSOCK(mode))
 		;
 	else
diff -u --recursive --new-file v2.3.47/linux/fs/devpts/devpts_i.h linux/fs/devpts/devpts_i.h
--- v2.3.47/linux/fs/devpts/devpts_i.h	Wed Aug 18 16:44:26 1999
+++ linux/fs/devpts/devpts_i.h	Sat Feb 26 20:47:21 2000
@@ -40,4 +40,4 @@
 }
 
 extern struct inode_operations devpts_root_inode_operations;
-extern struct inode_operations devpts_device_inode_operations;
+extern struct file_operations devpts_root_operations;
diff -u --recursive --new-file v2.3.47/linux/fs/devpts/inode.c linux/fs/devpts/inode.c
--- v2.3.47/linux/fs/devpts/inode.c	Tue Jan  4 13:57:17 2000
+++ linux/fs/devpts/inode.c	Sat Feb 26 20:33:05 2000
@@ -62,16 +62,10 @@
 static void devpts_write_inode(struct inode *inode);
 
 static struct super_operations devpts_sops = {
-	devpts_read_inode,
-	devpts_write_inode,
-	NULL,			/* put_inode */
-	NULL,			/* delete_inode */
-	NULL,			/* notify_change */
-	devpts_put_super,
-	NULL,			/* write_super */
-	devpts_statfs,
-	NULL,			/* remount_fs */
-	NULL,			/* clear_inode */
+	read_inode:	devpts_read_inode,
+	write_inode:	devpts_write_inode,
+	put_super:	devpts_put_super,
+	statfs:		devpts_statfs,
 };
 
 static int devpts_parse_options(char *options, struct devpts_sb_info *sbi)
@@ -264,7 +258,6 @@
 	ino_t ino = inode->i_ino;
 	struct devpts_sb_info *sbi = SBI(inode->i_sb);
 
-	inode->i_op = NULL;
 	inode->i_mode = 0;
 	inode->i_nlink = 0;
 	inode->i_size = 0;
@@ -276,6 +269,7 @@
 	if ( ino == 1 ) {
 		inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
 		inode->i_op = &devpts_root_inode_operations;
+		inode->i_fop = &devpts_root_operations;
 		inode->i_nlink = 2;
 		return;
 	} 
diff -u --recursive --new-file v2.3.47/linux/fs/devpts/root.c linux/fs/devpts/root.c
--- v2.3.47/linux/fs/devpts/root.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/devpts/root.c	Sat Feb 26 20:33:05 2000
@@ -20,14 +20,13 @@
 static struct dentry *devpts_root_lookup(struct inode *,struct dentry *);
 static int devpts_revalidate(struct dentry *, int);
 
-static struct file_operations devpts_root_operations = {
+struct file_operations devpts_root_operations = {
+	read:		generic_read_dir,
 	readdir:	devpts_root_readdir,
 };
 
 struct inode_operations devpts_root_inode_operations = {
-	&devpts_root_operations, /* file operations */
-	NULL,                   /* create */
-	devpts_root_lookup,     /* lookup */
+	lookup:		devpts_root_lookup,
 };
 
 static struct dentry_operations devpts_dentry_operations = {
diff -u --recursive --new-file v2.3.47/linux/fs/efs/dir.c linux/fs/efs/dir.c
--- v2.3.47/linux/fs/efs/dir.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/efs/dir.c	Sat Feb 26 20:33:05 2000
@@ -8,14 +8,13 @@
 
 static int efs_readdir(struct file *, void *, filldir_t);
 
-static struct file_operations efs_dir_operations = {
+struct file_operations efs_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	efs_readdir,
 };
 
 struct inode_operations efs_dir_inode_operations = {
-	&efs_dir_operations,	/* default directory file-ops */
-	NULL,			/* create */
-	efs_lookup,		/* lookup */
+	lookup:		efs_lookup,
 };
 
 static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) {
diff -u --recursive --new-file v2.3.47/linux/fs/efs/file.c linux/fs/efs/file.c
--- v2.3.47/linux/fs/efs/file.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/efs/file.c	Sat Feb 26 20:33:05 2000
@@ -60,12 +60,3 @@
 
 	return efs_map_block(inode, block);
 }
-
-static struct file_operations efs_file_operations = {
-	read:		generic_file_read,
-	mmap:		generic_file_mmap,
-};
-
-struct inode_operations efs_file_inode_operations = {
-	&efs_file_operations,	/* default file operations */
-};
diff -u --recursive --new-file v2.3.47/linux/fs/efs/inode.c linux/fs/efs/inode.c
--- v2.3.47/linux/fs/efs/inode.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/efs/inode.c	Sat Feb 26 20:33:05 2000
@@ -137,9 +137,10 @@
 	switch (inode->i_mode & S_IFMT) {
 		case S_IFDIR: 
 			inode->i_op = &efs_dir_inode_operations; 
+			inode->i_fop = &efs_dir_operations; 
 			break;
 		case S_IFREG:
-			inode->i_op = &efs_file_inode_operations;
+			inode->i_fop = &generic_ro_fops;
 			inode->i_data.a_ops = &efs_aops;
 			break;
 		case S_IFLNK:
@@ -161,16 +162,7 @@
         
 read_inode_error:
 	printk(KERN_WARNING "EFS: failed to read inode %lu\n", inode->i_ino);
-	inode->i_mode = S_IFREG;
-	inode->i_atime = 0;
-	inode->i_ctime = 0;
-	inode->i_mtime = 0;
-	inode->i_nlink = 1;
-	inode->i_size = 0;
-	inode->i_blocks = 0;
-	inode->i_uid = 0;
-	inode->i_gid = 0;
-	inode->i_op = NULL;
+	make_bad_inode(inode);
 
 	return;
 }
diff -u --recursive --new-file v2.3.47/linux/fs/efs/super.c linux/fs/efs/super.c
--- v2.3.47/linux/fs/efs/super.c	Tue Aug 31 17:29:14 1999
+++ linux/fs/efs/super.c	Sat Feb 26 20:33:05 2000
@@ -21,15 +21,9 @@
 };
 
 static struct super_operations efs_superblock_operations = {
-	efs_read_inode,	/* read_inode */
-	NULL,		/* write_inode */
-	NULL,		/* put_inode */
-	NULL,		/* delete_inode */
-	NULL,		/* notify_change */
-	efs_put_super,	/* put_super */
-	NULL,		/* write_super */
-	efs_statfs,	/* statfs */
-	NULL		/* remount */
+	read_inode:	efs_read_inode,
+	put_super:	efs_put_super,
+	statfs:		efs_statfs,
 };
 
 int __init init_efs_fs(void) {
diff -u --recursive --new-file v2.3.47/linux/fs/exec.c linux/fs/exec.c
--- v2.3.47/linux/fs/exec.c	Thu Feb 10 17:11:16 2000
+++ linux/fs/exec.c	Sat Feb 26 20:33:05 2000
@@ -88,7 +88,7 @@
 		l = &inode->i_sb->s_files;
 
 	error = -EINVAL;
-	if (!inode->i_op || !inode->i_op->default_file_ops)
+	if (!inode->i_fop)
 		goto out;
 	fd = get_unused_fd();
 	if (fd >= 0) {
@@ -101,7 +101,7 @@
 		f->f_dentry = dentry;
 		f->f_pos = 0;
 		f->f_reada = 0;
-		f->f_op = inode->i_op->default_file_ops;
+		f->f_op = inode->i_fop;
 		if (f->f_op->open) {
 			error = f->f_op->open(inode,f);
 			if (error)
@@ -352,7 +352,7 @@
 	struct inode * inode = dentry->d_inode;
 	int result = -ENOEXEC;
 
-	if (!inode->i_op || !inode->i_op->default_file_ops)
+	if (!inode->i_fop)
 		goto end_readexec;
 	if (init_private_file(&file, dentry, 1))
 		goto end_readexec;
@@ -900,7 +900,7 @@
 
 	if (!S_ISREG(inode->i_mode))
 		goto close_fail;
-	if (!inode->i_op || !inode->i_op->default_file_ops)
+	if (!inode->i_fop)
 		goto close_fail;
 	if (!file->f_op->write)
 		goto close_fail;
diff -u --recursive --new-file v2.3.47/linux/fs/ext2/dir.c linux/fs/ext2/dir.c
--- v2.3.47/linux/fs/ext2/dir.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/ext2/dir.c	Sat Feb 26 20:33:05 2000
@@ -20,37 +20,13 @@
 
 #include <linux/fs.h>
 
-
-
-static ssize_t ext2_dir_read (struct file * filp, char * buf,
-			      size_t count, loff_t *ppos)
-{
-	return -EISDIR;
-}
-
 static int ext2_readdir(struct file *, void *, filldir_t);
 
-static struct file_operations ext2_dir_operations = {
-	read:		ext2_dir_read,
+struct file_operations ext2_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	ext2_readdir,
 	ioctl:		ext2_ioctl,
 	fsync:		ext2_sync_file,
-};
-
-/*
- * directories can handle most operations...
- */
-struct inode_operations ext2_dir_inode_operations = {
-	&ext2_dir_operations,	/* default directory file-ops */
-	ext2_create,		/* create */
-	ext2_lookup,		/* lookup */
-	ext2_link,		/* link */
-	ext2_unlink,		/* unlink */
-	ext2_symlink,		/* symlink */
-	ext2_mkdir,		/* mkdir */
-	ext2_rmdir,		/* rmdir */
-	ext2_mknod,		/* mknod */
-	ext2_rename,		/* rename */
 };
 
 int ext2_check_dir_entry (const char * function, struct inode * dir,
diff -u --recursive --new-file v2.3.47/linux/fs/ext2/file.c linux/fs/ext2/file.c
--- v2.3.47/linux/fs/ext2/file.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/ext2/file.c	Sat Feb 26 20:33:05 2000
@@ -95,7 +95,7 @@
  * We have mostly NULL's here: the current defaults are ok for
  * the ext2 filesystem.
  */
-static struct file_operations ext2_file_operations = {
+struct file_operations ext2_file_operations = {
 	llseek:		ext2_file_lseek,
 	read:		generic_file_read,
 	write:		generic_file_write,
@@ -107,6 +107,5 @@
 };
 
 struct inode_operations ext2_file_inode_operations = {
-	&ext2_file_operations,
 	truncate:	ext2_truncate,
 };
diff -u --recursive --new-file v2.3.47/linux/fs/ext2/ialloc.c linux/fs/ext2/ialloc.c
--- v2.3.47/linux/fs/ext2/ialloc.c	Tue Dec 14 01:27:24 1999
+++ linux/fs/ext2/ialloc.c	Sat Feb 26 20:33:05 2000
@@ -469,7 +469,6 @@
 	inode->u.ext2_i.i_dir_acl = 0;
 	inode->u.ext2_i.i_dtime = 0;
 	inode->u.ext2_i.i_block_group = i;
-	inode->i_op = NULL;
 	if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)
 		inode->i_flags |= MS_SYNCHRONOUS;
 	insert_inode_hash(inode);
diff -u --recursive --new-file v2.3.47/linux/fs/ext2/inode.c linux/fs/ext2/inode.c
--- v2.3.47/linux/fs/ext2/inode.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/ext2/inode.c	Sat Feb 26 20:33:06 2000
@@ -50,7 +50,7 @@
 	if (is_bad_inode(inode) ||
 	    inode->i_ino == EXT2_ACL_IDX_INO ||
 	    inode->i_ino == EXT2_ACL_DATA_INO)
-		return;
+		goto no_delete;
 	inode->u.ext2_i.i_dtime	= CURRENT_TIME;
 	mark_inode_dirty(inode);
 	ext2_update_inode(inode, IS_SYNC(inode));
@@ -60,6 +60,10 @@
 	ext2_free_inode (inode);
 
 	unlock_kernel();
+	return;
+no_delete:
+	clear_inode(inode);	/* We must guarantee clearing of inode... */
+	unlock_kernel();
 }
 
 #define inode_bmap(inode, nr) (le32_to_cpu((inode)->u.ext2_i.i_data[(nr)]))
@@ -751,10 +755,12 @@
 		/* Nothing to do */ ;
 	else if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &ext2_file_inode_operations;
+		inode->i_fop = &ext2_file_operations;
 		inode->i_mapping->a_ops = &ext2_aops;
-	} else if (S_ISDIR(inode->i_mode))
+	} else if (S_ISDIR(inode->i_mode)) {
 		inode->i_op = &ext2_dir_inode_operations;
-	else if (S_ISLNK(inode->i_mode)) {
+		inode->i_fop = &ext2_dir_operations;
+	} else if (S_ISLNK(inode->i_mode)) {
 		if (!inode->i_blocks)
 			inode->i_op = &ext2_fast_symlink_inode_operations;
 		else {
diff -u --recursive --new-file v2.3.47/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
--- v2.3.47/linux/fs/ext2/namei.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/ext2/namei.c	Sat Feb 26 20:33:06 2000
@@ -159,7 +159,7 @@
 	return NULL;
 }
 
-struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry)
+static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry)
 {
 	struct inode * inode;
 	struct ext2_dir_entry_2 * de;
@@ -369,7 +369,7 @@
  * If the create succeeds, we fill in the inode information
  * with d_instantiate(). 
  */
-int ext2_create (struct inode * dir, struct dentry * dentry, int mode)
+static int ext2_create (struct inode * dir, struct dentry * dentry, int mode)
 {
 	struct inode * inode;
 	struct buffer_head * bh;
@@ -384,6 +384,7 @@
 		return err;
 
 	inode->i_op = &ext2_file_inode_operations;
+	inode->i_fop = &ext2_file_operations;
 	inode->i_mapping->a_ops = &ext2_aops;
 	inode->i_mode = mode;
 	mark_inode_dirty(inode);
@@ -407,7 +408,7 @@
 	return 0;
 }
 
-int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
+static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
 {
 	struct inode * inode;
 	struct buffer_head * bh;
@@ -445,7 +446,7 @@
 	goto out;
 }
 
-int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
 {
 	struct inode * inode;
 	struct buffer_head * bh, * dir_block;
@@ -462,6 +463,7 @@
 		goto out;
 
 	inode->i_op = &ext2_dir_inode_operations;
+	inode->i_fop = &ext2_dir_operations;
 	inode->i_size = inode->i_sb->s_blocksize;
 	inode->i_blocks = 0;	
 	dir_block = ext2_bread (inode, 0, 1, &err);
@@ -579,7 +581,7 @@
 	return 1;
 }
 
-int ext2_rmdir (struct inode * dir, struct dentry *dentry)
+static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
 {
 	int retval;
 	struct inode * inode;
@@ -630,7 +632,7 @@
 	return retval;
 }
 
-int ext2_unlink(struct inode * dir, struct dentry *dentry)
+static int ext2_unlink(struct inode * dir, struct dentry *dentry)
 {
 	int retval;
 	struct inode * inode;
@@ -678,7 +680,7 @@
 	return retval;
 }
 
-int ext2_symlink (struct inode * dir, struct dentry *dentry, const char * symname)
+static int ext2_symlink (struct inode * dir, struct dentry *dentry, const char * symname)
 {
 	struct inode * inode;
 	struct ext2_dir_entry_2 * de;
@@ -733,7 +735,7 @@
 	goto out;
 }
 
-int ext2_link (struct dentry * old_dentry,
+static int ext2_link (struct dentry * old_dentry,
 		struct inode * dir, struct dentry *dentry)
 {
 	struct inode *inode = old_dentry->d_inode;
@@ -776,7 +778,7 @@
  * Anybody can rename anything with this: the permission checks are left to the
  * higher-level routines.
  */
-int ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
+static int ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
 			   struct inode * new_dir,struct dentry *new_dentry)
 {
 	struct inode * old_inode, * new_inode;
@@ -894,3 +896,18 @@
 	brelse (new_bh);
 	return retval;
 }
+
+/*
+ * directories can handle most operations...
+ */
+struct inode_operations ext2_dir_inode_operations = {
+	create:		ext2_create,
+	lookup:		ext2_lookup,
+	link:		ext2_link,
+	unlink:		ext2_unlink,
+	symlink:	ext2_symlink,
+	mkdir:		ext2_mkdir,
+	rmdir:		ext2_rmdir,
+	mknod:		ext2_mknod,
+	rename:		ext2_rename,
+};
diff -u --recursive --new-file v2.3.47/linux/fs/ext2/super.c linux/fs/ext2/super.c
--- v2.3.47/linux/fs/ext2/super.c	Tue Jan 11 22:31:43 2000
+++ linux/fs/ext2/super.c	Sat Feb 26 20:33:06 2000
@@ -121,15 +121,14 @@
 }
 
 static struct super_operations ext2_sops = {
-	ext2_read_inode,
-	ext2_write_inode,
-	ext2_put_inode,
-	ext2_delete_inode,
-	NULL,
-	ext2_put_super,
-	ext2_write_super,
-	ext2_statfs,
-	ext2_remount
+	read_inode:	ext2_read_inode,
+	write_inode:	ext2_write_inode,
+	put_inode:	ext2_put_inode,
+	delete_inode:	ext2_delete_inode,
+	put_super:	ext2_put_super,
+	write_super:	ext2_write_super,
+	statfs:		ext2_statfs,
+	remount_fs:	ext2_remount,
 };
 
 /*
diff -u --recursive --new-file v2.3.47/linux/fs/fat/dir.c linux/fs/fat/dir.c
--- v2.3.47/linux/fs/fat/dir.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/fat/dir.c	Sat Feb 26 20:33:06 2000
@@ -34,14 +34,8 @@
 
 #define PRINTK(X)
 
-static ssize_t fat_dir_read(struct file * filp, char * buf,
-			    size_t count, loff_t *ppos)
-{
-	return -EISDIR;
-}
-
 struct file_operations fat_dir_operations = {
-	read:		fat_dir_read,
+	read:		generic_read_dir,
 	readdir:	fat_readdir,
 	ioctl:		fat_dir_ioctl,
 	fsync:		file_fsync,
diff -u --recursive --new-file v2.3.47/linux/fs/fat/fatfs_syms.c linux/fs/fat/fatfs_syms.c
--- v2.3.47/linux/fs/fat/fatfs_syms.c	Wed Oct 27 16:34:12 1999
+++ linux/fs/fat/fatfs_syms.c	Sat Feb 26 20:33:06 2000
@@ -15,8 +15,6 @@
 #include "msbuffer.h"
 #include "tables.h"
 
-extern struct file_operations fat_dir_operations;
-
 EXPORT_SYMBOL(fat_new_dir);
 EXPORT_SYMBOL(fat_bmap);
 EXPORT_SYMBOL(fat_get_block);
@@ -25,7 +23,6 @@
 EXPORT_SYMBOL(fat_clear_inode);
 EXPORT_SYMBOL(fat_date_unix2dos);
 EXPORT_SYMBOL(fat_delete_inode);
-EXPORT_SYMBOL(fat_dir_operations);
 EXPORT_SYMBOL(fat_esc2uni);
 EXPORT_SYMBOL(fat_file_read);
 EXPORT_SYMBOL(fat_file_write);
diff -u --recursive --new-file v2.3.47/linux/fs/fat/file.c linux/fs/fat/file.c
--- v2.3.47/linux/fs/fat/file.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/fat/file.c	Sat Feb 26 20:33:42 2000
@@ -30,7 +30,7 @@
 #define PRINTK(x)
 #define Printk(x) printk x
 
-static struct file_operations fat_file_operations = {
+struct file_operations fat_file_operations = {
 	read:		fat_file_read,
 	write:		fat_file_write,
 	mmap:		generic_file_mmap,
@@ -38,19 +38,8 @@
 };
 
 struct inode_operations fat_file_inode_operations = {
-	&fat_file_operations,	/* default file operations */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	fat_truncate,		/* truncate */
+	truncate:	fat_truncate,
+	setattr:	fat_notify_change,
 };
 
 ssize_t fat_file_read(
diff -u --recursive --new-file v2.3.47/linux/fs/fat/inode.c linux/fs/fat/inode.c
--- v2.3.47/linux/fs/fat/inode.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/fat/inode.c	Sat Feb 26 20:33:42 2000
@@ -375,6 +375,7 @@
 	inode->i_version = ++event;
 	inode->i_mode = (S_IRWXUGO & ~sbi->options.fs_umask) | S_IFDIR;
 	inode->i_op = sbi->dir_ops;
+	inode->i_fop = &fat_dir_operations;
 	if (sbi->fat_bits == 32) {
 		MSDOS_I(inode)->i_start = sbi->root_cluster;
 		if ((nr = MSDOS_I(inode)->i_start) != 0) {
@@ -406,16 +407,11 @@
 }
 
 static struct super_operations fat_sops = { 
-	NULL,
-	fat_write_inode,
-	NULL,
-	fat_delete_inode,
-	fat_notify_change,
-	fat_put_super,
-	NULL,		/* write_super */
-	fat_statfs,
-	NULL,		/* remount */
-	fat_clear_inode
+	write_inode:	fat_write_inode,
+	delete_inode:	fat_delete_inode,
+	put_super:	fat_put_super,
+	statfs:		fat_statfs,
+	clear_inode:	fat_clear_inode,
 };
 
 /*
@@ -788,6 +784,7 @@
 		inode->i_mode = MSDOS_MKMODE(de->attr,S_IRWXUGO &
 		    ~sbi->options.fs_umask) | S_IFDIR;
 		inode->i_op = sbi->dir_ops;
+		inode->i_fop = &fat_dir_operations;
 
 		MSDOS_I(inode)->i_start = CF_LE_W(de->start);
 		if (sbi->fat_bits == 32) {
@@ -830,6 +827,7 @@
 		inode->i_nlink = 1;
 		inode->i_size = CF_LE_L(de->size);
 	        inode->i_op = &fat_file_inode_operations;
+	        inode->i_fop = &fat_file_operations;
 		inode->i_mapping->a_ops = &fat_aops;
 		MSDOS_I(inode)->mmu_private = inode->i_size;
 	}
diff -u --recursive --new-file v2.3.47/linux/fs/fcntl.c linux/fs/fcntl.c
--- v2.3.47/linux/fs/fcntl.c	Mon Oct 11 15:38:15 1999
+++ linux/fs/fcntl.c	Sat Feb 26 20:46:44 2000
@@ -259,7 +259,7 @@
 
 /* Table to convert sigio signal codes into poll band bitmaps */
 
-static int band_table[NSIGPOLL+1] = {
+static long band_table[NSIGPOLL+1] = {
 	~0,
 	POLLIN | POLLRDNORM,			/* POLL_IN */
 	POLLOUT | POLLWRNORM | POLLWRBAND,	/* POLL_OUT */
@@ -291,7 +291,7 @@
 			si.si_errno = 0;
 		        si.si_code  = reason;
 			if (reason < 0 || reason > NSIGPOLL)
-				si.si_band  = ~0;
+				si.si_band  = ~0L;
 			else
 				si.si_band = band_table[reason];
 			si.si_fd    = fa->fa_fd;
diff -u --recursive --new-file v2.3.47/linux/fs/fifo.c linux/fs/fifo.c
--- v2.3.47/linux/fs/fifo.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/fifo.c	Sat Feb 26 20:33:06 2000
@@ -152,10 +152,6 @@
  * is contain the open that then fills in the correct operations
  * depending on the access mode of the file...
  */
-static struct file_operations def_fifo_fops = {
+struct file_operations def_fifo_fops = {
 	open:		fifo_open,	/* will set read or write pipe_fops */
-};
-
-struct inode_operations fifo_inode_operations = {
-	&def_fifo_fops,		/* default file operations */
 };
diff -u --recursive --new-file v2.3.47/linux/fs/file_table.c linux/fs/file_table.c
--- v2.3.47/linux/fs/file_table.c	Wed Jul 14 13:30:36 1999
+++ linux/fs/file_table.c	Sat Feb 26 20:33:06 2000
@@ -99,7 +99,7 @@
 /*
  * Clear and initialize a (private) struct file for the given dentry,
  * and call the open function (if any).  The caller must verify that
- * inode->i_op and inode->i_op->default_file_ops are not NULL.
+ * inode->i_fop is not NULL.
  */
 int init_private_file(struct file *filp, struct dentry *dentry, int mode)
 {
@@ -109,7 +109,7 @@
 	filp->f_dentry = dentry;
 	filp->f_uid    = current->fsuid;
 	filp->f_gid    = current->fsgid;
-	filp->f_op     = dentry->d_inode->i_op->default_file_ops;
+	filp->f_op     = dentry->d_inode->i_fop;
 	if (filp->f_op->open)
 		return filp->f_op->open(dentry->d_inode, filp);
 	else
diff -u --recursive --new-file v2.3.47/linux/fs/hfs/dir.c linux/fs/hfs/dir.c
--- v2.3.47/linux/fs/hfs/dir.c	Tue May 11 23:01:41 1999
+++ linux/fs/hfs/dir.c	Sat Feb 26 20:33:06 2000
@@ -157,19 +157,6 @@
 /*================ Global functions ================*/
 
 /*
- * hfs_dir_read()
- *
- * This is the read() entry in the file_operations structure for HFS
- * directories.	 It simply returns an error code, since reading is not
- * supported.
- */
-hfs_rwret_t hfs_dir_read(struct file * filp, char *buf,
-			 hfs_rwarg_t count, loff_t *ppos)
-{
-	return -EISDIR;
-}
-
-/*
  * hfs_create()
  *
  * This is the create() entry in the inode_operations structure for
diff -u --recursive --new-file v2.3.47/linux/fs/hfs/dir_cap.c linux/fs/hfs/dir_cap.c
--- v2.3.47/linux/fs/hfs/dir_cap.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/hfs/dir_cap.c	Sat Feb 26 20:33:42 2000
@@ -57,35 +57,31 @@
 #define DOT_FINDERINFO	(&hfs_cap_reserved1[3])
 #define DOT_ROOTINFO	(&hfs_cap_reserved2[0])
 
-static struct file_operations hfs_cap_dir_operations = {
-	read:		hfs_dir_read,
+struct file_operations hfs_cap_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	cap_readdir,
 	fsync:		file_fsync,
 };
 
 struct inode_operations hfs_cap_ndir_inode_operations = {
-	&hfs_cap_dir_operations,/* default directory file-ops */
-	hfs_create,		/* create */
-	cap_lookup,		/* lookup */
-	NULL,			/* link */
-	hfs_unlink,		/* unlink */
-	NULL,			/* symlink */
-	hfs_mkdir,		/* mkdir */
-	hfs_rmdir,		/* rmdir */
-	NULL,			/* mknod */
-	hfs_rename,		/* rename */
+	create:		hfs_create,
+	lookup:		cap_lookup,
+	unlink:		hfs_unlink,
+	mkdir:		hfs_mkdir,
+	rmdir:		hfs_rmdir,
+	rename:		hfs_rename,
+	setattr:	hfs_notify_change,
 };
 
 struct inode_operations hfs_cap_fdir_inode_operations = {
-	&hfs_cap_dir_operations,/* default directory file-ops */
-	NULL,			/* create */
-	cap_lookup,		/* lookup */
+	lookup:		cap_lookup,
+	setattr:	hfs_notify_change,
 };
 
 struct inode_operations hfs_cap_rdir_inode_operations = {
-	&hfs_cap_dir_operations,/* default directory file-ops */
-	hfs_create,		/* create */
-	cap_lookup,		/* lookup */
+	create:		hfs_create,
+	lookup:		cap_lookup,
+	setattr:	hfs_notify_change,
 };
 
 /*================ File-local functions ================*/
diff -u --recursive --new-file v2.3.47/linux/fs/hfs/dir_dbl.c linux/fs/hfs/dir_dbl.c
--- v2.3.47/linux/fs/hfs/dir_dbl.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/hfs/dir_dbl.c	Sat Feb 26 20:33:42 2000
@@ -56,23 +56,20 @@
 #define ROOTINFO	(&hfs_dbl_reserved2[0])
 #define PCNT_ROOTINFO	(&hfs_dbl_reserved2[1])
 
-static struct file_operations hfs_dbl_dir_operations = {
-	read:		hfs_dir_read,
+struct file_operations hfs_dbl_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	dbl_readdir,
 	fsync:		file_fsync,
 };
 
 struct inode_operations hfs_dbl_dir_inode_operations = {
-	&hfs_dbl_dir_operations,/* default directory file-ops */
-	dbl_create,		/* create */
-	dbl_lookup,		/* lookup */
-	NULL,			/* link */
-	dbl_unlink,		/* unlink */
-	NULL,			/* symlink */
-	dbl_mkdir,		/* mkdir */
-	dbl_rmdir,		/* rmdir */
-	NULL,			/* mknod */
-	dbl_rename,		/* rename */
+	create:		dbl_create,
+	lookup:		dbl_lookup,
+	unlink:		dbl_unlink,
+	mkdir:		dbl_mkdir,
+	rmdir:		dbl_rmdir,
+	rename:		dbl_rename,
+	setattr:	hfs_notify_change,
 };
 
 
diff -u --recursive --new-file v2.3.47/linux/fs/hfs/dir_nat.c linux/fs/hfs/dir_nat.c
--- v2.3.47/linux/fs/hfs/dir_nat.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/hfs/dir_nat.c	Sat Feb 26 20:33:42 2000
@@ -62,36 +62,28 @@
 #define DOT_PARENT	(&hfs_nat_reserved1[3])
 #define ROOTINFO        (&hfs_nat_reserved2[0])
 
-static struct file_operations hfs_nat_dir_operations = {
-	read:		hfs_dir_read,
+struct file_operations hfs_nat_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	nat_readdir,
 	fsync:		file_fsync,
 };
 
 struct inode_operations hfs_nat_ndir_inode_operations = {
-	&hfs_nat_dir_operations,/* default directory file-ops */
-	hfs_create,		/* create */
-	nat_lookup,		/* lookup */
-	NULL,			/* link */
-	hfs_unlink,		/* unlink */
-	NULL,			/* symlink */
-	hfs_mkdir,		/* mkdir */
-	nat_rmdir,		/* rmdir */
-	NULL,			/* mknod */
-	hfs_rename,		/* rename */
+	create:		hfs_create,
+	lookup:		nat_lookup,
+	unlink:		hfs_unlink,
+	mkdir:		hfs_mkdir,
+	rmdir:		nat_rmdir,
+	rename:		hfs_rename,
+	setattr:	hfs_notify_change,
 };
 
 struct inode_operations hfs_nat_hdir_inode_operations = {
-	&hfs_nat_dir_operations,/* default directory file-ops */
-	hfs_create,		/* create */
-	nat_lookup,		/* lookup */
-	NULL,			/* link */
-	nat_hdr_unlink,		/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	nat_hdr_rename,		/* rename */
+	create:		hfs_create,
+	lookup:		nat_lookup,
+	unlink:		nat_hdr_unlink,
+	rename:		nat_hdr_rename,
+	setattr:	hfs_notify_change,
 };
 
 /*================ File-local functions ================*/
diff -u --recursive --new-file v2.3.47/linux/fs/hfs/file.c linux/fs/hfs/file.c
--- v2.3.47/linux/fs/hfs/file.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/hfs/file.c	Sat Feb 26 20:33:42 2000
@@ -31,7 +31,7 @@
 
 /*================ Global variables ================*/
 
-static struct file_operations hfs_file_operations = {
+struct file_operations hfs_file_operations = {
 	read:		hfs_file_read,
 	write:		hfs_file_write,
 	mmap:		generic_file_mmap,
@@ -39,19 +39,8 @@
 };
 
 struct inode_operations hfs_file_inode_operations = {
-	&hfs_file_operations,	/* default file operations */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	hfs_file_truncate,	/* truncate */
+	truncate:	hfs_file_truncate,
+	setattr:	hfs_notify_change,
 };
 
 /*================ Variable-like macros ================*/
diff -u --recursive --new-file v2.3.47/linux/fs/hfs/file_cap.c linux/fs/hfs/file_cap.c
--- v2.3.47/linux/fs/hfs/file_cap.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/hfs/file_cap.c	Sat Feb 26 20:33:42 2000
@@ -31,8 +31,6 @@
 				 hfs_rwarg_t, loff_t *);
 static hfs_rwret_t cap_info_write(struct file *, const char *,
 				  hfs_rwarg_t, loff_t *);
-static void cap_info_truncate(struct inode *);
-
 /*================ Function-like macros ================*/
 
 /*
@@ -46,26 +44,14 @@
 
 /*================ Global variables ================*/
 
-static struct file_operations hfs_cap_info_operations = {
+struct file_operations hfs_cap_info_operations = {
 	read:		cap_info_read,
 	write:		cap_info_write,
 	fsync:		file_fsync,
 };
 
 struct inode_operations hfs_cap_info_inode_operations = {
-	&hfs_cap_info_operations,	/* default file operations */
-	NULL,				/* create */
-	NULL,				/* lookup */
-	NULL,				/* link */
-	NULL,				/* unlink */
-	NULL,				/* symlink */
-	NULL,				/* mkdir */
-	NULL,				/* rmdir */
-	NULL,				/* mknod */
-	NULL,				/* rename */
-	NULL,				/* readlink */
-	NULL,				/* follow_link */
-	cap_info_truncate,		/* truncate */
+	setattr:	hfs_notify_change_cap,
 };
 
 /*================ File-local functions ================*/
@@ -264,18 +250,4 @@
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	mark_inode_dirty(inode);
 	return count;
-}
-
-/*
- * cap_info_truncate()
- *
- * This is the truncate field in the inode_operations structure for
- * CAP metadata files.
- */
-static void cap_info_truncate(struct inode *inode)
-{
-	if (inode->i_size > HFS_FORK_MAX) {
-		inode->i_size = HFS_FORK_MAX;
-		mark_inode_dirty(inode);
-	}
 }
diff -u --recursive --new-file v2.3.47/linux/fs/hfs/file_hdr.c linux/fs/hfs/file_hdr.c
--- v2.3.47/linux/fs/hfs/file_hdr.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/hfs/file_hdr.c	Sat Feb 26 20:33:42 2000
@@ -43,30 +43,16 @@
 static hfs_rwret_t hdr_read(struct file *, char *, hfs_rwarg_t, loff_t *);
 static hfs_rwret_t hdr_write(struct file *, const char *,
 			     hfs_rwarg_t, loff_t *);
-static void hdr_truncate(struct inode *);
-
 /*================ Global variables ================*/
 
-static struct file_operations hfs_hdr_operations = {
+struct file_operations hfs_hdr_operations = {
 	read:		hdr_read,
 	write:		hdr_write,
 	fsync:		file_fsync,
 };
 
 struct inode_operations hfs_hdr_inode_operations = {
-	&hfs_hdr_operations,	/* default file operations */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	hdr_truncate,		/* truncate */
+	setattr:	hfs_notify_change_hdr,
 };
 
 const struct hfs_hdr_layout hfs_dbl_fil_hdr_layout = {
@@ -962,13 +948,13 @@
  * header files.  The purpose is to allocate or release blocks as needed
  * to satisfy a change in file length.
  */
-static void hdr_truncate(struct inode *inode)
+void hdr_truncate(struct inode *inode, size_t size)
 {
 	struct hfs_cat_entry *entry = HFS_I(inode)->entry;
 	struct hfs_hdr_layout *layout;
-	size_t size = inode->i_size;
 	int lcv, last;
 
+	inode->i_size = size;
 	if (!HFS_I(inode)->layout) {
 		HFS_I(inode)->layout = dup_layout(HFS_I(inode)->default_layout);
 	}
diff -u --recursive --new-file v2.3.47/linux/fs/hfs/inode.c linux/fs/hfs/inode.c
--- v2.3.47/linux/fs/hfs/inode.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/hfs/inode.c	Sat Feb 26 20:33:42 2000
@@ -106,7 +106,9 @@
  *     to permissions must be applied to all other in-core inodes which 
  *     correspond to the same HFS file.
  */
-int hfs_notify_change(struct dentry *dentry, struct iattr * attr)
+enum {HFS_NORM, HFS_HDR, HFS_CAP};
+
+static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int kind)
 {
 	struct inode *inode = dentry->d_inode;
 	struct hfs_cat_entry *entry = HFS_I(inode)->entry;
@@ -148,6 +150,22 @@
 		}
 		attr->ia_mode &= ~hsb->s_umask;
 	}
+	/*
+	 * Normal files handle size change in normal way.
+	 * Oddballs are served here.
+	 */
+	if (attr->ia_valid & ATTR_SIZE) {
+		if (kind == HFS_CAP) {
+			inode->i_size = attr->ia_size;
+			if (inode->i_size > HFS_FORK_MAX)
+				inode->i_size = HFS_FORK_MAX;
+			mark_inode_dirty(inode);
+			attr->ia_valid &= ~ATTR_SIZE;
+		} else if (kind == HFS_HDR) {
+			hdr_truncate(inode, attr->ia_size);
+			attr->ia_valid &= ~ATTR_SIZE;
+		}
+	}
 	inode_setattr(inode, attr);
 
 	/* We wouldn't want to mess with the sizes of the other fork */
@@ -184,6 +202,21 @@
 	return 0;
 }
 
+int hfs_notify_change(struct dentry *dentry, struct iattr * attr)
+{
+	return __hfs_notify_change(dentry, attr, HFS_NORM);
+}
+
+int hfs_notify_change_cap(struct dentry *dentry, struct iattr * attr)
+{
+	return __hfs_notify_change(dentry, attr, HFS_CAP);
+}
+
+int hfs_notify_change_hdr(struct dentry *dentry, struct iattr * attr)
+{
+	return __hfs_notify_change(dentry, attr, HFS_HDR);
+}
+
 static int hfs_writepage(struct dentry *dentry, struct page *page)
 {
 	return block_write_full_page(page,hfs_get_block);
@@ -329,10 +362,12 @@
 		inode->i_nlink = 1;
 		inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
 		inode->i_op = &hfs_cap_info_inode_operations;
+		inode->i_fop = &hfs_cap_info_operations;
 	} else if (entry->type == HFS_CDR_FIL) {
 		init_file_inode(inode, (type == HFS_CAP_DATA) ?
 						HFS_FK_DATA : HFS_FK_RSRC);
 		inode->i_op = &hfs_file_inode_operations;
+		inode->i_fop = &hfs_file_operations;
 		inode->i_mapping->a_ops = &hfs_aops;
 		inode->u.hfs_i.mmu_private = inode->i_size;
 	} else { /* Directory */
@@ -345,16 +380,19 @@
 			inode->i_mode = S_IRWXUGO | S_IFDIR;
 			inode->i_nlink = hdir->dirs + 4;
 			inode->i_op = &hfs_cap_ndir_inode_operations;
+			inode->i_fop = &hfs_cap_dir_operations;
 			HFS_I(inode)->file_type = HFS_CAP_NORM;
 		} else if (type == HFS_CAP_FDIR) {
 			inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
 			inode->i_nlink = 2;
 			inode->i_op = &hfs_cap_fdir_inode_operations;
+			inode->i_fop = &hfs_cap_dir_operations;
 			HFS_I(inode)->file_type = HFS_CAP_FNDR;
 		} else if (type == HFS_CAP_RDIR) {
 			inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
 			inode->i_nlink = 2;
 			inode->i_op = &hfs_cap_rdir_inode_operations;
+			inode->i_fop = &hfs_cap_dir_operations;
 			HFS_I(inode)->file_type = HFS_CAP_RSRC;
 		}
 	}
@@ -385,9 +423,11 @@
 			HFS_I(inode)->default_layout = &hfs_dbl_dir_hdr_layout;
 		}
 		inode->i_op = &hfs_hdr_inode_operations;
+		inode->i_fop = &hfs_hdr_operations;
 	} else if (entry->type == HFS_CDR_FIL) {
 		init_file_inode(inode, HFS_FK_DATA);
 		inode->i_op = &hfs_file_inode_operations;
+		inode->i_fop = &hfs_file_operations;
 		inode->i_mapping->a_ops = &hfs_aops;
 		inode->u.hfs_i.mmu_private = inode->i_size;
 	} else { /* Directory */
@@ -398,6 +438,7 @@
 		inode->i_size = 3 + 2 * (hdir->dirs + hdir->files);
 		inode->i_mode = S_IRWXUGO | S_IFDIR;
 		inode->i_op = &hfs_dbl_dir_inode_operations;
+		inode->i_fop = &hfs_dbl_dir_operations;
 		HFS_I(inode)->file_type = HFS_DBL_NORM;
 		HFS_I(inode)->dir_size = 2;
 	}
@@ -426,11 +467,13 @@
 			inode->i_nlink = 1;
 		}
 		inode->i_op = &hfs_hdr_inode_operations;
+		inode->i_fop = &hfs_hdr_operations;
 		HFS_I(inode)->default_layout = (version == 2) ?
 			&hfs_nat2_hdr_layout : &hfs_nat_hdr_layout;
 	} else if (entry->type == HFS_CDR_FIL) {
 		init_file_inode(inode, HFS_FK_DATA);
 		inode->i_op = &hfs_file_inode_operations;
+		inode->i_fop = &hfs_file_operations;
 		inode->i_mapping->a_ops = &hfs_aops;
 		inode->u.hfs_i.mmu_private = inode->i_size;
 	} else { /* Directory */
@@ -449,5 +492,6 @@
 			inode->i_op = &hfs_nat_hdir_inode_operations;
 			HFS_I(inode)->file_type = HFS_NAT_HDR;
 		}
+		inode->i_fop = &hfs_nat_dir_operations;
 	}
 }
diff -u --recursive --new-file v2.3.47/linux/fs/hfs/super.c linux/fs/hfs/super.c
--- v2.3.47/linux/fs/hfs/super.c	Tue Aug 31 17:29:14 1999
+++ linux/fs/hfs/super.c	Sat Feb 26 20:33:42 2000
@@ -42,15 +42,11 @@
 /*================ Global variables ================*/
 
 static struct super_operations hfs_super_operations = { 
-	hfs_read_inode,		/* read_inode */
-	NULL,			/* write_inode */
-	hfs_put_inode,		/* put_inode     - in inode.c */
-	NULL,                   /* delete_inode  */
-	hfs_notify_change,	/* notify_change - in inode.c */
-	hfs_put_super,		/* put_super */
-	hfs_write_super,	/* write_super */
-	hfs_statfs,		/* statfs */
-	NULL			/* remount_fs */
+	read_inode:	hfs_read_inode,
+	put_inode:	hfs_put_inode,
+	put_super:	hfs_put_super,
+	write_super:	hfs_write_super,
+	statfs:		hfs_statfs,
 };
 
 /*================ File-local variables ================*/
@@ -72,7 +68,6 @@
 static void hfs_read_inode(struct inode *inode)
 {
   inode->i_mode = 0;
-  inode->i_op = NULL;
 }
 
 /*
diff -u --recursive --new-file v2.3.47/linux/fs/hpfs/dir.c linux/fs/hpfs/dir.c
--- v2.3.47/linux/fs/hpfs/dir.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/hpfs/dir.c	Sat Feb 26 20:33:06 2000
@@ -8,11 +8,6 @@
 
 #include "hpfs_fn.h"
 
-ssize_t hpfs_dir_read(struct file *filp, char *name, size_t len, loff_t *loff)
-{
-	return -EISDIR;
-}
-
 int hpfs_dir_release(struct inode *inode, struct file *filp)
 {
 	hpfs_del_pos(inode, &filp->f_pos);
diff -u --recursive --new-file v2.3.47/linux/fs/hpfs/hpfs_fn.h linux/fs/hpfs/hpfs_fn.h
--- v2.3.47/linux/fs/hpfs/hpfs_fn.h	Thu Feb 10 17:11:17 2000
+++ linux/fs/hpfs/hpfs_fn.h	Sat Feb 26 20:33:06 2000
@@ -224,7 +224,6 @@
 
 /* dir.c */
 
-ssize_t hpfs_dir_read(struct file *, char *, size_t, loff_t *);
 int hpfs_dir_release(struct inode *, struct file *);
 loff_t hpfs_dir_lseek(struct file *, loff_t, int);
 int hpfs_readdir(struct file *, void *, filldir_t);
diff -u --recursive --new-file v2.3.47/linux/fs/hpfs/inode.c linux/fs/hpfs/inode.c
--- v2.3.47/linux/fs/hpfs/inode.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/hpfs/inode.c	Sat Feb 26 20:33:42 2000
@@ -8,7 +8,7 @@
 
 #include "hpfs_fn.h"
 
-static const struct file_operations hpfs_file_ops =
+static struct file_operations hpfs_file_ops =
 {
 	read:		generic_file_read,
 	write:		hpfs_file_write,
@@ -18,45 +18,33 @@
 	fsync:		hpfs_file_fsync,
 };
 
-static const struct inode_operations hpfs_file_iops =
+static struct inode_operations hpfs_file_iops =
 {
-	(nonconst *) & hpfs_file_ops,	/* default file operations */
-	NULL,				/* create */
-	NULL,				/* lookup */
-	NULL,				/* link */
-	NULL,				/* unlink */
-	NULL,				/* symlink */
-	NULL,				/* mkdir */
-	NULL,				/* rmdir */
-	NULL,				/* mknod */
-	NULL,				/* rename */
-	NULL,				/* readlink */
-	NULL,				/* follow_link */
-	hpfs_truncate,			/* truncate */
+	truncate:	hpfs_truncate,
+	setattr:	hpfs_notify_change,
 };
 
-static const struct file_operations hpfs_dir_ops =
+static struct file_operations hpfs_dir_ops =
 {
 	llseek:		hpfs_dir_lseek,
-	read:		hpfs_dir_read,
+	read:		generic_read_dir,
 	readdir:	hpfs_readdir,
 	open:		hpfs_open,
 	release:	hpfs_dir_release,
 	fsync:		hpfs_file_fsync,
 };
 
-static const struct inode_operations hpfs_dir_iops =
+static struct inode_operations hpfs_dir_iops =
 {
-	(nonconst *) & hpfs_dir_ops,	/* default directory file ops */
-	hpfs_create,			/* create */
-	hpfs_lookup,			/* lookup */
-	NULL,				/* link */
-	hpfs_unlink,			/* unlink */
-	hpfs_symlink,			/* symlink */
-	hpfs_mkdir,			/* mkdir */
-	hpfs_rmdir,			/* rmdir */
-	hpfs_mknod,			/* mknod */
-	hpfs_rename,			/* rename */
+	create:		hpfs_create,
+	lookup:		hpfs_lookup,
+	unlink:		hpfs_unlink,
+	symlink:	hpfs_symlink,
+	mkdir:		hpfs_mkdir,
+	rmdir:		hpfs_rmdir,
+	mknod:		hpfs_mknod,
+	rename:		hpfs_rename,
+	setattr:	hpfs_notify_change,
 };
 
 struct address_space_operations hpfs_symlink_aops = {
@@ -70,7 +58,6 @@
 	struct super_block *sb = i->i_sb;
 	unsigned char *ea;
 	int ea_size;
-	i->i_op = 0;
 	init_MUTEX(&i->i_hpfs_sem);
 	i->i_uid = sb->s_hpfs_uid;
 	i->i_gid = sb->s_hpfs_gid;
@@ -104,14 +91,16 @@
 	if (i->i_sb->s_hpfs_rd_inode == 2) {
 		i->i_mode |= S_IFREG;
 		i->i_mode &= ~0111;
-		i->i_op = (struct inode_operations *) &hpfs_file_iops;
+		i->i_op = &hpfs_file_iops;
+		i->i_fop = &hpfs_file_ops;
 		i->i_nlink = 1;
 		return;
 	}
 	if (!(fnode = hpfs_map_fnode(sb, i->i_ino, &bh))) {
 		/*i->i_mode |= S_IFREG;
 		i->i_mode &= ~0111;
-		i->i_op = (struct inode_operations *) &hpfs_file_iops;
+		i->i_op = &hpfs_file_iops;
+		i->i_fop = &hpfs_file_ops;
 		i->i_nlink = 0;*/
 		make_bad_inode(i);
 		return;
@@ -171,7 +160,8 @@
 	if (fnode->dirflag) {
 		unsigned n_dnodes, n_subdirs;
 		i->i_mode |= S_IFDIR;
-		i->i_op = (struct inode_operations *) &hpfs_dir_iops;
+		i->i_op = &hpfs_dir_iops;
+		i->i_fop = &hpfs_dir_ops;
 		i->i_hpfs_parent_dir = fnode->up;
 		i->i_hpfs_dno = fnode->u.external[0].disk_secno;
 		if (sb->s_hpfs_chk >= 2) {
@@ -186,7 +176,8 @@
 	} else {
 		i->i_mode |= S_IFREG;
 		if (!i->i_hpfs_ea_mode) i->i_mode &= ~0111;
-		i->i_op = (struct inode_operations *) &hpfs_file_iops;
+		i->i_op = &hpfs_file_iops;
+		i->i_fop = &hpfs_file_ops;
 		i->i_nlink = 1;
 		i->i_size = fnode->file_size;
 		i->i_blocks = ((i->i_size + 511) >> 9) + 1;
diff -u --recursive --new-file v2.3.47/linux/fs/hpfs/super.c linux/fs/hpfs/super.c
--- v2.3.47/linux/fs/hpfs/super.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/hpfs/super.c	Sat Feb 26 20:33:42 2000
@@ -152,19 +152,13 @@
 
 /* Super operations */
 
-static const struct super_operations hpfs_sops =
+static struct super_operations hpfs_sops =
 {
-        hpfs_read_inode,		/* read_inode */
-        NULL,				/* write_inode */
-	NULL,				/* put_inode */
-	hpfs_delete_inode,		/* delete inode */
-        hpfs_notify_change,		/* notify_change */
-        hpfs_put_super,			/* put_super */
-        NULL,				/* write_super */
-        hpfs_statfs,			/* statfs */
-        hpfs_remount_fs,		/* remount_fs */
-	NULL,				/* clear inode */
-	NULL,				/* umount_begin */
+        read_inode:	hpfs_read_inode,
+	delete_inode:	hpfs_delete_inode,
+	put_super:	hpfs_put_super,
+	statfs:		hpfs_statfs,
+	remount_fs:	hpfs_remount_fs,
 };
 
 /*
@@ -437,7 +431,7 @@
 	s->s_magic = HPFS_SUPER_MAGIC;
 	s->s_blocksize = 512;
 	s->s_blocksize_bits = 9;
-	s->s_op = (struct super_operations *) &hpfs_sops;
+	s->s_op = &hpfs_sops;
 
 	s->s_hpfs_root = superblock->root;
 	s->s_hpfs_fs_size = superblock->n_sectors;
diff -u --recursive --new-file v2.3.47/linux/fs/inode.c linux/fs/inode.c
--- v2.3.47/linux/fs/inode.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/inode.c	Sat Feb 26 20:33:06 2000
@@ -471,9 +471,12 @@
 static void clean_inode(struct inode *inode)
 {
 	static struct address_space_operations empty_aops = {};
+	static struct inode_operations empty_iops = {};
+	static struct file_operations empty_fops = {};
 	memset(&inode->u, 0, sizeof(inode->u));
 	inode->i_sock = 0;
-	inode->i_op = NULL;
+	inode->i_op = &empty_iops;
+	inode->i_fop = &empty_fops;
 	inode->i_nlink = 1;
 	atomic_set(&inode->i_writecount, 0);
 	inode->i_size = 0;
diff -u --recursive --new-file v2.3.47/linux/fs/isofs/Makefile linux/fs/isofs/Makefile
--- v2.3.47/linux/fs/isofs/Makefile	Thu Feb 10 17:11:17 2000
+++ linux/fs/isofs/Makefile	Sat Feb 26 20:33:06 2000
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definitions are now in the main makefile.
 
 O_TARGET := isofs.o
-O_OBJS   := namei.o inode.o file.o dir.o util.o rock.o
+O_OBJS   := namei.o inode.o dir.o util.o rock.o
 
 ifdef CONFIG_JOLIET
 O_OBJS += joliet.o
diff -u --recursive --new-file v2.3.47/linux/fs/isofs/dir.c linux/fs/isofs/dir.c
--- v2.3.47/linux/fs/isofs/dir.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/isofs/dir.c	Sat Feb 26 20:33:06 2000
@@ -26,8 +26,9 @@
 
 static int isofs_readdir(struct file *, void *, filldir_t);
 
-static struct file_operations isofs_dir_operations =
+struct file_operations isofs_dir_operations =
 {
+	read:		generic_read_dir,
 	readdir:	isofs_readdir,
 };
 
@@ -36,9 +37,7 @@
  */
 struct inode_operations isofs_dir_inode_operations =
 {
-	&isofs_dir_operations,	/* default directory file-ops */
-	NULL,			/* create */
-	isofs_lookup,		/* lookup */
+	lookup:		isofs_lookup,
 };
 
 static int isofs_name_translate(char * old, int len, char * new)
diff -u --recursive --new-file v2.3.47/linux/fs/isofs/file.c linux/fs/isofs/file.c
--- v2.3.47/linux/fs/isofs/file.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/isofs/file.c	Wed Dec 31 16:00:00 1969
@@ -1,31 +0,0 @@
-/*
- *  linux/fs/isofs/file.c
- *
- *  (C) 1992, 1993, 1994  Eric Youngdale Modified for ISO 9660 filesystem.
- *
- *  (C) 1991  Linus Torvalds - minix filesystem
- *
- *  isofs regular file handling primitives
- */
-
-#include <linux/sched.h>
-#include <linux/iso_fs.h>
-#include <linux/fcntl.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/stat.h>
-#include <linux/locks.h>
-#include <linux/fs.h>
-
-/*
- * We have mostly NULLs here: the current defaults are OK for
- * the isofs filesystem.
- */
-static struct file_operations isofs_file_operations = {
-	read:		generic_file_read,
-	mmap:		generic_file_mmap,
-};
-
-struct inode_operations isofs_file_inode_operations = {
-	&isofs_file_operations,	/* default file operations */
-};
diff -u --recursive --new-file v2.3.47/linux/fs/isofs/inode.c linux/fs/isofs/inode.c
--- v2.3.47/linux/fs/isofs/inode.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/isofs/inode.c	Sat Feb 26 20:33:06 2000
@@ -77,15 +77,9 @@
 static int isofs_statfs (struct super_block *, struct statfs *, int);
 
 static struct super_operations isofs_sops = {
-	isofs_read_inode,
-	NULL,			/* write_inode */
-	NULL,			/* put_inode */
-	NULL,			/* delete_inode */
-	NULL,			/* notify_change */
-	isofs_put_super,
-	NULL,			/* write_super */
-	isofs_statfs,
-	NULL
+	read_inode:	isofs_read_inode,
+	put_super:	isofs_put_super,
+	statfs:		isofs_statfs,
 };
 
 static struct dentry_operations isofs_dentry_ops[] = {
@@ -1259,7 +1253,6 @@
 	}
 
 	/* Install the inode operations vector */
-	inode->i_op = NULL;
 #ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
 	if (inode->i_sb->u.isofs_sb.s_cruft != 'y' &&
 	    (volume_seq_no != 0) && (volume_seq_no != 1)) {
@@ -1268,11 +1261,12 @@
 #endif IGNORE_WRONG_MULTI_VOLUME_SPECS
 	{
 	  if (S_ISREG(inode->i_mode)) {
-	    inode->i_op = &isofs_file_inode_operations;
+	    inode->i_fop = &generic_ro_fops;
 	    inode->i_data.a_ops = &isofs_aops;
-	  } else if (S_ISDIR(inode->i_mode))
+	  } else if (S_ISDIR(inode->i_mode)) {
 	    inode->i_op = &isofs_dir_inode_operations;
-	  else if (S_ISLNK(inode->i_mode)) {
+	    inode->i_fop = &isofs_dir_operations;
+	  } else if (S_ISLNK(inode->i_mode)) {
 	    inode->i_op = &page_symlink_inode_operations;
 	    inode->i_data.a_ops = &isofs_symlink_aops;
 	  } else
@@ -1283,14 +1277,7 @@
 
       fail:
 	/* With a data error we return this information */
-	inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
-	inode->u.isofs_i.i_first_extent = 0;
-	inode->i_size = 0;
-	inode->i_blocks = inode->i_blksize = 0;
-	inode->i_nlink = 1;
-	inode->i_uid = inode->i_gid = 0;
-	inode->i_mode = S_IFREG;  /*Regular file, no one gets to read*/
-	inode->i_op = NULL;
+	make_bad_inode(inode);
 	return;
 }
 
diff -u --recursive --new-file v2.3.47/linux/fs/minix/bitmap.c linux/fs/minix/bitmap.c
--- v2.3.47/linux/fs/minix/bitmap.c	Thu Nov 11 20:11:49 1999
+++ linux/fs/minix/bitmap.c	Sat Feb 26 20:33:06 2000
@@ -289,7 +289,6 @@
 	inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
 	inode->i_ino = j;
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-	inode->i_op = NULL;
 	inode->i_blocks = inode->i_blksize = 0;
 	insert_inode_hash(inode);
 	mark_inode_dirty(inode);
diff -u --recursive --new-file v2.3.47/linux/fs/minix/dir.c linux/fs/minix/dir.c
--- v2.3.47/linux/fs/minix/dir.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/minix/dir.c	Sat Feb 26 20:33:06 2000
@@ -12,36 +12,12 @@
 #include <linux/minix_fs.h>
 #include <linux/stat.h>
 
-#include <asm/uaccess.h>
-
-static ssize_t minix_dir_read(struct file * filp, char * buf,
-			      size_t count, loff_t *ppos)
-{
-	return -EISDIR;
-}
-
 static int minix_readdir(struct file *, void *, filldir_t);
 
-static struct file_operations minix_dir_operations = {
-	read:		minix_dir_read,
+struct file_operations minix_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	minix_readdir,
 	fsync:		file_fsync,
-};
-
-/*
- * directories can handle most operations...
- */
-struct inode_operations minix_dir_inode_operations = {
-	&minix_dir_operations,	/* default directory file-ops */
-	minix_create,		/* create */
-	minix_lookup,		/* lookup */
-	minix_link,		/* link */
-	minix_unlink,		/* unlink */
-	minix_symlink,		/* symlink */
-	minix_mkdir,		/* mkdir */
-	minix_rmdir,		/* rmdir */
-	minix_mknod,		/* mknod */
-	minix_rename,		/* rename */
 };
 
 static int minix_readdir(struct file * filp,
diff -u --recursive --new-file v2.3.47/linux/fs/minix/file.c linux/fs/minix/file.c
--- v2.3.47/linux/fs/minix/file.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/minix/file.c	Sat Feb 26 20:33:06 2000
@@ -6,18 +6,6 @@
  *  minix regular file handling primitives
  */
 
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/locks.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
 #include <linux/fs.h>
 #include <linux/minix_fs.h>
 
@@ -25,7 +13,7 @@
  * We have mostly NULLs here: the current defaults are OK for
  * the minix filesystem.
  */
-static struct file_operations minix_file_operations = {
+struct file_operations minix_file_operations = {
 	read:		generic_file_read,
 	write:		generic_file_write,
 	mmap:		generic_file_mmap,
@@ -33,6 +21,5 @@
 };
 
 struct inode_operations minix_file_inode_operations = {
-	&minix_file_operations,
 	truncate:	minix_truncate,
 };
diff -u --recursive --new-file v2.3.47/linux/fs/minix/inode.c linux/fs/minix/inode.c
--- v2.3.47/linux/fs/minix/inode.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/minix/inode.c	Sat Feb 26 20:33:06 2000
@@ -85,15 +85,13 @@
 }
 
 static struct super_operations minix_sops = {
-	minix_read_inode,
-	minix_write_inode,
-	NULL,			/* put_inode */
-	minix_delete_inode,
-	NULL,			/* notify_change */
-	minix_put_super,
-	minix_write_super,
-	minix_statfs,
-	minix_remount
+	read_inode:	minix_read_inode,
+	write_inode:	minix_write_inode,
+	delete_inode:	minix_delete_inode,
+	put_super:	minix_put_super,
+	write_super:	minix_write_super,
+	statfs:		minix_statfs,
+	remount_fs:	minix_remount,
 };
 
 static int minix_remount (struct super_block * sb, int * flags, char * data)
@@ -1054,7 +1052,6 @@
 	int block, ino;
 
 	ino = inode->i_ino;
-	inode->i_op = NULL;
 	inode->i_mode = 0;
 	if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
 		printk("Bad inode number on dev %s"
@@ -1083,10 +1080,12 @@
 		inode->u.minix_i.u.i1_data[block] = raw_inode->i_zone[block];
 	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &minix_file_inode_operations;
+		inode->i_fop = &minix_file_operations;
 		inode->i_mapping->a_ops = &minix_aops;
-	} else if (S_ISDIR(inode->i_mode))
+	} else if (S_ISDIR(inode->i_mode)) {
 		inode->i_op = &minix_dir_inode_operations;
-	else if (S_ISLNK(inode->i_mode)) {
+		inode->i_fop = &minix_dir_operations;
+	} else if (S_ISLNK(inode->i_mode)) {
 		inode->i_op = &page_symlink_inode_operations;
 		inode->i_mapping->a_ops = &minix_aops;
 	} else
@@ -1104,7 +1103,6 @@
 	int block, ino;
 
 	ino = inode->i_ino;
-	inode->i_op = NULL;
 	inode->i_mode = 0;
 	if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
 		printk("Bad inode number on dev %s"
@@ -1135,10 +1133,12 @@
 		inode->u.minix_i.u.i2_data[block] = raw_inode->i_zone[block];
 	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &minix_file_inode_operations;
+		inode->i_fop = &minix_file_operations;
 		inode->i_mapping->a_ops = &minix_aops;
-	} else if (S_ISDIR(inode->i_mode))
+	} else if (S_ISDIR(inode->i_mode)) {
 		inode->i_op = &minix_dir_inode_operations;
-	else if (S_ISLNK(inode->i_mode)) {
+		inode->i_fop = &minix_dir_operations;
+	} else if (S_ISLNK(inode->i_mode)) {
 		inode->i_op = &page_symlink_inode_operations;
 		inode->i_mapping->a_ops = &minix_aops;
 	} else
diff -u --recursive --new-file v2.3.47/linux/fs/minix/namei.c linux/fs/minix/namei.c
--- v2.3.47/linux/fs/minix/namei.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/minix/namei.c	Sat Feb 26 20:33:06 2000
@@ -115,7 +115,7 @@
 	0		/* compare */
 };
 
-struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry)
+static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry)
 {
 	struct inode * inode = NULL;
 	struct minix_dir_entry * de;
@@ -206,7 +206,7 @@
 	return 0;
 }
 
-int minix_create(struct inode * dir, struct dentry *dentry, int mode)
+static int minix_create(struct inode * dir, struct dentry *dentry, int mode)
 {
 	int error;
 	struct inode * inode;
@@ -219,6 +219,7 @@
 	if (!inode)
 		return -ENOSPC;
 	inode->i_op = &minix_file_inode_operations;
+	inode->i_fop = &minix_file_operations;
 	inode->i_mapping->a_ops = &minix_aops;
 	inode->i_mode = mode;
 	mark_inode_dirty(inode);
@@ -237,7 +238,7 @@
 	return 0;
 }
 
-int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev)
+static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev)
 {
 	int error;
 	struct inode * inode;
@@ -266,7 +267,7 @@
 	return 0;
 }
 
-int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
+static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
 {
 	int error;
 	struct inode * inode;
@@ -283,6 +284,7 @@
 	if (!inode)
 		return -ENOSPC;
 	inode->i_op = &minix_dir_inode_operations;
+	inode->i_fop = &minix_dir_operations;
 	inode->i_size = 2 * info->s_dirsize;
 	dir_block = minix_bread(inode,0,1);
 	if (!dir_block) {
@@ -377,7 +379,7 @@
 	return 1;
 }
 
-int minix_rmdir(struct inode * dir, struct dentry *dentry)
+static int minix_rmdir(struct inode * dir, struct dentry *dentry)
 {
 	int retval;
 	struct inode * inode;
@@ -422,7 +424,7 @@
 	return retval;
 }
 
-int minix_unlink(struct inode * dir, struct dentry *dentry)
+static int minix_unlink(struct inode * dir, struct dentry *dentry)
 {
 	int retval;
 	struct inode * inode;
@@ -457,7 +459,7 @@
 	return retval;
 }
 
-int minix_symlink(struct inode * dir, struct dentry *dentry,
+static int minix_symlink(struct inode * dir, struct dentry *dentry,
 		  const char * symname)
 {
 	struct minix_dir_entry * de;
@@ -502,7 +504,7 @@
 	goto out;
 }
 
-int minix_link(struct dentry * old_dentry, struct inode * dir,
+static int minix_link(struct dentry * old_dentry, struct inode * dir,
 	       struct dentry *dentry)
 {
 	int error;
@@ -540,7 +542,7 @@
  * Anybody can rename anything with this: the permission checks are left to the
  * higher-level routines.
  */
-int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
+static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
 			   struct inode * new_dir, struct dentry *new_dentry)
 {
 	struct inode * old_inode, * new_inode;
@@ -630,3 +632,18 @@
 	brelse(new_bh);
 	return retval;
 }
+
+/*
+ * directories can handle most operations...
+ */
+struct inode_operations minix_dir_inode_operations = {
+	create:		minix_create,
+	lookup:		minix_lookup,
+	link:		minix_link,
+	unlink:		minix_unlink,
+	symlink:	minix_symlink,
+	mkdir:		minix_mkdir,
+	rmdir:		minix_rmdir,
+	mknod:		minix_mknod,
+	rename:		minix_rename,
+};
diff -u --recursive --new-file v2.3.47/linux/fs/msdos/namei.c linux/fs/msdos/namei.c
--- v2.3.47/linux/fs/msdos/namei.c	Thu Feb 10 17:11:17 2000
+++ linux/fs/msdos/namei.c	Sat Feb 26 20:33:42 2000
@@ -585,16 +585,13 @@
 
 /* The public inode operations for the msdos fs */
 struct inode_operations msdos_dir_inode_operations = {
-	&fat_dir_operations,	/* default directory file-ops */
-	msdos_create,		/* create */
-	msdos_lookup,		/* lookup */
-	NULL,			/* link */
-	msdos_unlink,		/* unlink */
-	NULL,			/* symlink */
-	msdos_mkdir,		/* mkdir */
-	msdos_rmdir,		/* rmdir */
-	NULL,			/* mknod */
-	msdos_rename,		/* rename */
+	create:		msdos_create,
+	lookup:		msdos_lookup,
+	unlink:		msdos_unlink,
+	mkdir:		msdos_mkdir,
+	rmdir:		msdos_rmdir,
+	rename:		msdos_rename,
+	setattr:	fat_notify_change,
 };
 
 static void msdos_put_super_callback(struct super_block *sb)
diff -u --recursive --new-file v2.3.47/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c
--- v2.3.47/linux/fs/ncpfs/dir.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/ncpfs/dir.c	Sat Feb 26 20:33:42 2000
@@ -31,7 +31,6 @@
 static void ncp_do_readdir(struct file *, void *, filldir_t,
 				struct ncp_cache_control *);
 
-static ssize_t ncp_dir_read(struct file *, char *, size_t, loff_t *);
 static int ncp_readdir(struct file *, void *, filldir_t);
 
 static int ncp_create(struct inode *, struct dentry *, int);
@@ -45,41 +44,26 @@
 extern int ncp_symlink(struct inode *, struct dentry *, const char *);
 #endif
 		      
-static struct file_operations ncp_dir_operations =
+struct file_operations ncp_dir_operations =
 {
-	read:		ncp_dir_read,
+	read:		generic_read_dir,
 	readdir:	ncp_readdir,
 	ioctl:		ncp_ioctl,
 };
 
 struct inode_operations ncp_dir_inode_operations =
 {
-	&ncp_dir_operations,	/* default directory file ops */
-	ncp_create,		/* create */
-	ncp_lookup,		/* lookup */
-	NULL,			/* link */
-	ncp_unlink,		/* unlink */
+	create:		ncp_create,
+	lookup:		ncp_lookup,
+	unlink:		ncp_unlink,
 #ifdef CONFIG_NCPFS_EXTRAS
-	ncp_symlink,		/* symlink */
-#else
-	NULL,			/* symlink */
+	symlink:	ncp_symlink,
 #endif
-	ncp_mkdir,		/* mkdir */
-	ncp_rmdir,		/* rmdir */
-	NULL,			/* mknod */
-	ncp_rename,		/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow link */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL,			/* revalidate */
+	mkdir:		ncp_mkdir,
+	rmdir:		ncp_rmdir,
+	rename:		ncp_rename,
+	setattr:	ncp_notify_change,
 };
-
-static ssize_t 
-ncp_dir_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
-{
-	return -EISDIR;
-}
 
 /*
  * Dentry operations routines
diff -u --recursive --new-file v2.3.47/linux/fs/ncpfs/file.c linux/fs/ncpfs/file.c
--- v2.3.47/linux/fs/ncpfs/file.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/ncpfs/file.c	Sat Feb 26 20:33:42 2000
@@ -275,7 +275,7 @@
 	return already_written ? already_written : errno;
 }
 
-static struct file_operations ncp_file_operations =
+struct file_operations ncp_file_operations =
 {
 	read:		ncp_file_read,
 	write:		ncp_file_write,
@@ -286,19 +286,5 @@
 
 struct inode_operations ncp_file_inode_operations =
 {
-	&ncp_file_operations,	/* default file operations */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL			/* revalidate */
+	setattr:	ncp_notify_change,
 };
diff -u --recursive --new-file v2.3.47/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
--- v2.3.47/linux/fs/ncpfs/inode.c	Sun Feb 13 19:29:04 2000
+++ linux/fs/ncpfs/inode.c	Sat Feb 26 20:33:42 2000
@@ -38,15 +38,10 @@
 
 static struct super_operations ncp_sops =
 {
-	NULL,			/* read inode */
-	NULL,			/* write inode */
-	ncp_put_inode,		/* put inode */
-	ncp_delete_inode,       /* delete inode */
-	ncp_notify_change,	/* notify change */
-	ncp_put_super,		/* put superblock */
-	NULL,			/* write superblock */
-	ncp_statfs,		/* stat filesystem */
-	NULL                    /* remount */
+	put_inode:	ncp_put_inode,
+	delete_inode:	ncp_delete_inode,
+	put_super:	ncp_put_super,
+	statfs:		ncp_statfs,
 };
 
 extern struct dentry_operations ncp_dentry_operations;
@@ -201,6 +196,12 @@
 	ncp_update_inode(inode, nwinfo);
 }
 
+static struct inode_operations ncp_symlink_inode_operations = {
+	readlink:	page_readlink,
+	follow_link:	page_follow_link,
+	setattr:	ncp_notify_change,
+};
+
 /*
  * Get a new inode.
  */
@@ -222,11 +223,13 @@
 		ncp_set_attr(inode, info);
 		if (S_ISREG(inode->i_mode)) {
 			inode->i_op = &ncp_file_inode_operations;
+			inode->i_fop = &ncp_file_operations;
 		} else if (S_ISDIR(inode->i_mode)) {
 			inode->i_op = &ncp_dir_inode_operations;
+			inode->i_fop = &ncp_dir_operations;
 #ifdef CONFIG_NCPFS_EXTRAS
 		} else if (S_ISLNK(inode->i_mode)) {
-			inode->i_op = &page_symlink_inode_operations;
+			inode->i_op = &ncp_symlink_inode_operations;
 			inode->i_data.a_ops = &ncp_symlink_aops;
 #endif
 		}
diff -u --recursive --new-file v2.3.47/linux/fs/nfs/dir.c linux/fs/nfs/dir.c
--- v2.3.47/linux/fs/nfs/dir.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/nfs/dir.c	Sat Feb 26 20:33:42 2000
@@ -38,7 +38,6 @@
 
 static int nfs_safe_remove(struct dentry *);
 
-static ssize_t nfs_dir_read(struct file *, char *, size_t, loff_t *);
 static int nfs_readdir(struct file *, void *, filldir_t);
 static struct dentry *nfs_lookup(struct inode *, struct dentry *);
 static int nfs_create(struct inode *, struct dentry *, int);
@@ -51,36 +50,26 @@
 static int nfs_rename(struct inode *, struct dentry *,
 		      struct inode *, struct dentry *);
 
-static struct file_operations nfs_dir_operations = {
-	read:		nfs_dir_read,
+struct file_operations nfs_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	nfs_readdir,
 	open:		nfs_open,
 	release:	nfs_release,
 };
 
 struct inode_operations nfs_dir_inode_operations = {
-	&nfs_dir_operations,	/* default directory file-ops */
-	nfs_create,		/* create */
-	nfs_lookup,		/* lookup */
-	nfs_link,		/* link */
-	nfs_unlink,		/* unlink */
-	nfs_symlink,		/* symlink */
-	nfs_mkdir,		/* mkdir */
-	nfs_rmdir,		/* rmdir */
-	nfs_mknod,		/* mknod */
-	nfs_rename,		/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	nfs_revalidate,		/* revalidate */
+	create:		nfs_create,
+	lookup:		nfs_lookup,
+	link:		nfs_link,
+	unlink:		nfs_unlink,
+	symlink:	nfs_symlink,
+	mkdir:		nfs_mkdir,
+	rmdir:		nfs_rmdir,
+	mknod:		nfs_mknod,
+	rename:		nfs_rename,
+	revalidate:	nfs_revalidate,
+	setattr:	nfs_notify_change,
 };
-
-static ssize_t
-nfs_dir_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
-{
-	return -EISDIR;
-}
 
 /* Each readdir response is composed of entries which look
  * like the following, as per the NFSv2 RFC:
diff -u --recursive --new-file v2.3.47/linux/fs/nfs/file.c linux/fs/nfs/file.c
--- v2.3.47/linux/fs/nfs/file.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/nfs/file.c	Sat Feb 26 20:33:42 2000
@@ -40,7 +40,7 @@
 static int  nfs_file_flush(struct file *);
 static int  nfs_fsync(struct file *, struct dentry *dentry);
 
-static struct file_operations nfs_file_operations = {
+struct file_operations nfs_file_operations = {
 	read:		nfs_file_read,
 	write:		nfs_file_write,
 	mmap:		nfs_file_mmap,
@@ -52,21 +52,8 @@
 };
 
 struct inode_operations nfs_file_inode_operations = {
-	&nfs_file_operations,	/* default file operations */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	nfs_revalidate,		/* revalidate */
+	revalidate:	nfs_revalidate,
+	setattr:	nfs_notify_change,
 };
 
 /* Hack for future NFS swap support */
diff -u --recursive --new-file v2.3.47/linux/fs/nfs/inode.c linux/fs/nfs/inode.c
--- v2.3.47/linux/fs/nfs/inode.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/nfs/inode.c	Sat Feb 26 20:33:42 2000
@@ -44,23 +44,17 @@
 static void nfs_read_inode(struct inode *);
 static void nfs_put_inode(struct inode *);
 static void nfs_delete_inode(struct inode *);
-static int  nfs_notify_change(struct dentry *, struct iattr *);
 static void nfs_put_super(struct super_block *);
 static void nfs_umount_begin(struct super_block *);
 static int  nfs_statfs(struct super_block *, struct statfs *, int);
 
 static struct super_operations nfs_sops = { 
-	nfs_read_inode,		/* read inode */
-	NULL,			/* write inode */
-	nfs_put_inode,		/* put inode */
-	nfs_delete_inode,	/* delete inode */
-	nfs_notify_change,	/* notify change */
-	nfs_put_super,		/* put superblock */
-	NULL,			/* write superblock */
-	nfs_statfs,		/* stat filesystem */
-	NULL,			/* no remount */
-	NULL,			/* no clear inode */
-	nfs_umount_begin	/* umount attempt begin */
+	read_inode:	nfs_read_inode,
+	put_inode:	nfs_put_inode,
+	delete_inode:	nfs_delete_inode,
+	put_super:	nfs_put_super,
+	statfs:		nfs_statfs,
+	umount_begin:	nfs_umount_begin,
 };
 
 struct rpc_stat			nfs_rpcstat = { &nfs_program };
@@ -78,7 +72,6 @@
 	inode->i_blksize = inode->i_sb->s_blocksize;
 	inode->i_mode = 0;
 	inode->i_rdev = 0;
-	inode->i_op = NULL;
 	NFS_FILEID(inode) = 0;
 	NFS_FSID(inode) = 0;
 	NFS_CACHEINV(inode);
@@ -477,12 +470,17 @@
 		NFS_FILEID(inode) = fattr->fileid;
 		NFS_FSID(inode) = fattr->fsid;
 		inode->i_mode = fattr->mode;
+		/* Why so? Because we want revalidate for devices/FIFOs, and
+		 * that's precisely what we have in nfs_file_inode_operations.
+		 */
+		inode->i_op = &nfs_file_inode_operations;
 		if (S_ISREG(inode->i_mode)) {
-			inode->i_op = &nfs_file_inode_operations;
+			inode->i_fop = &nfs_file_operations;
 			inode->i_data.a_ops = &nfs_file_aops;
-		} else if (S_ISDIR(inode->i_mode))
+		} else if (S_ISDIR(inode->i_mode)) {
 			inode->i_op = &nfs_dir_inode_operations;
-		else if (S_ISLNK(inode->i_mode))
+			inode->i_fop = &nfs_dir_operations;
+		} else if (S_ISLNK(inode->i_mode))
 			inode->i_op = &nfs_symlink_inode_operations;
 		else
 			init_special_inode(inode, inode->i_mode, fattr->rdev);
diff -u --recursive --new-file v2.3.47/linux/fs/nfs/symlink.c linux/fs/nfs/symlink.c
--- v2.3.47/linux/fs/nfs/symlink.c	Tue Dec 14 01:27:24 1999
+++ linux/fs/nfs/symlink.c	Sat Feb 26 20:33:42 2000
@@ -104,4 +104,6 @@
 struct inode_operations nfs_symlink_inode_operations = {
 	readlink:	nfs_readlink,
 	follow_link:	nfs_follow_link,
+	revalidate:	nfs_revalidate,
+	setattr:	nfs_notify_change,
 };
diff -u --recursive --new-file v2.3.47/linux/fs/nfs/write.c linux/fs/nfs/write.c
--- v2.3.47/linux/fs/nfs/write.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/nfs/write.c	Mon Feb 21 11:27:23 2000
@@ -416,9 +416,23 @@
 int
 nfs_writepage(struct dentry * dentry, struct page *page)
 {
-	int result = nfs_writepage_sync(dentry, dentry->d_inode, page, 0, PAGE_SIZE); 
-	if ( result == PAGE_SIZE) return 0; 
-	return result; 
+	struct inode *inode = dentry->d_inode;
+	unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
+	unsigned offset = PAGE_CACHE_SIZE;
+	int err;
+
+	/* easy case */
+	if (page->index < end_index)
+		goto do_it;
+	/* things got complicated... */
+	offset = inode->i_size & (PAGE_CACHE_SIZE-1);
+	/* OK, are we completely out? */
+	if (page->index >= end_index+1 || !offset)
+		return -EIO;
+do_it:
+	err = nfs_writepage_sync(dentry, inode, page, 0, offset); 
+	if ( err == offset) return 0; 
+	return err; 
 }
 
 /*
diff -u --recursive --new-file v2.3.47/linux/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
--- v2.3.47/linux/fs/nfsd/nfsfh.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/nfsd/nfsfh.c	Sat Feb 26 20:33:07 2000
@@ -76,7 +76,7 @@
 	if (!dir || !S_ISDIR(dir->i_mode))
 		goto out;
 	error = -EINVAL;
-	if (!dir->i_op || !dir->i_op->default_file_ops)
+	if (!dir->i_fop)
 		goto out;
 	/*
 	 * Open the directory ...
diff -u --recursive --new-file v2.3.47/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c
--- v2.3.47/linux/fs/nfsd/vfs.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/nfsd/vfs.c	Sat Feb 26 20:33:07 2000
@@ -432,14 +432,14 @@
 	err = nfserr_perm;
 	if (IS_APPEND(inode) || IS_ISMNDLK(inode))
 		goto out;
-	if (!inode->i_op || !inode->i_op->default_file_ops)
+	if (!inode->i_fop)
 		goto out;
 
 	if ((access & MAY_WRITE) && (err = get_write_access(inode)) != 0)
 		goto out_nfserr;
 
 	memset(filp, 0, sizeof(*filp));
-	filp->f_op    = inode->i_op->default_file_ops;
+	filp->f_op    = inode->i_fop;
 	atomic_set(&filp->f_count, 1);
 	filp->f_dentry = dentry;
 	if (access & MAY_WRITE) {
@@ -512,8 +512,7 @@
 	struct inode *inode = dp->d_inode;
 	int (*fsync) (struct file *, struct dentry *);
 	
-	if (inode->i_op->default_file_ops
-	    && (fsync = inode->i_op->default_file_ops->fsync)) {
+	if (inode->i_fop && (fsync = inode->i_fop->fsync)) {
 		fsync(NULL, dp);
 	}
 }
diff -u --recursive --new-file v2.3.47/linux/fs/ntfs/fs.c linux/fs/ntfs/fs.c
--- v2.3.47/linux/fs/ntfs/fs.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/ntfs/fs.c	Sat Feb 26 20:33:07 2000
@@ -412,7 +412,6 @@
 };
 
 static struct inode_operations ntfs_inode_operations_nobmap = {
-	&ntfs_file_operations_nommap,
 };
 
 #ifdef CONFIG_NTFS_RW
@@ -466,6 +465,7 @@
 	}
 	/* It's not a directory */
 	r->i_op=&ntfs_inode_operations_nobmap;
+	r->i_fop=&ntfs_file_operations_nommap,
 	r->i_mode=S_IFREG|S_IRUGO;
 #ifdef CONFIG_NTFS_RW
 	r->i_mode|=S_IWUGO;
@@ -529,6 +529,7 @@
 	}
 	/* It's a directory */
 	r->i_op = &ntfs_dir_inode_operations;
+	r->i_fop = &ntfs_dir_operations;
 	r->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
 #ifdef CONFIG_NTFS_RW
 	r->i_mode|=S_IWUGO;
@@ -570,32 +571,19 @@
 };
 
 static struct inode_operations ntfs_inode_operations = {
-	&ntfs_file_operations,
 };
 
 static struct file_operations ntfs_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	ntfs_readdir,
 };
 
 static struct inode_operations ntfs_dir_inode_operations = {
-	&ntfs_dir_operations,
+	lookup:		ntfs_lookup,
 #ifdef CONFIG_NTFS_RW
-	ntfs_create, /* create */
-#else
-	NULL,
+	create:		ntfs_create,
+	mkdir:		_linux_ntfs_mkdir,
 #endif
-	ntfs_lookup, /* lookup */
-	NULL, /* link */
-	NULL, /* unlink */
-	NULL, /* symlink */
-#ifdef CONFIG_NTFS_RW
-	_linux_ntfs_mkdir, /* mkdir */
-#else
-	NULL,
-#endif
-	NULL, /* rmdir */
-	NULL, /* mknod */
-	NULL, /* rename */
 };
 
 static int ntfs_writepage(struct dentry *dentry, struct page *page)
@@ -636,7 +624,6 @@
 	ntfs_attribute *si;
 
 	vol=NTFS_INO2VOL(inode);
-	inode->i_op=NULL;
 	inode->i_mode=0;
 	ntfs_debug(DEBUG_OTHER, "ntfs_read_inode %x\n",(unsigned)inode->i_ino);
 
@@ -693,16 +680,19 @@
 		inode->i_size = at ? at->size : 0;
 	  
 		inode->i_op=&ntfs_dir_inode_operations;
+		inode->i_fop=&ntfs_dir_operations;
 		inode->i_mode=S_IFDIR|S_IRUGO|S_IXUGO;
 	}
 	else
 	{
 		if (can_mmap) {
 			inode->i_op = &ntfs_inode_operations;
+			inode->i_fop = &ntfs_file_operations;
 			inode->i_mapping->a_ops = &ntfs_aops;
 			inode->u.ntfs_i.mmu_private = inode->i_size;
 		} else {
 			inode->i_op=&ntfs_inode_operations_nobmap;
+			inode->i_fop=&ntfs_file_operations_nommap,
 		}
 		inode->i_mode=S_IFREG|S_IRUGO;
 	}
@@ -806,20 +796,14 @@
 
 /* Define the super block operation that are implemented */
 static struct super_operations ntfs_super_operations = {
-	ntfs_read_inode,
+	read_inode:	ntfs_read_inode,
 #ifdef CONFIG_NTFS_RW
-	ntfs_write_inode,
-#else
-	NULL,
+	write_inode:	ntfs_write_inode,
 #endif
-	NULL, /* put_inode */
-	NULL, /* delete_inode */
-	NULL, /* notify_change */
-	ntfs_put_super,
-	NULL, /* write_super */
-	ntfs_statfs,
-	ntfs_remount_fs, /* remount */
-	_ntfs_clear_inode, /* clear_inode */ 
+	put_super:	ntfs_put_super,
+	statfs:		ntfs_statfs,
+	remount_fs:	ntfs_remount_fs,
+	clear_inode:	_ntfs_clear_inode,
 };
 
 /* Called to mount a filesystem by read_super() in fs/super.c
diff -u --recursive --new-file v2.3.47/linux/fs/open.c linux/fs/open.c
--- v2.3.47/linux/fs/open.c	Wed Feb 16 17:03:52 2000
+++ linux/fs/open.c	Sat Feb 26 20:33:07 2000
@@ -680,7 +680,7 @@
 	f->f_reada = 0;
 	f->f_op = NULL;
 	if (inode->i_op)
-		f->f_op = inode->i_op->default_file_ops;
+		f->f_op = inode->i_fop;
 	if (inode->i_sb)
 		file_move(f, &inode->i_sb->s_files);
 	if (f->f_op && f->f_op->open) {
diff -u --recursive --new-file v2.3.47/linux/fs/openpromfs/inode.c linux/fs/openpromfs/inode.c
--- v2.3.47/linux/fs/openpromfs/inode.c	Sat Feb 12 11:22:11 2000
+++ linux/fs/openpromfs/inode.c	Sat Feb 26 20:33:07 2000
@@ -558,31 +558,24 @@
 	release:	property_release,
 };
 
-static struct inode_operations openpromfs_prop_inode_ops = {
-	&openpromfs_prop_ops,	/* default property file-ops */
-};
-
 static struct file_operations openpromfs_nodenum_ops = {
 	read:		nodenum_read,
 };
 
-static struct inode_operations openpromfs_nodenum_inode_ops = {
-	&openpromfs_nodenum_ops,/* default .node file-ops */
-};
-
-static struct file_operations openprom_alias_operations = {
+static struct file_operations openprom_operations = {
+	read:		generic_read_dir,
 	readdir:	openpromfs_readdir,
 };
 
 static struct inode_operations openprom_alias_inode_operations = {
-	&openprom_alias_operations,/* default aliases directory file-ops */
-	openpromfs_create,	/* create */
-	openpromfs_lookup,	/* lookup */
-	NULL,			/* link */
-	openpromfs_unlink,	/* unlink */
+	create:		openpromfs_create,
+	lookup:		openpromfs_lookup,
+	unlink:		openpromfs_unlink,
 };
 
-extern struct inode_operations openprom_inode_operations;
+static struct inode_operations openprom_inode_operations = {
+	lookup:		openpromfs_lookup,
+};
 
 static int lookup_children(u16 n, const char * name, int len)
 {
@@ -710,11 +703,12 @@
 			inode->i_op = &openprom_alias_inode_operations;
 		} else
 			inode->i_op = &openprom_inode_operations;
+		inode->i_fop = &openprom_operations;
 		inode->i_nlink = 2;
 		break;
 	case OPFSL_NODENUM:
 		inode->i_mode = S_IFREG | S_IRUGO;
-		inode->i_op = &openpromfs_nodenum_inode_ops;
+		inode->i_fop = &openpromfs_nodenum_ops;
 		inode->i_nlink = 1;
 		inode->u.generic_ip = (void *)(long)(n);
 		break;
@@ -729,7 +723,7 @@
 					inode->i_mode |= S_IWUSR;
 			}
 		}
-		inode->i_op = &openpromfs_prop_inode_ops;
+		inode->i_fop = &openpromfs_prop_ops;
 		inode->i_nlink = 1;
 		if (inode->i_size < 0)
 			inode->i_size = 0;
@@ -845,7 +839,7 @@
 	if (!inode)
 		return -EINVAL;
 	inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
-	inode->i_op = &openpromfs_prop_inode_ops;
+	inode->i_fop = &openpromfs_prop_ops;
 	inode->i_nlink = 1;
 	if (inode->i_size < 0) inode->i_size = 0;
 	inode->u.generic_ip = (void *)(long)(((u16)aliases) | 
@@ -976,22 +970,12 @@
 	return n;
 }
 
-
-static struct file_operations openprom_operations = {
-	readdir:	openpromfs_readdir,
-};
-
-static struct inode_operations openprom_inode_operations = {
-	&openprom_operations,/* default net directory file-ops */
-	NULL,			/* create */
-	openpromfs_lookup,	/* lookup */
-};
-
 static void openprom_read_inode(struct inode * inode)
 {
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	if (inode->i_ino == OPENPROM_ROOT_INO) {
 		inode->i_op = &openprom_inode_operations;
+		inode->i_fop = &openprom_operations;
 		inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
 	}
 }
@@ -1017,15 +1001,9 @@
 }
 
 static struct super_operations openprom_sops = { 
-	openprom_read_inode,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	openprom_put_super,
-	NULL,
-	openprom_statfs,
-	NULL
+	read_inode:	openprom_read_inode,
+	put_super:	openprom_put_super,
+	statfs:		openprom_statfs,
 };
 
 struct super_block *openprom_read_super(struct super_block *s,void *data, 
diff -u --recursive --new-file v2.3.47/linux/fs/partitions/check.c linux/fs/partitions/check.c
--- v2.3.47/linux/fs/partitions/check.c	Wed Feb 16 17:03:52 2000
+++ linux/fs/partitions/check.c	Sat Feb 26 08:25:35 2000
@@ -396,11 +396,15 @@
 	int first_minor	= drive << dev->minor_shift;
 	int end_minor	= first_minor + dev->max_p;
 
-	blk_size[dev->major] = NULL;
+	if(!dev->sizes)
+		blk_size[dev->major] = NULL;
+
 	dev->part[first_minor].nr_sects = size;
 	/* No Such Agen^Wdevice or no minors to use for partitions */
 	if (!size || minors == 1)
 		return;
+
+	blk_size[dev->major] = NULL;
 	check_partition(dev, MKDEV(dev->major, first_minor), 1 + first_minor);
 
  	/*
diff -u --recursive --new-file v2.3.47/linux/fs/partitions/msdos.c linux/fs/partitions/msdos.c
--- v2.3.47/linux/fs/partitions/msdos.c	Wed Feb 16 17:03:52 2000
+++ linux/fs/partitions/msdos.c	Sat Feb 26 20:32:15 2000
@@ -351,7 +351,7 @@
 	int tested_for_xlate = 0;
 
 read_mbr:
-#endif
+#endif /* CONFIG_BLK_DEV_IDE */
 	if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
 		if (warn_no_part) printk(" unable to read partition table\n");
 		return -1;
@@ -359,7 +359,7 @@
 	data = bh->b_data;
 #ifdef CONFIG_BLK_DEV_IDE
 check_table:
-#endif
+#endif /* CONFIG_BLK_DEV_IDE */
 	/* Use bforget(), because we may have changed the disk geometry */
 	if (*(unsigned short *)  (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) {
 		bforget(bh);
diff -u --recursive --new-file v2.3.47/linux/fs/pipe.c linux/fs/pipe.c
--- v2.3.47/linux/fs/pipe.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/pipe.c	Sat Feb 26 20:33:07 2000
@@ -533,7 +533,6 @@
 
 static struct inode * get_pipe_inode(void)
 {
-	extern struct inode_operations pipe_inode_operations;
 	struct inode *inode = get_empty_inode();
 	unsigned long page;
 
@@ -548,7 +547,7 @@
 	if (!inode->i_pipe)
 		goto fail_page;
 
-	inode->i_op = &pipe_inode_operations;
+	inode->i_fop = &rdwr_pipe_fops;
 
 	init_waitqueue_head(PIPE_WAIT(*inode));
 	PIPE_BASE(*inode) = (char *) page;
@@ -577,10 +576,6 @@
 fail_inode:
 	return NULL;
 }
-
-struct inode_operations pipe_inode_operations = {
-	&rdwr_pipe_fops,
-};
 
 int do_pipe(int *fd)
 {
diff -u --recursive --new-file v2.3.47/linux/fs/proc/base.c linux/fs/proc/base.c
--- v2.3.47/linux/fs/proc/base.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/proc/base.c	Sat Feb 26 20:33:07 2000
@@ -208,10 +208,6 @@
 	read:		pid_maps_read,
 };
 
-struct inode_operations proc_maps_inode_operations = {
-	&proc_maps_operations,	/* default base directory file-ops */
-};
-
 #define PROC_BLOCK_SIZE	(3*1024)		/* 4K page size but our output routines use some slack for overruns */
 
 static ssize_t proc_info_read(struct file * file, char * buf,
@@ -259,10 +255,6 @@
 	read:		proc_info_read,
 };
 
-static struct inode_operations proc_info_inode_operations = {
-	&proc_info_file_operations,  /* default proc file-ops */
-};
-
 #define MAY_PTRACE(p) \
 (p==current||(p->p_pptr==current&&(p->flags&PF_PTRACED)&&p->state==TASK_STOPPED))
 
@@ -350,21 +342,7 @@
 };
 
 static struct inode_operations proc_mem_inode_operations = {
-	&proc_mem_operations,	/* default base directory file-ops */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* truncate */
-	proc_permission,	/* permission */
-	NULL			/* revalidate */
+	permission:	proc_permission,
 };
 
 static struct dentry * proc_pid_follow_link(struct dentry *dentry,
@@ -453,14 +431,6 @@
 	follow_link:	proc_pid_follow_link
 };
 
-/* reading from directory - bad */
-
-static ssize_t proc_dir_read (struct file * filp, char * buf,
-			      size_t count, loff_t *ppos)
-{
-	return -EISDIR;
-}
-
 struct pid_entry {
 	int type;
 	int len;
@@ -744,28 +714,16 @@
 }
 
 static struct file_operations proc_fd_operations = {
-	read: proc_dir_read,		/* read - bad */
-	readdir: proc_readfd,		/* readdir */
+	read:		generic_read_dir,
+	readdir:	proc_readfd,
 };
 
 /*
  * proc directories can do almost nothing..
  */
 static struct inode_operations proc_fd_inode_operations = {
-	&proc_fd_operations,	/* default base directory file-ops */
-	NULL,			/* create */
-	proc_lookupfd,		/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* truncate */
-	proc_permission,	/* permission */
+	lookup:		proc_lookupfd,
+	permission:	proc_permission,
 };
 
 static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
@@ -801,6 +759,7 @@
 		case PROC_PID_FD:
 			inode->i_nlink = 2;
 			inode->i_op = &proc_fd_inode_operations;
+			inode->i_fop = &proc_fd_operations;
 			break;
 		case PROC_PID_EXE:
 			inode->i_op = &proc_pid_link_inode_operations;
@@ -815,36 +774,37 @@
 			inode->u.proc_i.op.proc_get_link = proc_root_link;
 			break;
 		case PROC_PID_ENVIRON:
-			inode->i_op = &proc_info_inode_operations;
+			inode->i_fop = &proc_info_file_operations;
 			inode->u.proc_i.op.proc_read = proc_pid_environ;
 			break;
 		case PROC_PID_STATUS:
-			inode->i_op = &proc_info_inode_operations;
+			inode->i_fop = &proc_info_file_operations;
 			inode->u.proc_i.op.proc_read = proc_pid_status;
 			break;
 		case PROC_PID_STAT:
-			inode->i_op = &proc_info_inode_operations;
+			inode->i_fop = &proc_info_file_operations;
 			inode->u.proc_i.op.proc_read = proc_pid_stat;
 			break;
 		case PROC_PID_CMDLINE:
-			inode->i_op = &proc_info_inode_operations;
+			inode->i_fop = &proc_info_file_operations;
 			inode->u.proc_i.op.proc_read = proc_pid_cmdline;
 			break;
 		case PROC_PID_STATM:
-			inode->i_op = &proc_info_inode_operations;
+			inode->i_fop = &proc_info_file_operations;
 			inode->u.proc_i.op.proc_read = proc_pid_statm;
 			break;
 		case PROC_PID_MAPS:
-			inode->i_op = &proc_maps_inode_operations;
+			inode->i_fop = &proc_maps_operations;
 			break;
 #ifdef __SMP__
 		case PROC_PID_CPU:
-			inode->i_op = &proc_info_inode_operations;
+			inode->i_fop = &proc_info_file_operations;
 			inode->u.proc_i.op.proc_read = proc_pid_cpu;
 			break;
 #endif
 		case PROC_PID_MEM:
 			inode->i_op = &proc_mem_inode_operations;
+			inode->i_fop = &proc_mem_operations;
 			break;
 		default:
 			printk("procfs: impossible type (%d)",p->type);
@@ -860,14 +820,12 @@
 }
 
 static struct file_operations proc_base_operations = {
-	read: proc_dir_read,		/* read - bad */
-	readdir: proc_base_readdir,	/* readdir */
+	read:		generic_read_dir,
+	readdir:	proc_base_readdir,
 };
 
 static struct inode_operations proc_base_inode_operations = {
-	&proc_base_operations,	/* default base directory file-ops */
-	NULL,			/* create */
-	proc_base_lookup,	/* lookup */
+	lookup:		proc_base_lookup,
 };
 
 struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
@@ -910,6 +868,7 @@
 		goto out;
 	inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
 	inode->i_op = &proc_base_inode_operations;
+	inode->i_fop = &proc_base_operations;
 	inode->i_nlink = 3;
 	inode->i_flags|=S_IMMUTABLE;
 
diff -u --recursive --new-file v2.3.47/linux/fs/proc/generic.c linux/fs/proc/generic.c
--- v2.3.47/linux/fs/proc/generic.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/proc/generic.c	Sat Feb 26 20:33:07 2000
@@ -37,10 +37,6 @@
 	write:		proc_file_write,
 };
 
-static struct inode_operations proc_file_inode_operations = {
-	&proc_file_operations,  /* default proc file-ops */
-};
-
 #ifndef MIN
 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
 #endif
@@ -343,10 +339,8 @@
 /*
  * proc directories can do almost nothing..
  */
-struct inode_operations proc_dir_inode_operations = {
-	&proc_dir_operations,	/* default net directory file-ops */
-	NULL,			/* create */
-	proc_lookup,		/* lookup */
+static struct inode_operations proc_dir_inode_operations = {
+	lookup:		proc_lookup,
 };
 
 int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
@@ -361,15 +355,17 @@
 	dp->parent = dir;
 	dir->subdir = dp;
 	if (S_ISDIR(dp->mode)) {
-		if (dp->ops == NULL)
-			dp->ops = &proc_dir_inode_operations;
+		if (dp->proc_iops == NULL) {
+			dp->proc_fops = &proc_dir_operations;
+			dp->proc_iops = &proc_dir_inode_operations;
+		}
 		dir->nlink++;
 	} else if (S_ISLNK(dp->mode)) {
-		if (dp->ops == NULL)
-			dp->ops = &proc_link_inode_operations;
+		if (dp->proc_iops == NULL)
+			dp->proc_iops = &proc_link_inode_operations;
 	} else if (S_ISREG(dp->mode)) {
-		if (dp->ops == NULL)
-			dp->ops = &proc_file_inode_operations;
+		if (dp->proc_fops == NULL)
+			dp->proc_fops = &proc_file_operations;
 	}
 	return 0;
 }
@@ -490,7 +486,8 @@
 	memcpy(((char *) ent) + sizeof(*ent), fn, len + 1);
 	ent->name = ((char *) ent) + sizeof(*ent);
 	ent->namelen = len;
-	ent->ops = &proc_dir_inode_operations;
+	ent->proc_fops = &proc_dir_operations;
+	ent->proc_iops = &proc_dir_inode_operations;
 	ent->nlink = 2;
 	ent->mode = S_IFDIR | S_IRUGO | S_IXUGO;
 
@@ -522,7 +519,8 @@
 	if (S_ISDIR(mode)) {
 		if ((mode & S_IALLUGO) == 0)
 		mode |= S_IRUGO | S_IXUGO;
-		ent->ops = &proc_dir_inode_operations;
+		ent->proc_fops = &proc_dir_operations;
+		ent->proc_iops = &proc_dir_inode_operations;
 		ent->nlink = 2;
 	} else {
 		if ((mode & S_IFMT) == 0)
diff -u --recursive --new-file v2.3.47/linux/fs/proc/inode.c linux/fs/proc/inode.c
--- v2.3.47/linux/fs/proc/inode.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/proc/inode.c	Sat Feb 26 20:33:07 2000
@@ -95,10 +95,6 @@
 	*p = (struct super_block *)(*p)->u.generic_sbp;
 }
 
-static void proc_write_inode(struct inode * inode)
-{
-}
-
 static void proc_read_inode(struct inode * inode)
 {
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
@@ -120,15 +116,11 @@
 }
 
 static struct super_operations proc_sops = { 
-	proc_read_inode,
-	proc_write_inode,
-	proc_put_inode,
-	proc_delete_inode,	/* delete_inode(struct inode *) */
-	NULL,
-	proc_put_super,
-	NULL,
-	proc_statfs,
-	NULL
+	read_inode:	proc_read_inode,
+	put_inode:	proc_put_inode,
+	delete_inode:	proc_delete_inode,
+	put_super:	proc_put_super,
+	statfs:		proc_statfs,
 };
 
 
@@ -195,8 +187,12 @@
 			__MOD_INC_USE_COUNT(de->owner);
 		if (S_ISBLK(de->mode)||S_ISCHR(de->mode)||S_ISFIFO(de->mode))
 			init_special_inode(inode,de->mode,kdev_t_to_nr(de->rdev));
-		else if (de->ops)
-			inode->i_op = de->ops;
+		else {
+			if (de->proc_iops)
+				inode->i_op = de->proc_iops;
+			if (de->proc_fops)
+				inode->i_fop = de->proc_fops;
+		}
 	}
 
 out:
diff -u --recursive --new-file v2.3.47/linux/fs/proc/kcore.c linux/fs/proc/kcore.c
--- v2.3.47/linux/fs/proc/kcore.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/proc/kcore.c	Sat Feb 26 20:33:07 2000
@@ -26,15 +26,11 @@
 
 static ssize_t read_kcore(struct file *, char *, size_t, loff_t *);
 
-static struct file_operations proc_kcore_operations = {
+struct file_operations proc_kcore_operations = {
 	read:		read_kcore,
 	open:		open_kcore,
 };
 
-struct inode_operations proc_kcore_inode_operations = {
-	&proc_kcore_operations,
-};
-
 #ifdef CONFIG_KCORE_AOUT
 static ssize_t read_kcore(struct file *file, char *buf, size_t count, loff_t *ppos)
 {
@@ -323,7 +319,7 @@
 	 * and after elf_kcore_store_hdr() returns.
 	 * For now assume that num_vma does not change (TA)
 	 */
-	proc_root_kcore.size = size = get_kcore_size(&num_vma, &elf_buflen);
+	proc_root_kcore->size = size = get_kcore_size(&num_vma, &elf_buflen);
 	if (buflen == 0 || *fpos >= size)
 		return 0;
 
diff -u --recursive --new-file v2.3.47/linux/fs/proc/kmsg.c linux/fs/proc/kmsg.c
--- v2.3.47/linux/fs/proc/kmsg.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/proc/kmsg.c	Sat Feb 26 20:33:07 2000
@@ -45,13 +45,9 @@
 }
 
 
-static struct file_operations proc_kmsg_operations = {
+struct file_operations proc_kmsg_operations = {
 	read:		kmsg_read,
 	poll:		kmsg_poll,
 	open:		kmsg_open,
 	release:	kmsg_release,
-};
-
-struct inode_operations proc_kmsg_inode_operations = {
-	&proc_kmsg_operations,	/* default base directory file-ops */
 };
diff -u --recursive --new-file v2.3.47/linux/fs/proc/proc_misc.c linux/fs/proc/proc_misc.c
--- v2.3.47/linux/fs/proc/proc_misc.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/proc/proc_misc.c	Sat Feb 26 20:33:07 2000
@@ -597,28 +597,11 @@
 	write:		write_profile,
 };
 
-static struct inode_operations proc_profile_inode_operations = {
-	&proc_profile_operations,
-};
-
-static struct proc_dir_entry proc_root_kmsg = {
-	0, 4, "kmsg",
-	S_IFREG | S_IRUSR, 1, 0, 0,
-	0, &proc_kmsg_inode_operations
-};
-struct proc_dir_entry proc_root_kcore = {
-	0, 5, "kcore",
-	S_IFREG | S_IRUSR, 1, 0, 0,
-	0, &proc_kcore_inode_operations
-};
-static struct proc_dir_entry proc_root_profile = {
-	0, 7, "profile",
-	S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
-	0, &proc_profile_inode_operations
-};
+struct proc_dir_entry *proc_root_kcore;
 
 void __init proc_misc_init(void)
 {
+	struct proc_dir_entry *entry;
 	static struct {
 		char *name;
 		int (*read_proc)(char*,char**,off_t,int,int*,void*);
@@ -664,11 +647,25 @@
 		create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
 
 	/* And now for trickier ones */
-	proc_register(&proc_root, &proc_root_kmsg);
-	proc_register(&proc_root, &proc_root_kcore);
-	proc_root_kcore.size = (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
+	entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
+	if (entry)
+		entry->proc_fops = &proc_kmsg_operations;
+	proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
+	if (proc_root_kcore) {
+		proc_root_kcore->proc_fops = &proc_kcore_operations;
+		proc_root_kcore->size =
+				(size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
+	}
 	if (prof_shift) {
-		proc_register(&proc_root, &proc_root_profile);
-		proc_root_profile.size = (1+prof_len) * sizeof(unsigned int);
+		entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL);
+		if (entry) {
+			entry->proc_fops = &proc_profile_operations;
+			entry->size = (1+prof_len) * sizeof(unsigned int);
+		}
 	}
+#ifdef __powerpc__
+	entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL);
+	if (entry)
+		entry->proc_fops = &ppc_htab_operations;
+#endif
 }
diff -u --recursive --new-file v2.3.47/linux/fs/proc/root.c linux/fs/proc/root.c
--- v2.3.47/linux/fs/proc/root.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/proc/root.c	Sat Feb 26 20:33:07 2000
@@ -51,13 +51,6 @@
 	S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, 1, 0, 0,
 	64, &proc_self_inode_operations,
 };
-#ifdef __powerpc__
-static struct proc_dir_entry proc_root_ppc_htab = {
-	0, 8, "ppc_htab",
-	S_IFREG | S_IRUGO|S_IWUSR, 1, 0, 0,
-	0, &proc_ppc_htab_inode_operations,
-};
-#endif
 
 void __init proc_root_init(void)
 {
@@ -143,16 +136,14 @@
  * directory handling functions for that..
  */
 static struct file_operations proc_root_operations = {
-	readdir: proc_root_readdir,
+	readdir:	 proc_root_readdir,
 };
 
 /*
  * proc root can do almost nothing..
  */
 static struct inode_operations proc_root_inode_operations = {
-	&proc_root_operations,	/* default base directory file-ops */
-	NULL,			/* create */
-	proc_root_lookup,	/* lookup */
+	lookup:		proc_root_lookup,
 };
 
 /*
@@ -161,7 +152,7 @@
 struct proc_dir_entry proc_root = {
 	PROC_ROOT_INO, 5, "/proc",
 	S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
-	0, &proc_root_inode_operations,
+	0, &proc_root_inode_operations, &proc_root_operations,
 	NULL, NULL,
 	NULL,
 	&proc_root, NULL
diff -u --recursive --new-file v2.3.47/linux/fs/qnx4/dir.c linux/fs/qnx4/dir.c
--- v2.3.47/linux/fs/qnx4/dir.c	Tue Feb  1 01:35:44 2000
+++ linux/fs/qnx4/dir.c	Sat Feb 26 20:33:07 2000
@@ -78,21 +78,19 @@
 	return 0;
 }
 
-static struct file_operations qnx4_dir_operations =
+struct file_operations qnx4_dir_operations =
 {
-	readdir:		qnx4_readdir,
-	fsync:			file_fsync,
+	read:		generic_read_dir,
+	readdir:	qnx4_readdir,
+	fsync:		file_fsync,
 };
 
 struct inode_operations qnx4_dir_inode_operations =
 {
-	default_file_ops:	&qnx4_dir_operations,
+	lookup:		qnx4_lookup,
 #ifdef CONFIG_QNX4FS_RW
-	create:			qnx4_create,
-#endif
-	lookup:			qnx4_lookup,
-#ifdef CONFIG_QNX4FS_RW
-	unlink:			qnx4_unlink,
-	rmdir:			qnx4_rmdir,
+	create:		qnx4_create,
+	unlink:		qnx4_unlink,
+	rmdir:		qnx4_rmdir,
 #endif
 };
diff -u --recursive --new-file v2.3.47/linux/fs/qnx4/file.c linux/fs/qnx4/file.c
--- v2.3.47/linux/fs/qnx4/file.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/qnx4/file.c	Sat Feb 26 20:33:07 2000
@@ -22,7 +22,7 @@
  * We have mostly NULL's here: the current defaults are ok for
  * the qnx4 filesystem.
  */
-static struct file_operations qnx4_file_operations =
+struct file_operations qnx4_file_operations =
 {
 	read:			generic_file_read,
 #ifdef CONFIG_QNX4FS_RW
@@ -36,7 +36,6 @@
 
 struct inode_operations qnx4_file_inode_operations =
 {
-	default_file_ops:	&qnx4_file_operations,
 #ifdef CONFIG_QNX4FS_RW
 	truncate:		qnx4_truncate,
 #endif
diff -u --recursive --new-file v2.3.47/linux/fs/qnx4/inode.c linux/fs/qnx4/inode.c
--- v2.3.47/linux/fs/qnx4/inode.c	Sat Feb 12 11:22:11 2000
+++ linux/fs/qnx4/inode.c	Sat Feb 26 20:33:07 2000
@@ -231,7 +231,7 @@
 		block = le32_to_cpu(qnx4_inode->i_first_xtnt.xtnt_blk) + iblock - 1;
 	} else {
 		// iblock is beyond first extent. We have to follow the extent chain.
-		i_xblk = qnx4_inode->i_xblk;
+		i_xblk = le32_to_cpu(qnx4_inode->i_xblk);
 		offset = iblock - le32_to_cpu(qnx4_inode->i_first_xtnt.xtnt_size);
 		ix = 0;
 		while ( --nxtnt > 0 ) {
@@ -455,7 +455,6 @@
 	int block, ino;
 
 	ino = inode->i_ino;
-	inode->i_op = NULL;
 	inode->i_mode = 0;
 
 	QNX4DEBUG(("Reading inode : [%d]\n", ino));
@@ -488,11 +487,13 @@
 	memcpy(&inode->u.qnx4_i, (struct qnx4_inode_info *) raw_inode, QNX4_DIR_ENTRY_SIZE);
 	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &qnx4_file_inode_operations;
+		inode->i_fop = &qnx4_file_operations;
 		inode->i_mapping->a_ops = &qnx4_aops;
 		inode->u.qnx4_i.mmu_private = inode->i_size;
-	} else if (S_ISDIR(inode->i_mode))
+	} else if (S_ISDIR(inode->i_mode)) {
 		inode->i_op = &qnx4_dir_inode_operations;
-	else if (S_ISLNK(inode->i_mode)) {
+		inode->i_fop = &qnx4_dir_operations;
+	} else if (S_ISLNK(inode->i_mode)) {
 		inode->i_op = &page_symlink_inode_operations;
 		inode->i_mapping->a_ops = &qnx4_aops;
 		inode->u.qnx4_i.mmu_private = inode->i_size;
diff -u --recursive --new-file v2.3.47/linux/fs/read_write.c linux/fs/read_write.c
--- v2.3.47/linux/fs/read_write.c	Sat Feb 12 11:22:11 2000
+++ linux/fs/read_write.c	Sat Feb 26 20:33:07 2000
@@ -13,6 +13,16 @@
 
 #include <asm/uaccess.h>
 
+struct file_operations generic_ro_fops = {
+	read:		generic_file_read,
+	mmap:		generic_file_mmap,
+};
+
+ssize_t generic_read_dir(struct file *filp, char *buf, size_t siz, loff_t *ppos)
+{
+	return -EISDIR;
+}
+
 loff_t default_llseek(struct file *file, loff_t offset, int origin)
 {
 	long long retval;
diff -u --recursive --new-file v2.3.47/linux/fs/romfs/inode.c linux/fs/romfs/inode.c
--- v2.3.47/linux/fs/romfs/inode.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/romfs/inode.c	Sat Feb 26 20:33:08 2000
@@ -450,27 +450,13 @@
 	readpage: romfs_readpage
 };
 
-static struct file_operations romfs_file_operations = {
-	read:		generic_file_read,
-	mmap:		generic_file_mmap,
-};
-
-static struct inode_operations romfs_file_inode_operations = {
-	&romfs_file_operations,
-};
-
 static struct file_operations romfs_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	romfs_readdir,
 };
 
-/* Merged dir/symlink op table.  readdir/lookup/readlink/follow_link
- * will protect from type mismatch.
- */
-
 static struct inode_operations romfs_dir_inode_operations = {
-	&romfs_dir_operations,
-	NULL,			/* create */
-	romfs_lookup,		/* lookup */
+	lookup:		romfs_lookup,
 };
 
 static mode_t romfs_modemap[] =
@@ -479,18 +465,6 @@
 	S_IFBLK+0600, S_IFCHR+0600, S_IFSOCK+0644, S_IFIFO+0644
 };
 
-static struct inode_operations *romfs_inoops[] =
-{
-	NULL,				/* hardlink, handled elsewhere */
-	&romfs_dir_inode_operations,
-	&romfs_file_inode_operations,
-	&page_symlink_inode_operations,
-	NULL,				/* device/fifo/socket nodes, */
-	NULL,				/*   set by init_special_inode */
-	NULL,
-	NULL,
-};
-
 static void
 romfs_read_inode(struct inode *i)
 {
@@ -498,7 +472,6 @@
 	struct romfs_inode ri;
 
 	ino = i->i_ino & ROMFH_MASK;
-	i->i_op = NULL;
 	i->i_mode = 0;
 
 	/* Loop for finding the real hard link */
@@ -534,32 +507,38 @@
         /* Compute permissions */
         ino = romfs_modemap[nextfh & ROMFH_TYPE];
 	/* only "normal" files have ops */
-        if ((i->i_op = romfs_inoops[nextfh & ROMFH_TYPE])) {
-		if (nextfh & ROMFH_EXEC)
-			ino |= S_IXUGO;
-		i->i_mode = ino;
-		if (S_ISDIR(ino))
+	switch (nextfh & ROMFH_TYPE) {
+		case 1:
 			i->i_size = i->u.romfs_i.i_metasize;
-		else
+			i->i_op = &romfs_dir_inode_operations;
+			i->i_fop = &romfs_dir_operations;
+			if (nextfh & ROMFH_EXEC)
+				ino |= S_IXUGO;
+			i->i_mode = ino;
+			break;
+		case 2:
+			i->i_fop = &generic_ro_fops;
 			i->i_data.a_ops = &romfs_aops;
-	} else {
-		/* depending on MBZ for sock/fifos */
-		nextfh = ntohl(ri.spec);
-		nextfh = kdev_t_to_nr(MKDEV(nextfh>>16,nextfh&0xffff));
-		init_special_inode(i, ino, nextfh);
+			if (nextfh & ROMFH_EXEC)
+				ino |= S_IXUGO;
+			i->i_mode = ino;
+			break;
+		case 3:
+			i->i_op = &page_symlink_inode_operations;
+			i->i_mode = S_IRWXUGO;
+			break;
+		default:
+			/* depending on MBZ for sock/fifos */
+			nextfh = ntohl(ri.spec);
+			nextfh = kdev_t_to_nr(MKDEV(nextfh>>16,nextfh&0xffff));
+			init_special_inode(i, ino, nextfh);
 	}
 }
 
 static struct super_operations romfs_ops = {
-	romfs_read_inode,	/* read inode */
-	NULL,			/* write inode */
-	NULL,			/* put inode */
-	NULL,			/* delete inode */
-	NULL,			/* notify change */
-	romfs_put_super,	/* put super */
-	NULL,			/* write super */
-	romfs_statfs,		/* statfs */
-	NULL			/* remount */
+	read_inode:	romfs_read_inode,
+	put_super:	romfs_put_super,
+	statfs:		romfs_statfs,
 };
 
 static struct file_system_type romfs_fs_type = {
diff -u --recursive --new-file v2.3.47/linux/fs/smbfs/dir.c linux/fs/smbfs/dir.c
--- v2.3.47/linux/fs/smbfs/dir.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/smbfs/dir.c	Sat Feb 26 20:33:42 2000
@@ -18,7 +18,6 @@
 /* #define pr_debug printk */
 #define SMBFS_MAX_AGE 5*HZ
 
-static ssize_t smb_dir_read(struct file *, char *, size_t, loff_t *);
 static int smb_readdir(struct file *, void *, filldir_t);
 static int smb_dir_open(struct inode *, struct file *);
 
@@ -30,9 +29,9 @@
 static int smb_rename(struct inode *, struct dentry *,
 		      struct inode *, struct dentry *);
 
-static struct file_operations smb_dir_operations =
+struct file_operations smb_dir_operations =
 {
-	read:		smb_dir_read,
+	read:		generic_read_dir,
 	readdir:	smb_readdir,
 	ioctl:		smb_ioctl,
 	open:		smb_dir_open,
@@ -40,28 +39,15 @@
 
 struct inode_operations smb_dir_inode_operations =
 {
-	&smb_dir_operations,	/* default directory file ops */
-	smb_create,		/* create */
-	smb_lookup,		/* lookup */
-	NULL,			/* link */
-	smb_unlink,		/* unlink */
-	NULL,			/* symlink */
-	smb_mkdir,		/* mkdir */
-	smb_rmdir,		/* rmdir */
-	NULL,			/* mknod */
-	smb_rename,		/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	smb_revalidate_inode,	/* revalidate */
+	create:		smb_create,
+	lookup:		smb_lookup,
+	unlink:		smb_unlink,
+	mkdir:		smb_mkdir,
+	rmdir:		smb_rmdir,
+	rename:		smb_rename,
+	revalidate:	smb_revalidate_inode,
+	setattr:	smb_notify_change,
 };
-
-static ssize_t
-smb_dir_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
-{
-	return -EISDIR;
-}
 
 static int 
 smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
diff -u --recursive --new-file v2.3.47/linux/fs/smbfs/file.c linux/fs/smbfs/file.c
--- v2.3.47/linux/fs/smbfs/file.c	Thu Feb 10 17:11:18 2000
+++ linux/fs/smbfs/file.c	Sat Feb 26 20:33:42 2000
@@ -169,17 +169,25 @@
 static int
 smb_writepage(struct dentry *dentry, struct page *page)
 {
-	int 	result;
-
-#ifdef SMBFS_PARANOIA
-	if (!PageLocked(page))
-		printk("smb_writepage: page not already locked!\n");
-#endif
+	struct inode *inode = dentry->d_inode;
+	unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
+	unsigned offset = PAGE_CACHE_SIZE;
+	int err;
+
+	/* easy case */
+	if (page->index < end_index)
+		goto do_it;
+	/* things got complicated... */
+	offset = inode->i_size & (PAGE_CACHE_SIZE-1);
+	/* OK, are we completely out? */
+	if (page->index >= end_index+1 || !offset)
+		return -EIO;
+do_it:
 	get_page(page);
-	result = smb_writepage_sync(dentry, page, 0, PAGE_SIZE);
+	err = smb_writepage_sync(dentry, page, 0, offset);
 	SetPageUptodate(page);
 	put_page(page);
-	return result;
+	return err;
 }
 
 static int
@@ -376,7 +384,7 @@
 	return error;
 }
 
-static struct file_operations smb_file_operations =
+struct file_operations smb_file_operations =
 {
 	read:		smb_file_read,
 	write:		smb_file_write,
@@ -389,19 +397,7 @@
 
 struct inode_operations smb_file_inode_operations =
 {
-	&smb_file_operations,	/* default file operations */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* truncate */
-	smb_file_permission,	/* permission */
-	smb_revalidate_inode,	/* revalidate */
+	permission:	smb_file_permission,
+	revalidate:	smb_revalidate_inode,
+	setattr:	smb_notify_change,
 };
diff -u --recursive --new-file v2.3.47/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c
--- v2.3.47/linux/fs/smbfs/inode.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/smbfs/inode.c	Sat Feb 26 20:33:42 2000
@@ -29,7 +29,6 @@
 #define SMBFS_PARANOIA 1
 /* #define SMBFS_DEBUG_VERBOSE 1 */
 
-static void smb_read_inode(struct inode *);
 static void smb_put_inode(struct inode *);
 static void smb_delete_inode(struct inode *);
 static void smb_put_super(struct super_block *);
@@ -38,15 +37,10 @@
 
 static struct super_operations smb_sops =
 {
-	smb_read_inode,		/* read inode */
-	NULL,			/* write inode */
-	smb_put_inode,		/* put inode */
-	smb_delete_inode,	/* delete inode */
-	smb_notify_change,	/* notify change */
-	smb_put_super,		/* put superblock */
-	NULL,			/* write superblock */
-	smb_statfs,		/* stat filesystem */
-	NULL			/* remount filesystem */
+	put_inode:	smb_put_inode,
+	delete_inode:	smb_delete_inode,
+	put_super:	smb_put_super,
+	statfs:		smb_statfs,
 };
 
 /* FIXME: Look at all inodes whether so that we do not get duplicate
@@ -84,11 +78,12 @@
 	smb_set_inode_attr(result, fattr);
 	if (S_ISREG(result->i_mode)) {
 		result->i_op = &smb_file_inode_operations;
+		result->i_fop = &smb_file_operations;
 		result->i_data.a_ops = &smb_file_aops;
-	} else if (S_ISDIR(result->i_mode))
+	} else if (S_ISDIR(result->i_mode)) {
 		result->i_op = &smb_dir_inode_operations;
-	else
-		result->i_op = NULL;
+		result->i_fop = &smb_dir_operations;
+	}
 	insert_inode_hash(result);
 	return result;
 }
@@ -150,14 +145,6 @@
 	 * Update the "last time refreshed" field for revalidation.
 	 */
 	inode->u.smbfs_i.oldmtime = jiffies;
-}
-
-static void
-smb_read_inode(struct inode *inode)
-{
-	/* Now it can be called only by NFS */
-	printk("smb_read_inode called from invalid point\n");
-	return;
 }
 
 /*
diff -u --recursive --new-file v2.3.47/linux/fs/smbfs/sock.c linux/fs/smbfs/sock.c
--- v2.3.47/linux/fs/smbfs/sock.c	Sat Feb 28 13:29:35 1998
+++ linux/fs/smbfs/sock.c	Sat Feb 26 08:17:28 2000
@@ -15,6 +15,7 @@
 #include <linux/net.h>
 #include <linux/mm.h>
 #include <linux/netdevice.h>
+#include <linux/smp_lock.h>
 #include <net/scm.h>
 #include <net/ip.h>
 
@@ -79,13 +80,33 @@
 	return err;
 }
 
+struct data_callback {
+	struct tq_struct cb;
+	struct sock *sk;
+};
 /*
  * N.B. What happens if we're in here when the socket closes??
  */
 static void
-smb_data_callback(struct sock *sk, int len)
+found_data(struct sock *sk)
 {
-	struct socket *socket = sk->socket;
+	/*
+	 * FIXME: copied from sock_def_readable, it should be a call to
+	 * server->data_ready()	-- manfreds@colorfullife.com
+	 */
+	read_lock(&sk->callback_lock);
+	if(!sk->dead) {
+		wake_up_interruptible(sk->sleep);
+		sock_wake_async(sk->socket,1,POLL_IN);
+	}
+	read_unlock(&sk->callback_lock);
+}
+
+static void
+smb_data_callback(void* ptr)
+{
+	struct data_callback* job=ptr;
+	struct socket *socket = job->sk->socket;
 	unsigned char peek_buf[4];
 	int result;
 	mm_segment_t fs;
@@ -93,10 +114,11 @@
 	fs = get_fs();
 	set_fs(get_ds());
 
+	lock_kernel();
 	while (1)
 	{
 		result = -EIO;
-		if (sk->dead)
+		if (job->sk->dead)
 		{
 #ifdef SMBFS_PARANOIA
 			printk("smb_data_callback: sock dead!\n");
@@ -120,12 +142,30 @@
 		if (result == -EAGAIN)
 			break;
 	}
+	unlock_kernel();
 	set_fs(fs);
 
 	if (result != -EAGAIN)
-	{
-		wake_up_interruptible(sk->sleep);
+		found_data(job->sk);
+	kfree(ptr);
+}
+
+static void
+smb_data_ready(struct sock *sk, int len)
+{
+	struct data_callback* job;
+	job = kmalloc(sizeof(struct data_callback),GFP_ATOMIC);
+	if(job == 0) {
+		printk("smb_data_ready(): lost SESSION KEEPALIVE due to OOM.\n");
+		found_data(sk);
+		return;
 	}
+	job->cb.next = NULL;
+	job->cb.sync = 0;
+	job->cb.routine = smb_data_callback;
+	job->cb.data = job;
+	job->sk = sk;
+	queue_task(&job->cb, &tq_scheduler);
 }
 
 int
@@ -182,8 +222,8 @@
 	/*
 	 * Install the callback atomically to avoid races ...
 	 */
-	data_ready = xchg(&sk->data_ready, smb_data_callback);
-	if (data_ready != smb_data_callback)
+	data_ready = xchg(&sk->data_ready, smb_data_ready);
+	if (data_ready != smb_data_ready)
 	{
 		server->data_ready = data_ready;
 		error = 0;
@@ -232,10 +272,10 @@
 	 */
 	data_ready = xchg(&sk->data_ready, server->data_ready);
 	server->data_ready = NULL;
-	if (data_ready != smb_data_callback)
+	if (data_ready != smb_data_ready)
 	{
 		printk("smb_dont_catch_keepalive: "
-		       "sk->data_callback != smb_data_callback\n");
+		       "sk->data_ready != smb_data_ready\n");
 	}
 	error = 0;
 out:
@@ -256,7 +296,7 @@
 printk("smb_close_socket: closing socket %p\n", server_sock(server));
 #endif
 #ifdef SMBFS_PARANOIA
-if (server_sock(server)->sk->data_ready == smb_data_callback)
+if (server_sock(server)->sk->data_ready == smb_data_ready)
 printk("smb_close_socket: still catching keepalives!\n");
 #endif
 		server->sock_file = NULL;
diff -u --recursive --new-file v2.3.47/linux/fs/super.c linux/fs/super.c
--- v2.3.47/linux/fs/super.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/super.c	Mon Feb 21 13:50:09 2000
@@ -1143,7 +1143,7 @@
 			sb->s_bdev = NULL;
 			sb->s_flags = root_mountflags;
 			sema_init(&sb->s_vfs_rename_sem,1);
-			sema_init(&s->s_nfsd_free_path_sem,1);
+			sema_init(&sb->s_nfsd_free_path_sem,1);
 			vfsmnt = add_vfsmnt(sb, "/dev/root", "/");
 			if (vfsmnt) {
 				if (nfs_root_mount(sb) >= 0) {
diff -u --recursive --new-file v2.3.47/linux/fs/sysv/dir.c linux/fs/sysv/dir.c
--- v2.3.47/linux/fs/sysv/dir.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/sysv/dir.c	Sat Feb 26 20:33:08 2000
@@ -19,36 +19,12 @@
 #include <linux/stat.h>
 #include <linux/string.h>
 
-#include <asm/uaccess.h>
-
-static ssize_t sysv_dir_read(struct file * filp, char * buf,
-			     size_t count, loff_t *ppos)
-{
-	return -EISDIR;
-}
-
 static int sysv_readdir(struct file *, void *, filldir_t);
 
-static struct file_operations sysv_dir_operations = {
-	read:		sysv_dir_read,
+struct file_operations sysv_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	sysv_readdir,
 	fsync:		file_fsync,
-};
-
-/*
- * directories can handle most operations...
- */
-struct inode_operations sysv_dir_inode_operations = {
-	&sysv_dir_operations,	/* default directory file-ops */
-	sysv_create,		/* create */
-	sysv_lookup,		/* lookup */
-	sysv_link,		/* link */
-	sysv_unlink,		/* unlink */
-	sysv_symlink,		/* symlink */
-	sysv_mkdir,		/* mkdir */
-	sysv_rmdir,		/* rmdir */
-	sysv_mknod,		/* mknod */
-	sysv_rename,		/* rename */
 };
 
 static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
diff -u --recursive --new-file v2.3.47/linux/fs/sysv/file.c linux/fs/sysv/file.c
--- v2.3.47/linux/fs/sysv/file.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/sysv/file.c	Sat Feb 26 20:33:43 2000
@@ -13,21 +13,14 @@
  *  SystemV/Coherent regular file handling primitives
  */
 
-#include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/sysv_fs.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/string.h>
-#include <linux/locks.h>
-#include <linux/pagemap.h>
 
 /*
  * We have mostly NULLs here: the current defaults are OK for
  * the coh filesystem.
  */
-static struct file_operations sysv_file_operations = {
+struct file_operations sysv_file_operations = {
 	read:		generic_file_read,
 	write:		generic_file_write,
 	mmap:		generic_file_mmap,
@@ -35,6 +28,6 @@
 };
 
 struct inode_operations sysv_file_inode_operations = {
-	&sysv_file_operations,
 	truncate:	sysv_truncate,
+	setattr:	sysv_notify_change,
 };
diff -u --recursive --new-file v2.3.47/linux/fs/sysv/ialloc.c linux/fs/sysv/ialloc.c
--- v2.3.47/linux/fs/sysv/ialloc.c	Sun Mar 21 07:11:37 1999
+++ linux/fs/sysv/ialloc.c	Sat Feb 26 20:33:08 2000
@@ -156,7 +156,6 @@
 	inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
 	inode->i_ino = ino;
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-	inode->i_op = NULL;
 	inode->i_blocks = inode->i_blksize = 0;
 	insert_inode_hash(inode);
 	mark_inode_dirty(inode);
diff -u --recursive --new-file v2.3.47/linux/fs/sysv/inode.c linux/fs/sysv/inode.c
--- v2.3.47/linux/fs/sysv/inode.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/sysv/inode.c	Sat Feb 26 20:33:43 2000
@@ -68,19 +68,15 @@
 static void sysv_put_super(struct super_block *);
 static void sysv_write_super(struct super_block *);
 static void sysv_read_inode(struct inode *);
-static int sysv_notify_change(struct dentry *, struct iattr *);
 static int sysv_statfs(struct super_block *, struct statfs *, int);
 
 static struct super_operations sysv_sops = {
-	sysv_read_inode,
-	sysv_write_inode,
-	NULL,			/* nothing special on put_inode() */
-	sysv_delete_inode,
-	sysv_notify_change,
-	sysv_put_super,
-	sysv_write_super,
-	sysv_statfs,
-	NULL			/* remount_fs */
+	read_inode:	sysv_read_inode,
+	write_inode:	sysv_write_inode,
+	delete_inode:	sysv_delete_inode,
+	put_super:	sysv_put_super,
+	write_super:	sysv_write_super,
+	statfs:		sysv_statfs,
 };
 
 /* The following functions try to recognize specific filesystems.
@@ -1027,6 +1023,12 @@
 	*(unsigned short *)(p+1) = (unsigned short) val;
 }
 
+struct inode_operations sysv_symlink_inode_operations = {
+	readlink:	page_readlink,
+	follow_link:	page_follow_link,
+	setattr:	sysv_notify_change,
+};
+
 static void sysv_read_inode(struct inode *inode)
 {
 	struct super_block * sb = inode->i_sb;
@@ -1036,7 +1038,6 @@
 	umode_t mode;
 
 	ino = inode->i_ino;
-	inode->i_op = NULL;
 	inode->i_mode = 0;
 	if (!ino || ino > sb->sv_ninodes) {
 		printk("Bad inode number on dev %s"
@@ -1085,11 +1086,13 @@
 				read3byte(&raw_inode->i_a.i_addb[3*block]);
 	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &sysv_file_inode_operations;
+		inode->i_fop = &sysv_file_operations;
 		inode->i_mapping->a_ops = &sysv_aops;
-	} else if (S_ISDIR(inode->i_mode))
+	} else if (S_ISDIR(inode->i_mode)) {
 		inode->i_op = &sysv_dir_inode_operations;
-	else if (S_ISLNK(inode->i_mode)) {
-		inode->i_op = &page_symlink_inode_operations;
+		inode->i_fop = &sysv_dir_operations;
+	} else if (S_ISLNK(inode->i_mode)) {
+		inode->i_op = &sysv_symlink_inode_operations;
 		inode->i_mapping->a_ops = &sysv_aops;
 	} else
 		init_special_inode(inode, inode->i_mode,raw_inode->i_a.i_rdev);
@@ -1097,7 +1100,7 @@
 }
 
 /* To avoid inconsistencies between inodes in memory and inodes on disk. */
-static int sysv_notify_change(struct dentry *dentry, struct iattr *attr)
+int sysv_notify_change(struct dentry *dentry, struct iattr *attr)
 {
 	struct inode *inode = dentry->d_inode;
 	int error;
diff -u --recursive --new-file v2.3.47/linux/fs/sysv/namei.c linux/fs/sysv/namei.c
--- v2.3.47/linux/fs/sysv/namei.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/sysv/namei.c	Sat Feb 26 20:33:43 2000
@@ -101,7 +101,7 @@
 	return NULL;
 }
 
-struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry)
+static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry)
 {
 	struct inode * inode = NULL;
 	struct sysv_dir_entry * de;
@@ -193,7 +193,7 @@
 	return 0;
 }
 
-int sysv_create(struct inode * dir, struct dentry * dentry, int mode)
+static int sysv_create(struct inode * dir, struct dentry * dentry, int mode)
 {
 	int error;
 	struct inode * inode;
@@ -204,6 +204,7 @@
 	if (!inode) 
 		return -ENOSPC;
 	inode->i_op = &sysv_file_inode_operations;
+	inode->i_fop = &sysv_file_operations;
 	inode->i_mapping->a_ops = &sysv_aops;
 	inode->i_mode = mode;
 	mark_inode_dirty(inode);
@@ -222,7 +223,7 @@
 	return 0;
 }
 
-int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev)
+static int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev)
 {
 	int error;
 	struct inode * inode;
@@ -256,7 +257,7 @@
 	return 0;
 }
 
-int sysv_mkdir(struct inode * dir, struct dentry *dentry, int mode)
+static int sysv_mkdir(struct inode * dir, struct dentry *dentry, int mode)
 {
 	int error;
 	struct inode * inode;
@@ -275,6 +276,7 @@
 	if (!inode)
 		return -ENOSPC;
 	inode->i_op = &sysv_dir_inode_operations;
+	inode->i_fop = &sysv_dir_operations;
 	inode->i_size = 2 * SYSV_DIRSIZE;
 	dir_block = sysv_file_bread(inode,0,1);
 	if (!dir_block) {
@@ -370,7 +372,7 @@
 	return 1;
 }
 
-int sysv_rmdir(struct inode * dir, struct dentry * dentry)
+static int sysv_rmdir(struct inode * dir, struct dentry * dentry)
 {
 	int retval;
 	struct inode * inode;
@@ -407,7 +409,7 @@
 	return retval;
 }
 
-int sysv_unlink(struct inode * dir, struct dentry * dentry)
+static int sysv_unlink(struct inode * dir, struct dentry * dentry)
 {
 	int retval;
 	struct inode * inode;
@@ -438,7 +440,7 @@
 	return retval;
 }
 
-int sysv_symlink(struct inode * dir, struct dentry * dentry, 
+static int sysv_symlink(struct inode * dir, struct dentry * dentry, 
 		 const char * symname)
 {
 	struct inode * inode;
@@ -456,7 +458,7 @@
 		goto out;
 
 	inode->i_mode = S_IFLNK | 0777;
-	inode->i_op = &page_symlink_inode_operations;
+	inode->i_op = &sysv_symlink_inode_operations;
 	inode->i_mapping->a_ops = &sysv_aops;
 	err = block_symlink(inode, symname, l);
 	if (err)
@@ -479,7 +481,7 @@
 	goto out;
 }
 
-int sysv_link(struct dentry * old_dentry, struct inode * dir, 
+static int sysv_link(struct dentry * old_dentry, struct inode * dir, 
 	      struct dentry * dentry)
 {
 	struct inode *oldinode = old_dentry->d_inode;
@@ -523,7 +525,7 @@
  * Anybody can rename anything with this: the permission checks are left to the
  * higher-level routines.
  */
-int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
+static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
 		  struct inode * new_dir, struct dentry * new_dentry)
 {
 	struct inode * old_inode, * new_inode;
@@ -604,3 +606,19 @@
 	brelse(new_bh);
 	return retval;
 }
+
+/*
+ * directories can handle most operations...
+ */
+struct inode_operations sysv_dir_inode_operations = {
+	create:		sysv_create,
+	lookup:		sysv_lookup,
+	link:		sysv_link,
+	unlink:		sysv_unlink,
+	symlink:	sysv_symlink,
+	mkdir:		sysv_mkdir,
+	rmdir:		sysv_rmdir,
+	mknod:		sysv_mknod,
+	rename:		sysv_rename,
+	setattr:	sysv_notify_change,
+};
diff -u --recursive --new-file v2.3.47/linux/fs/udf/dir.c linux/fs/udf/dir.c
--- v2.3.47/linux/fs/udf/dir.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/udf/dir.c	Sat Feb 26 20:33:08 2000
@@ -49,37 +49,11 @@
 
 /* readdir and lookup functions */
 
-static struct file_operations udf_dir_operations = {
+struct file_operations udf_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	udf_readdir,
 	ioctl:		udf_ioctl,
 	fsync:		udf_sync_file,
-};
-
-struct inode_operations udf_dir_inode_operations = {
-	&udf_dir_operations,
-#if CONFIG_UDF_RW == 1
-	udf_create, 	/* create */
-#else
-	NULL,			/* create */
-#endif
-	udf_lookup,		/* lookup */
-#if CONFIG_UDF_RW == 1
-	udf_link,		/* link */
-	udf_unlink,		/* unlink */
-	udf_symlink,	/* symlink */
-	udf_mkdir,		/* mkdir */
-	udf_rmdir,		/* rmdir */
-	udf_mknod,		/* mknod */
-	udf_rename,		/* rename */
-#else
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-#endif
 };
 
 /*
diff -u --recursive --new-file v2.3.47/linux/fs/udf/file.c linux/fs/udf/file.c
--- v2.3.47/linux/fs/udf/file.c	Sun Feb 20 21:12:39 2000
+++ linux/fs/udf/file.c	Sat Feb 26 20:33:08 2000
@@ -349,7 +349,7 @@
 	return 0;
 }
 
-static struct file_operations udf_file_operations = {
+struct file_operations udf_file_operations = {
 	llseek:		udf_file_llseek,
 	read:		generic_file_read,
 	write:		udf_file_write,
@@ -361,7 +361,6 @@
 };
 
 struct inode_operations udf_file_inode_operations = {
-	&udf_file_operations,
 #if CONFIG_UDF_RW == 1
 	truncate:	udf_truncate,
 #endif
diff -u --recursive --new-file v2.3.47/linux/fs/udf/ialloc.c linux/fs/udf/ialloc.c
--- v2.3.47/linux/fs/udf/ialloc.c	Fri Jan 28 15:09:09 2000
+++ linux/fs/udf/ialloc.c	Sat Feb 26 20:33:08 2000
@@ -151,7 +151,6 @@
 	UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_IN_ICB;
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	UDF_I_UMTIME(inode) = UDF_I_UATIME(inode) = UDF_I_UCTIME(inode) = CURRENT_UTIME;
-	inode->i_op = NULL;
 	insert_inode_hash(inode);
 	mark_inode_dirty(inode);
 	unlock_super(sb);
diff -u --recursive --new-file v2.3.47/linux/fs/udf/inode.c linux/fs/udf/inode.c
--- v2.3.47/linux/fs/udf/inode.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/udf/inode.c	Sat Feb 26 20:33:08 2000
@@ -1077,6 +1077,7 @@
 		case FILE_TYPE_DIRECTORY:
 		{
 			inode->i_op = &udf_dir_inode_operations;
+			inode->i_fop = &udf_dir_operations;
 			inode->i_mode |= S_IFDIR;
 			inode->i_nlink ++;
 			break;
@@ -1089,6 +1090,7 @@
 			else
 				inode->i_data.a_ops = &udf_aops;
 			inode->i_op = &udf_file_inode_operations;
+			inode->i_fop = &udf_file_operations;
 			inode->i_mode |= S_IFREG;
 			break;
 		}
diff -u --recursive --new-file v2.3.47/linux/fs/udf/namei.c linux/fs/udf/namei.c
--- v2.3.47/linux/fs/udf/namei.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/udf/namei.c	Sat Feb 26 20:33:08 2000
@@ -289,7 +289,7 @@
  *	Written, tested, and released.
  */
 
-struct dentry *
+static struct dentry *
 udf_lookup(struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode = NULL;
@@ -631,7 +631,7 @@
 	return udf_write_fi(cfi, fi, fibh, NULL, NULL);
 }
 
-int udf_create(struct inode *dir, struct dentry *dentry, int mode)
+static int udf_create(struct inode *dir, struct dentry *dentry, int mode)
 {
 	struct udf_fileident_bh fibh;
 	struct inode *inode;
@@ -644,6 +644,7 @@
 
 	inode->i_data.a_ops = &udf_adinicb_aops;
 	inode->i_op = &udf_file_inode_operations;
+	inode->i_fop = &udf_file_operations;
 	inode->i_mode = mode;
 	mark_inode_dirty(inode);
 
@@ -672,7 +673,7 @@
 	return 0;
 }
 
-int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev)
+static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev)
 {
 	struct inode * inode;
 	struct udf_fileident_bh fibh;
@@ -686,8 +687,6 @@
 
 	inode->i_uid = current->fsuid;
 	init_special_inode(inode, mode, rdev);
-	inode->i_mode = mode;
-	inode->i_op = NULL;
 	if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
 	{
 		udf_debug("udf_add_entry failure!\n");
@@ -717,7 +716,7 @@
 	return err;
 }
 
-int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
 {
 	struct inode * inode;
 	struct udf_fileident_bh fibh;
@@ -736,6 +735,7 @@
 		goto out;
 
 	inode->i_op = &udf_dir_inode_operations;
+	inode->i_fop = &udf_dir_operations;
 	inode->i_size = (sizeof(struct FileIdentDesc) + 3) & ~3;
 	UDF_I_LENALLOC(inode) = inode->i_size;
 	loc = UDF_I_LOCATION(inode).logicalBlockNum;
@@ -860,7 +860,7 @@
 	return 1;
 }
 
-int udf_rmdir(struct inode * dir, struct dentry * dentry)
+static int udf_rmdir(struct inode * dir, struct dentry * dentry)
 {
 	int retval;
 	struct inode * inode;
@@ -906,7 +906,7 @@
 	return retval;
 }
 
-int udf_unlink(struct inode * dir, struct dentry * dentry)
+static int udf_unlink(struct inode * dir, struct dentry * dentry)
 {
 	int retval;
 	struct inode * inode;
@@ -955,7 +955,7 @@
 	return retval;
 }
 
-int udf_symlink(struct inode * dir, struct dentry * dentry, const char * symname)
+static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * symname)
 {
 	struct inode * inode;
 	struct PathComponent *pc;
@@ -1075,7 +1075,7 @@
 	return err;
 }
 
-int udf_link(struct dentry * old_dentry, struct inode * dir,
+static int udf_link(struct dentry * old_dentry, struct inode * dir,
 	 struct dentry *dentry)
 {
 	struct inode *inode = old_dentry->d_inode;
@@ -1127,7 +1127,7 @@
 /* Anybody can rename anything with this: the permission checks are left to the
  * higher-level routines.
  */
-int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
+static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
 	struct inode * new_dir, struct dentry * new_dentry)
 {
 	struct inode * old_inode, * new_inode;
@@ -1270,3 +1270,17 @@
 	}
 	return retval;
 }
+
+struct inode_operations udf_dir_inode_operations = {
+	lookup:		udf_lookup,
+#if CONFIG_UDF_RW == 1
+	create:		udf_create,
+	link:		udf_link,
+	unlink:		udf_unlink,
+	symlink:	udf_symlink,
+	mkdir:		udf_mkdir,
+	rmdir:		udf_rmdir,
+	mknod:		udf_mknod,
+	rename:		udf_rename,
+#endif
+};
diff -u --recursive --new-file v2.3.47/linux/fs/udf/super.c linux/fs/udf/super.c
--- v2.3.47/linux/fs/udf/super.c	Fri Jan 28 15:09:09 2000
+++ linux/fs/udf/super.c	Sat Feb 26 20:33:08 2000
@@ -105,25 +105,15 @@
 /* Superblock operations */
 static struct super_operations udf_sb_ops =
 {
-	udf_read_inode,		/* read_inode */
+	read_inode:	udf_read_inode,
+	put_inode:	udf_put_inode,
+	put_super:	udf_put_super,
+	statfs:		udf_statfs,
+	remount_fs:	udf_remount_fs,
 #if CONFIG_UDF_RW == 1
-	udf_write_inode,	/* write_inode */
-#else
-	NULL,				/* write_inode */
+	write_inode:	udf_write_inode,
+	delete_inode:	udf_delete_inode,
 #endif
-	udf_put_inode,		/* put_inode */
-#if CONFIG_UDF_RW == 1
-	udf_delete_inode,	/* delete_inode */
-#else
-	NULL,				/* delete_inode */
-#endif
-	NULL,				/* notify_change */
-	udf_put_super,		/* put_super */
-	NULL,				/* write_super */
-	udf_statfs,			/* statfs */
-	udf_remount_fs,		/* remount_fs */
-	NULL,				/* clear_inode */
-	NULL,				/* umount_begin */
 };
 
 struct udf_options
diff -u --recursive --new-file v2.3.47/linux/fs/udf/udfdecl.h linux/fs/udf/udfdecl.h
--- v2.3.47/linux/fs/udf/udfdecl.h	Thu Feb 10 17:11:19 2000
+++ linux/fs/udf/udfdecl.h	Sat Feb 26 20:33:08 2000
@@ -63,6 +63,8 @@
 
 extern struct inode_operations udf_dir_inode_operations;
 extern struct inode_operations udf_file_inode_operations;
+extern struct file_operations udf_dir_operations;
+extern struct file_operations udf_file_operations;
 extern struct address_space_operations udf_adinicb_aops;
 extern struct address_space_operations udf_symlink_aops;
 
@@ -118,15 +120,6 @@
 
 /* namei.c */
 extern int udf_write_fi(struct FileIdentDesc *, struct FileIdentDesc *, struct udf_fileident_bh *, Uint8 *, Uint8 *);
-extern struct dentry * udf_lookup(struct inode *, struct dentry *);
-extern int udf_create(struct inode *, struct dentry *, int);
-extern int udf_mknod(struct inode *, struct dentry *, int, int);
-extern int udf_mkdir(struct inode *, struct dentry *, int);
-extern int udf_rmdir(struct inode *, struct dentry *);
-extern int udf_unlink(struct inode *, struct dentry *);
-extern int udf_symlink(struct inode *, struct dentry *, const char *);
-extern int udf_link(struct dentry *, struct inode *, struct dentry *);
-extern int udf_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
 
 /* file.c */
 extern int udf_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
diff -u --recursive --new-file v2.3.47/linux/fs/ufs/Makefile linux/fs/ufs/Makefile
--- v2.3.47/linux/fs/ufs/Makefile	Sun Jul 26 01:20:22 1998
+++ linux/fs/ufs/Makefile	Sat Feb 26 20:33:08 2000
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definitions are now in the main makefile.
 
 O_TARGET := ufs.o
-O_OBJS   := acl.o balloc.o cylinder.o dir.o file.o ialloc.o inode.o \
+O_OBJS   := balloc.o cylinder.o dir.o file.o ialloc.o inode.o \
 		namei.o super.o symlink.o truncate.o util.o
 M_OBJS   := $(O_TARGET)
 
diff -u --recursive --new-file v2.3.47/linux/fs/ufs/acl.c linux/fs/ufs/acl.c
--- v2.3.47/linux/fs/ufs/acl.c	Mon Jan  4 11:51:29 1999
+++ linux/fs/ufs/acl.c	Wed Dec 31 16:00:00 1969
@@ -1,68 +0,0 @@
-/*
- *  linux/fs/ufs/acl.c
- *
- * Copyright (C) 1998
- * Daniel Pirkl <daniel.pirkl@email.cz>
- * Charles University, Faculty of Mathematics and Physics
- *
- *  from
- *
- *  linux/fs/ext2/acl.c
- *
- * Copyright (C) 1993, 1994, 1995
- * Remy Card (card@masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
- */
-
-/*
- * This file will contain the Access Control Lists management for UFS
- */
-
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/ufs_fs.h>
-#include <linux/sched.h>
-#include <linux/stat.h>
-
-/*
- * ufs_permission ()
- *
- * Check for access rights
- */
-int ufs_permission (struct inode * inode, int mask)
-{
-	unsigned short mode = inode->i_mode;
-
-	/*
-	 * Nobody gets write access to a file on a readonly-fs
-	 */
-	if ((mask & S_IWOTH) && 
-	    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) &&
-	    IS_RDONLY(inode))
-		return -EROFS;
-	/*
-	 * Nobody gets write access to an immutable file
-	 */
-	if ((mask & S_IWOTH) && IS_IMMUTABLE(inode))
-		return -EACCES;
-
-	/*
-	 * If no ACL, checks using the file mode
-	 */
-	else if (current->fsuid == inode->i_uid)
-		mode >>= 6;
-	else if (in_group_p (inode->i_gid))
-		mode >>= 3;
-	/*
-	 * Access is always granted for root. We now check last,
-	 * though, for BSD process accounting correctness
-	 */
-	if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE))
-		return 0;
-	if ((mask == S_IROTH) ||
-	    (S_ISDIR(mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
-		if (capable(CAP_DAC_READ_SEARCH))
-			return 0;
-	return -EACCES;
-}
diff -u --recursive --new-file v2.3.47/linux/fs/ufs/dir.c linux/fs/ufs/dir.c
--- v2.3.47/linux/fs/ufs/dir.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/ufs/dir.c	Sat Feb 26 20:33:08 2000
@@ -177,25 +177,8 @@
 	return (error_msg == NULL ? 1 : 0);
 }
 
-static struct file_operations ufs_dir_operations = {
+struct file_operations ufs_dir_operations = {
+	read:		generic_read_dir,
 	readdir:	ufs_readdir,
 	fsync:		file_fsync,
-};
-
-struct inode_operations ufs_dir_inode_operations = {
-	&ufs_dir_operations,	/* default directory file operations */
-	ufs_create,		/* create */
-	ufs_lookup,		/* lookup */
-	ufs_link,		/* link */
-	ufs_unlink,		/* unlink */
-	ufs_symlink,		/* symlink */
-	ufs_mkdir,		/* mkdir */
-	ufs_rmdir,		/* rmdir */
-	ufs_mknod,		/* mknod */
-	ufs_rename,		/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* truncate */
-	ufs_permission,		/* permission */
-	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.47/linux/fs/ufs/file.c linux/fs/ufs/file.c
--- v2.3.47/linux/fs/ufs/file.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/ufs/file.c	Sat Feb 26 20:33:08 2000
@@ -71,7 +71,7 @@
  * We have mostly NULL's here: the current defaults are ok for
  * the ufs filesystem.
  */
-static struct file_operations ufs_file_operations = {
+struct file_operations ufs_file_operations = {
 	llseek:		ufs_file_lseek,
 	read:		generic_file_read,
 	write:		generic_file_write,
@@ -79,6 +79,5 @@
 };
 
 struct inode_operations ufs_file_inode_operations = {
-	&ufs_file_operations,
 	truncate:	ufs_truncate,
 };
diff -u --recursive --new-file v2.3.47/linux/fs/ufs/ialloc.c linux/fs/ufs/ialloc.c
--- v2.3.47/linux/fs/ufs/ialloc.c	Tue Jan 11 22:31:44 2000
+++ linux/fs/ufs/ialloc.c	Sat Feb 26 20:33:08 2000
@@ -290,7 +290,6 @@
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	inode->u.ufs_i.i_flags = dir->u.ufs_i.i_flags;
 	inode->u.ufs_i.i_lastfrag = 0;
-	inode->i_op = NULL;
 
 	insert_inode_hash(inode);
 	mark_inode_dirty(inode);
diff -u --recursive --new-file v2.3.47/linux/fs/ufs/inode.c linux/fs/ufs/inode.c
--- v2.3.47/linux/fs/ufs/inode.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/ufs/inode.c	Sat Feb 26 20:33:08 2000
@@ -641,14 +641,14 @@
 	}
 
 
-	inode->i_op = NULL;
-
 	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &ufs_file_inode_operations;
+		inode->i_fop = &ufs_file_operations;
 		inode->i_mapping->a_ops = &ufs_aops;
-	} else if (S_ISDIR(inode->i_mode))
+	} else if (S_ISDIR(inode->i_mode)) {
 		inode->i_op = &ufs_dir_inode_operations;
-	else if (S_ISLNK(inode->i_mode)) {
+		inode->i_fop = &ufs_dir_operations;
+	} else if (S_ISLNK(inode->i_mode)) {
 		if (!inode->i_blocks)
 			inode->i_op = &ufs_fast_symlink_inode_operations;
 		else {
diff -u --recursive --new-file v2.3.47/linux/fs/ufs/namei.c linux/fs/ufs/namei.c
--- v2.3.47/linux/fs/ufs/namei.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/ufs/namei.c	Sat Feb 26 20:33:09 2000
@@ -183,7 +183,7 @@
 	return NULL;
 }
 
-struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry)
+static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry)
 {
 	struct super_block * sb;
 	struct inode * inode;
@@ -403,7 +403,7 @@
  * If the create succeeds, we fill in the inode information
  * with d_instantiate(). 
  */
-int ufs_create (struct inode * dir, struct dentry * dentry, int mode)
+static int ufs_create (struct inode * dir, struct dentry * dentry, int mode)
 {
 	struct super_block * sb;
 	struct inode * inode;
@@ -424,6 +424,7 @@
 	if (!inode)
 		return err;
 	inode->i_op = &ufs_file_inode_operations;
+	inode->i_fop = &ufs_file_operations;
 	inode->i_mapping->a_ops = &ufs_aops;
 	inode->i_mode = mode;
 	mark_inode_dirty(inode);
@@ -450,7 +451,7 @@
 	return 0;
 }
 
-int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
+static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
 {
 	struct super_block * sb;
 	struct inode * inode;
@@ -494,7 +495,7 @@
 	goto out;
 }
 
-int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
 {
 	struct super_block * sb;
 	struct inode * inode;
@@ -516,6 +517,7 @@
 		goto out;
 
 	inode->i_op = &ufs_dir_inode_operations;
+	inode->i_fop = &ufs_dir_operations;
 	inode->i_size = UFS_SECTOR_SIZE;
 	dir_block = ufs_bread (inode, 0, 1, &err);
 	if (!dir_block) {
@@ -631,7 +633,7 @@
 	return 1;
 }
 
-int ufs_rmdir (struct inode * dir, struct dentry *dentry)
+static int ufs_rmdir (struct inode * dir, struct dentry *dentry)
 {
 	struct super_block *sb;
 	int retval;
@@ -690,7 +692,7 @@
 	return retval;
 }
 
-int ufs_unlink(struct inode * dir, struct dentry *dentry)
+static int ufs_unlink(struct inode * dir, struct dentry *dentry)
 {
 	struct super_block * sb;
 	int retval;
@@ -749,7 +751,7 @@
 /*
  * Create symbolic link. We use only slow symlinks at this time.
  */
-int ufs_symlink (struct inode * dir, struct dentry * dentry,
+static int ufs_symlink (struct inode * dir, struct dentry * dentry,
 	const char * symname)
 {
 	struct super_block * sb = dir->i_sb;
@@ -813,7 +815,7 @@
 	goto out;
 }
 
-int ufs_link (struct dentry * old_dentry, struct inode * dir,
+static int ufs_link (struct dentry * old_dentry, struct inode * dir,
 	struct dentry *dentry)
 {
 	struct inode *inode = old_dentry->d_inode;
@@ -857,7 +859,7 @@
  * Anybody can rename anything with this: the permission checks are left to the
  * higher-level routines.
  */
-int ufs_rename (struct inode * old_dir, struct dentry * old_dentry,
+static int ufs_rename (struct inode * old_dir, struct dentry * old_dentry,
 	struct inode * new_dir,	struct dentry * new_dentry )
 {
 	struct super_block * sb;
@@ -973,3 +975,15 @@
 	
 	return retval;
 }
+
+struct inode_operations ufs_dir_inode_operations = {
+	create:		ufs_create,
+	lookup:		ufs_lookup,
+	link:		ufs_link,
+	unlink:		ufs_unlink,
+	symlink:	ufs_symlink,
+	mkdir:		ufs_mkdir,
+	rmdir:		ufs_rmdir,
+	mknod:		ufs_mknod,
+	rename:		ufs_rename,
+};
diff -u --recursive --new-file v2.3.47/linux/fs/ufs/super.c linux/fs/ufs/super.c
--- v2.3.47/linux/fs/ufs/super.c	Fri Jan 21 18:19:17 2000
+++ linux/fs/ufs/super.c	Sat Feb 26 20:33:09 2000
@@ -173,6 +173,8 @@
 }
 #endif /* UFS_SUPER_DEBUG_MORE */
 
+static struct super_operations ufs_super_ops;
+
 static char error_buf[1024];
 
 void ufs_error (struct super_block * sb, const char * function,
@@ -947,15 +949,14 @@
 }
 
 static struct super_operations ufs_super_ops = {
-	ufs_read_inode,
-	ufs_write_inode,
-	ufs_put_inode,
-	ufs_delete_inode,
-	NULL,			/* notify_change() */
-	ufs_put_super,
-	ufs_write_super,
-	ufs_statfs,
-	ufs_remount
+	read_inode:	ufs_read_inode,
+	write_inode:	ufs_write_inode,
+	put_inode:	ufs_put_inode,
+	delete_inode:	ufs_delete_inode,
+	put_super:	ufs_put_super,
+	write_super:	ufs_write_super,
+	statfs:		ufs_statfs,
+	remount_fs:	ufs_remount,
 };
 
 static struct file_system_type ufs_fs_type = {
diff -u --recursive --new-file v2.3.47/linux/fs/umsdos/check.c linux/fs/umsdos/check.c
--- v2.3.47/linux/fs/umsdos/check.c	Tue Dec 14 01:27:24 1999
+++ linux/fs/umsdos/check.c	Sat Feb 26 20:33:09 2000
@@ -84,7 +84,6 @@
 /*
  * check an inode
  */
-extern struct inode_operations umsdos_rdir_inode_operations;
 
 void check_inode (struct inode *inode)
 {
diff -u --recursive --new-file v2.3.47/linux/fs/umsdos/dir.c linux/fs/umsdos/dir.c
--- v2.3.47/linux/fs/umsdos/dir.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/umsdos/dir.c	Sat Feb 26 20:33:43 2000
@@ -52,17 +52,6 @@
 	umsdos_dentry_dput	/* d_delete(struct dentry *) */
 };
 
-
-/*
- * So  grep *  doesn't complain in the presence of directories.
- */
- 
-int dummy_dir_read (struct file *filp, char *buff, size_t size, loff_t *count)
-{
-	return -EISDIR;
-}
-
-
 struct UMSDOS_DIR_ONCE {
 	void *dirbuf;
 	filldir_t filldir;
@@ -800,23 +789,23 @@
 }	
 
 
-static struct file_operations umsdos_dir_operations =
+struct file_operations umsdos_dir_operations =
 {
-	read:		dummy_dir_read,
+	read:		generic_read_dir,
 	readdir:	UMSDOS_readdir,
 	ioctl:		UMSDOS_ioctl_dir,
 };
 
 struct inode_operations umsdos_dir_inode_operations =
 {
-	&umsdos_dir_operations,	/* default directory file-ops */
-	UMSDOS_create,		/* create */
-	UMSDOS_lookup,		/* lookup */
-	UMSDOS_link,		/* link */
-	UMSDOS_unlink,		/* unlink */
-	UMSDOS_symlink,		/* symlink */
-	UMSDOS_mkdir,		/* mkdir */
-	UMSDOS_rmdir,		/* rmdir */
-	UMSDOS_mknod,		/* mknod */
-	UMSDOS_rename,		/* rename */
+	create:		UMSDOS_create,
+	lookup:		UMSDOS_lookup,
+	link:		UMSDOS_link,
+	unlink:		UMSDOS_unlink,
+	symlink:	UMSDOS_symlink,
+	mkdir:		UMSDOS_mkdir,
+	rmdir:		UMSDOS_rmdir,
+	mknod:		UMSDOS_mknod,
+	rename:		UMSDOS_rename,
+	setattr:	UMSDOS_notify_change,
 };
diff -u --recursive --new-file v2.3.47/linux/fs/umsdos/inode.c linux/fs/umsdos/inode.c
--- v2.3.47/linux/fs/umsdos/inode.c	Sun Feb 13 19:29:04 2000
+++ linux/fs/umsdos/inode.c	Sat Feb 26 20:33:43 2000
@@ -20,8 +20,6 @@
 #include <linux/list.h>
 
 extern struct dentry_operations umsdos_dentry_operations;
-extern struct inode_operations umsdos_rdir_inode_operations;
-
 
 struct dentry *saved_root = NULL;	/* Original root if changed */
 struct inode *pseudo_root = NULL;	/* Useful to simulate the pseudo DOS */
@@ -42,7 +40,7 @@
 	filp->f_reada = 1;
 	filp->f_flags = O_RDWR;
 	filp->f_dentry = dentry;
-	filp->f_op = dentry->d_inode->i_op->default_file_ops;
+	filp->f_op = dentry->d_inode->i_fop;
 }
 
 
@@ -100,10 +98,12 @@
 	inode->u.umsdos_i.dir_info.pid = 0;
 
 	inode->i_op = &umsdos_rdir_inode_operations;
+	inode->i_fop = &umsdos_rdir_operations;
 	if (umsdos_have_emd(dir)) {
 Printk((KERN_DEBUG "umsdos_setup_dir: %s/%s using EMD\n",
 dir->d_parent->d_name.name, dir->d_name.name));
 		inode->i_op = &umsdos_dir_inode_operations;
+		inode->i_fop = &umsdos_dir_operations;
 	}
 }
 
@@ -126,7 +126,16 @@
 	return;
 }
 
-
+static struct inode_operations umsdos_file_inode_operations = {
+	truncate:	fat_truncate,
+	setattr:	UMSDOS_notify_change,
+};
+
+static struct inode_operations umsdos_symlink_inode_operations = {
+	readlink:	page_readlink,
+	follow_link:	page_follow_link,
+	setattr:	UMSDOS_notify_change,
+};
 
 /*
  * Connect the proper tables in the inode and add some info.
@@ -150,13 +159,14 @@
 dentry, f_pos));
 	umsdos_set_dirinfo_new(dentry, f_pos);
 
+	inode->i_op = &umsdos_file_inode_operations;
 	if (S_ISREG (inode->i_mode)) {
-		/* All set */
+		/* address_space operations already set */
 	} else if (S_ISDIR (inode->i_mode)) {
 		umsdos_setup_dir(dentry);
 	} else if (S_ISLNK (inode->i_mode)) {
 		/* address_space operations already set */
-		inode->i_op = &page_symlink_inode_operations;
+		inode->i_op = &umsdos_symlink_inode_operations;
 	} else
 		init_special_inode(inode, inode->i_mode,
 					kdev_t_to_nr(inode->i_rdev));
@@ -307,16 +317,12 @@
 
 static struct super_operations umsdos_sops =
 {
-	NULL,			/* read_inode */
-	UMSDOS_write_inode,	/* write_inode */
-	UMSDOS_put_inode,	/* put_inode */
-	fat_delete_inode,	/* delete_inode */
-	UMSDOS_notify_change,	/* notify_change */
-	UMSDOS_put_super,	/* put_super */
-	NULL,			/* write_super */
-	fat_statfs,		/* statfs */
-	NULL,			/* remount_fs */
-	fat_clear_inode		/* clear_inode */
+	write_inode:	UMSDOS_write_inode,
+	put_inode:	UMSDOS_put_inode,
+	delete_inode:	fat_delete_inode,
+	put_super:	UMSDOS_put_super,
+	statfs:		fat_statfs,
+	clear_inode:	fat_clear_inode,
 };
 
 /*
diff -u --recursive --new-file v2.3.47/linux/fs/umsdos/rdir.c linux/fs/umsdos/rdir.c
--- v2.3.47/linux/fs/umsdos/rdir.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/umsdos/rdir.c	Sat Feb 26 20:33:43 2000
@@ -218,23 +218,20 @@
  * have a "r" prefix (r for real) such as UMSDOS_rlookup, to differentiate
  * from the one with full UMSDOS semantics.
  */
-static struct file_operations umsdos_rdir_operations =
+struct file_operations umsdos_rdir_operations =
 {
-	read:		dummy_dir_read,
+	read:		generic_read_dir,
 	readdir:	UMSDOS_rreaddir,
 	ioctl:		UMSDOS_ioctl_dir,
 };
 
 struct inode_operations umsdos_rdir_inode_operations =
 {
-	&umsdos_rdir_operations,	/* default directory file-ops */
-	msdos_create,		/* create */
-	UMSDOS_rlookup,		/* lookup */
-	NULL,			/* link */
-	msdos_unlink,		/* unlink */
-	NULL,			/* symlink */
-	msdos_mkdir,		/* mkdir */
-	UMSDOS_rrmdir,		/* rmdir */
-	NULL,			/* mknod */
-	msdos_rename,		/* rename */
+	create:		msdos_create,
+	lookup:		UMSDOS_rlookup,
+	unlink:		msdos_unlink,
+	mkdir:		msdos_mkdir,
+	rmdir:		UMSDOS_rrmdir,
+	rename:		msdos_rename,
+	setattr:	UMSDOS_notify_change,
 };
diff -u --recursive --new-file v2.3.47/linux/fs/vfat/namei.c linux/fs/vfat/namei.c
--- v2.3.47/linux/fs/vfat/namei.c	Thu Feb 10 17:11:19 2000
+++ linux/fs/vfat/namei.c	Sat Feb 26 20:33:43 2000
@@ -1266,16 +1266,13 @@
 
 /* Public inode operations for the VFAT fs */
 struct inode_operations vfat_dir_inode_operations = {
-	&fat_dir_operations,	/* default directory file-ops */
-	vfat_create,		/* create */
-	vfat_lookup,		/* lookup */
-	NULL,			/* link */
-	vfat_unlink,		/* unlink */
-	NULL,			/* symlink */
-	vfat_mkdir,		/* mkdir */
-	vfat_rmdir,		/* rmdir */
-	NULL,			/* mknod */
-	vfat_rename,		/* rename */
+	create:		vfat_create,
+	lookup:		vfat_lookup,
+	unlink:		vfat_unlink,
+	mkdir:		vfat_mkdir,
+	rmdir:		vfat_rmdir,
+	rename:		vfat_rename,
+	setattr:	fat_notify_change,
 };
 
 struct super_block *vfat_read_super(struct super_block *sb,void *data,
diff -u --recursive --new-file v2.3.47/linux/include/asm-alpha/atomic.h linux/include/asm-alpha/atomic.h
--- v2.3.47/linux/include/asm-alpha/atomic.h	Mon Jul 19 13:12:47 1999
+++ linux/include/asm-alpha/atomic.h	Thu Feb 24 22:36:05 2000
@@ -41,7 +41,7 @@
 	"	addl %0,%2,%0\n"
 	"	stl_c %0,%1\n"
 	"	beq %0,2f\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"2:	br 1b\n"
 	".previous"
 	:"=&r" (temp), "=m" (__atomic_fool_gcc(v))
@@ -56,7 +56,7 @@
 	"	subl %0,%2,%0\n"
 	"	stl_c %0,%1\n"
 	"	beq %0,2f\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"2:	br 1b\n"
 	".previous"
 	:"=&r" (temp), "=m" (__atomic_fool_gcc(v))
@@ -76,7 +76,7 @@
 	"	stl_c %0,%1\n"
 	"	beq %0,2f\n"
 	"	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"2:	br 1b\n"
 	".previous"
 	:"=&r" (temp), "=m" (__atomic_fool_gcc(v)), "=&r" (result)
@@ -94,7 +94,7 @@
 	"	stl_c %0,%1\n"
 	"	beq %0,2f\n"
 	"	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"2:	br 1b\n"
 	".previous"
 	:"=&r" (temp), "=m" (__atomic_fool_gcc(v)), "=&r" (result)
diff -u --recursive --new-file v2.3.47/linux/include/asm-alpha/bitops.h linux/include/asm-alpha/bitops.h
--- v2.3.47/linux/include/asm-alpha/bitops.h	Thu Feb 10 17:11:19 2000
+++ linux/include/asm-alpha/bitops.h	Thu Feb 24 22:36:05 2000
@@ -31,7 +31,7 @@
 	"	stl_c %0,%1\n"
 	"	beq %0,3f\n"
 	"2:\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"3:	br 1b\n"
 	".previous"
 	:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
@@ -52,7 +52,7 @@
 	"	stl_c %0,%1\n"
 	"	beq %0,3f\n"
 	"2:\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"3:	br 1b\n"
 	".previous"
 	:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
@@ -69,7 +69,7 @@
 	"	xor %0,%2,%0\n"
 	"	stl_c %0,%1\n"
 	"	beq %0,3f\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"3:	br 1b\n"
 	".previous"
 	:"=&r" (temp), "=m" (*m)
@@ -92,7 +92,7 @@
 	"	beq %0,3f\n"
 	"	mb\n"
 	"2:\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"3:	br 1b\n"
 	".previous"
 	:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
@@ -117,7 +117,7 @@
 	"	beq %0,3f\n"
 	"	mb\n"
 	"2:\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"3:	br 1b\n"
 	".previous"
 	:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
@@ -140,7 +140,7 @@
 	"	stl_c %0,%1\n"
 	"	beq %0,3f\n"
 	"	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"3:	br 1b\n"
 	".previous"
 	:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
diff -u --recursive --new-file v2.3.47/linux/include/asm-alpha/parport.h linux/include/asm-alpha/parport.h
--- v2.3.47/linux/include/asm-alpha/parport.h	Fri Jan 28 15:09:09 2000
+++ linux/include/asm-alpha/parport.h	Sat Feb 26 20:34:34 2000
@@ -43,6 +43,8 @@
 				count++;
 		} while (*io && (++i < PARPORT_PC_MAX_PORTS));
 	} else {
+		count += parport_pc_init_superio ();
+
 		/* Probe all the likely ports. */
 		if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL))
 			count++;
diff -u --recursive --new-file v2.3.47/linux/include/asm-alpha/pci.h linux/include/asm-alpha/pci.h
--- v2.3.47/linux/include/asm-alpha/pci.h	Sun Feb 20 21:12:39 2000
+++ linux/include/asm-alpha/pci.h	Thu Feb 24 22:45:28 2000
@@ -118,7 +118,8 @@
    again owns the buffer.  */
 
 extern inline void
-pci_dma_sync_single(struct pci_dev *dev, dma_addr_t dma_addr, long size, int direction)
+pci_dma_sync_single(struct pci_dev *dev, dma_addr_t dma_addr, long size,
+		    int direction)
 {
 	/* Nothing to do.  */
 }
@@ -128,19 +129,17 @@
    for a scatter-gather list, same rules and usage.  */
 
 extern inline void
-pci_dma_sync_sg(struct pci_dev *dev, struct scatterlist *sg, int nents, int direction)
+pci_dma_sync_sg(struct pci_dev *dev, struct scatterlist *sg, int nents,
+	        int direction)
 {
 	/* Nothing to do.  */
 }
 
 /* Return whether the given PCI device DMA address mask can
- * be supported properly.  For example, if your device can
- * only drive the low 24-bits during PCI bus mastering, then
- * you would pass 0x00ffffff as the mask to this function.
- */
-extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
-{
-	return 1;
-}
+   be supported properly.  For example, if your device can
+   only drive the low 24-bits during PCI bus mastering, then
+   you would pass 0x00ffffff as the mask to this function.  */
+
+extern int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask);
 
 #endif /* __ALPHA_PCI_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-alpha/semaphore-helper.h linux/include/asm-alpha/semaphore-helper.h
--- v2.3.47/linux/include/asm-alpha/semaphore-helper.h	Thu Apr 15 05:42:32 1999
+++ linux/include/asm-alpha/semaphore-helper.h	Thu Feb 24 22:36:05 2000
@@ -34,7 +34,7 @@
 		"	stl_c	%0,%2\n"
 		"	beq	%0,3f\n"
 		"2:\n"
-		".section .text2,\"ax\"\n"
+		".subsection 2\n"
 		"3:	br	1b\n"
 		".previous"
 		: "=r"(ret), "=r"(tmp), "=m"(__atomic_fool_gcc(&sem->waking))
@@ -104,7 +104,7 @@
 		"	stq_c	%1,%4\n"
 		"	beq	%1,3f\n"
 		"2:\n"
-		".section .text2,\"ax\"\n"
+		".subsection 2\n"
 		"3:	br	1b\n"
 		".previous"
 		: "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(tmp3), "=m"(*sem)
diff -u --recursive --new-file v2.3.47/linux/include/asm-alpha/semaphore.h linux/include/asm-alpha/semaphore.h
--- v2.3.47/linux/include/asm-alpha/semaphore.h	Thu Feb 10 17:11:20 2000
+++ linux/include/asm-alpha/semaphore.h	Thu Feb 24 22:36:05 2000
@@ -116,7 +116,7 @@
 		"	beq	$28,2f\n"
 		"	blt	$24,3f\n"
 		"4:	mb\n"
-		".section .text2,\"ax\"\n"
+		".subsection 2\n"
 		"2:	br	1b\n"
 		"3:	lda	$24,%1\n"
 		"	jsr	$28,($27),__down_failed\n"
@@ -153,7 +153,7 @@
 		"	blt	$24,3f\n"
 		"	mov	$31,%0\n"
 		"4:	mb\n"
-		".section .text2,\"ax\"\n"
+		".subsection 2\n"
 		"2:	br	1b\n"
 		"3:	lda	$24,%2\n"
 		"	jsr	$28,($27),__down_failed_interruptible\n"
@@ -216,7 +216,7 @@
 		"	stq_c	%1,%4\n"
 		"	beq	%1,3f\n"
 		"2:\n"
-		".section .text2,\"ax\"\n"
+		".subsection 2\n"
 		"3:	br	1b\n"
 		".previous"
 		: "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub)
@@ -253,7 +253,7 @@
 		"	beq	$28,2f\n"
 		"	ble	$24,3f\n"
 		"4:\n"
-		".section .text2,\"ax\"\n"
+		".subsection 2\n"
 		"2:	br	1b\n"
 		"3:	lda	$24,%1\n"
 		"	jsr	$28,($27),__up_wakeup\n"
@@ -379,7 +379,7 @@
 		"	beq	$28,2f\n"
 		"	blt	$25,3f\n"
 		"4:	mb\n"
-		".section .text2,\"ax\"\n"
+		".subsection 2\n"
 		"2:	br	1b\n"
 		"3:	lda	$24,%1\n"
 		"	jsr	$28,($27),__down_read_failed\n"
@@ -429,7 +429,7 @@
 		"	beq	$28,2f\n"
 		"	bne	$25,3f\n"
 		"4:	mb\n"
-		".section .text2,\"ax\"\n"
+		".subsection 2\n"
 		"2:	br	1b\n"
 		"3:	lda	$24,%1\n"
 		"	jsr	$28,($27),__down_write_failed\n"
@@ -488,7 +488,7 @@
 		"	beq	$28,2f\n"
 		"	beq	$24,3f\n"
 		"4:\n"
-		".section .text2,\"ax\"\n"
+		".subsection 2\n"
 		"2:	br	1b\n"
 		"3:	lda	$24,%1\n"
 		"	mov	0,$25\n"
@@ -538,7 +538,7 @@
 		"	beq	$28,2f\n"
 		"	blt	$24,3f\n"
 		"4:\n"
-		".section .text2,\"ax\"\n"
+		".subsection 2\n"
 		"2:	br	1b\n"
 		"3:	ldah	$25,%3($24)\n"
 		/* Only do the wake if we're no longer negative.  */
diff -u --recursive --new-file v2.3.47/linux/include/asm-alpha/spinlock.h linux/include/asm-alpha/spinlock.h
--- v2.3.47/linux/include/asm-alpha/spinlock.h	Fri Sep 10 23:57:36 1999
+++ linux/include/asm-alpha/spinlock.h	Thu Feb 24 22:36:05 2000
@@ -78,7 +78,7 @@
 	"	stl_c	%0,%1\n"
 	"	beq	%0,2f\n"
 	"	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"2:	ldl	%0,%1\n"
 	"	blbs	%0,2b\n"
 	"	br	1b\n"
@@ -114,7 +114,7 @@
 	"	stl_c	%1,%0\n"
 	"	beq	%1,6f\n"
 	"	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"6:	ldl	%1,%0\n"
 	"	bne	%1,6b\n"
 	"	br	1b\n"
@@ -135,7 +135,7 @@
 	"	stl_c	%1,%0\n"
 	"	beq	%1,6f\n"
 	"4:	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"6:	ldl	%1,%0\n"
 	"	blbs	%1,6b\n"
 	"	br	1b\n"
@@ -160,7 +160,7 @@
 	"	addl	%1,2,%1\n"
 	"	stl_c	%1,%0\n"
 	"	beq	%1,6f\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"6:	br	1b\n"
 	".previous"
 	: "=m" (__dummy_lock(lock)), "=&r" (regx)
diff -u --recursive --new-file v2.3.47/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h
--- v2.3.47/linux/include/asm-alpha/system.h	Wed Dec 15 10:43:17 1999
+++ linux/include/asm-alpha/system.h	Thu Feb 24 22:36:05 2000
@@ -259,11 +259,31 @@
 __CALL_PAL_W1(wrusp, unsigned long);
 __CALL_PAL_W1(wrvptptr, unsigned long);
 
-#define __cli()			((void) swpipl(7))
-#define __sti()			((void) swpipl(0))
+#define IPL_MIN		0
+#define IPL_SW0		1
+#define IPL_SW1		2
+#define IPL_DEV0	3
+#define IPL_DEV1	4
+#define IPL_TIMER	5
+#define IPL_PERF	6
+#define IPL_POWERFAIL	6
+#define IPL_MCHECK	7
+#define IPL_MAX		7
+
+#ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK
+#undef IPL_MIN
+#define IPL_MIN		__min_ipl
+extern int __min_ipl;
+#endif
+
+#define getipl()		(rdps() & 7)
+#define setipl(ipl)		((void) swpipl(ipl))
+
+#define __cli()			setipl(IPL_MAX)
+#define __sti()			setipl(IPL_MIN)
 #define __save_flags(flags)	((flags) = rdps())
-#define __save_and_cli(flags)	((flags) = swpipl(7))
-#define __restore_flags(flags)	((void) swpipl(flags))
+#define __save_and_cli(flags)	((flags) = swpipl(IPL_MAX))
+#define __restore_flags(flags)	setipl(flags)
 
 #define local_irq_save(flags)		__save_and_cli(flags)
 #define local_irq_restore(flags)	__restore_flags(flags)
@@ -332,7 +352,7 @@
 	"	stl_c %1,%2\n"
 	"	beq %1,2f\n"
 	"	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"2:	br 1b\n"
 	".previous"
 	: "=&r" (val), "=&r" (dummy), "=m" (*m)
@@ -352,7 +372,7 @@
 	"	stq_c %1,%2\n"
 	"	beq %1,2f\n"
 	"	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"2:	br 1b\n"
 	".previous"
 	: "=&r" (val), "=&r" (dummy), "=m" (*m)
@@ -408,7 +428,7 @@
 	"	stl_c %1,%2\n"
 	"	beq %1,3f\n"
 	"2:	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"3:	br 1b\n"
 	".previous"
 	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
@@ -430,7 +450,7 @@
 	"	stq_c %1,%2\n"
 	"	beq %1,3f\n"
 	"2:	mb\n"
-	".section .text2,\"ax\"\n"
+	".subsection 2\n"
 	"3:	br 1b\n"
 	".previous"
 	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
diff -u --recursive --new-file v2.3.47/linux/include/asm-arm/arch-arc/io.h linux/include/asm-arm/arch-arc/io.h
--- v2.3.47/linux/include/asm-arm/arch-arc/io.h	Tue Dec 14 01:27:24 1999
+++ linux/include/asm-arm/arch-arc/io.h	Thu Feb 24 22:44:47 2000
@@ -91,7 +91,7 @@
 
 DECLARE_IO(char,b,"b")
 DECLARE_IO(short,w,"")
-DECLARE_IO(long,l,"")
+DECLARE_IO(int,l,"")
 
 #undef DECLARE_IO
 #undef DECLARE_DYN_IN
diff -u --recursive --new-file v2.3.47/linux/include/asm-arm/arch-cl7500/io.h linux/include/asm-arm/arch-cl7500/io.h
--- v2.3.47/linux/include/asm-arm/arch-cl7500/io.h	Tue Dec 14 01:27:24 1999
+++ linux/include/asm-arm/arch-cl7500/io.h	Thu Feb 24 22:44:47 2000
@@ -92,7 +92,7 @@
 
 DECLARE_IO(char,b,"b")
 DECLARE_IO(short,w,"")
-DECLARE_IO(long,l,"")
+DECLARE_IO(int,l,"")
 
 #undef DECLARE_IO
 #undef DECLARE_DYN_IN
diff -u --recursive --new-file v2.3.47/linux/include/asm-arm/arch-ebsa110/io.h linux/include/asm-arm/arch-ebsa110/io.h
--- v2.3.47/linux/include/asm-arm/arch-ebsa110/io.h	Tue Dec 14 01:27:24 1999
+++ linux/include/asm-arm/arch-ebsa110/io.h	Thu Feb 24 22:44:47 2000
@@ -67,7 +67,7 @@
 
 DECLARE_IO(char,b,"b")
 DECLARE_IO(short,w,"")
-DECLARE_IO(long,l,"")
+DECLARE_IO(int,l,"")
 
 #undef DECLARE_IO
 #undef DECLARE_DYN_OUT
diff -u --recursive --new-file v2.3.47/linux/include/asm-arm/arch-ebsa285/io.h linux/include/asm-arm/arch-ebsa285/io.h
--- v2.3.47/linux/include/asm-arm/arch-ebsa285/io.h	Fri Jan 21 18:19:17 2000
+++ linux/include/asm-arm/arch-ebsa285/io.h	Thu Feb 24 22:44:47 2000
@@ -45,7 +45,7 @@
  * Generic virtual read/write
  */
 #define __arch_getb(a)		(*(volatile unsigned char *)(a))
-#define __arch_getl(a)		(*(volatile unsigned long *)(a))
+#define __arch_getl(a)		(*(volatile unsigned int  *)(a))
 
 extern __inline__ unsigned int __arch_getw(unsigned long a)
 {
@@ -58,7 +58,7 @@
 
 
 #define __arch_putb(v,a)	(*(volatile unsigned char *)(a) = (v))
-#define __arch_putl(v,a)	(*(volatile unsigned long *)(a) = (v))
+#define __arch_putl(v,a)	(*(volatile unsigned int  *)(a) = (v))
 
 extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
 {
diff -u --recursive --new-file v2.3.47/linux/include/asm-arm/arch-nexuspci/io.h linux/include/asm-arm/arch-nexuspci/io.h
--- v2.3.47/linux/include/asm-arm/arch-nexuspci/io.h	Tue Dec 14 01:27:24 1999
+++ linux/include/asm-arm/arch-nexuspci/io.h	Thu Feb 24 22:44:47 2000
@@ -46,7 +46,7 @@
 
 DECLARE_IO(char,b,"b","Jr")
 DECLARE_IO(short,w,"h","r")
-DECLARE_IO(long,l,"","Jr")
+DECLARE_IO(int,l,"","Jr")
 
 #undef DECLARE_IO
 #undef DECLARE_DYN_OUT
diff -u --recursive --new-file v2.3.47/linux/include/asm-arm/arch-rpc/io.h linux/include/asm-arm/arch-rpc/io.h
--- v2.3.47/linux/include/asm-arm/arch-rpc/io.h	Tue Dec 14 01:27:24 1999
+++ linux/include/asm-arm/arch-rpc/io.h	Thu Feb 24 22:44:47 2000
@@ -90,7 +90,7 @@
 
 DECLARE_IO(char,b,"b")
 DECLARE_IO(short,w,"")
-DECLARE_IO(long,l,"")
+DECLARE_IO(int,l,"")
 
 #undef DECLARE_IO
 #undef DECLARE_DYN_IN
diff -u --recursive --new-file v2.3.47/linux/include/asm-arm/arch-sa1100/io.h linux/include/asm-arm/arch-sa1100/io.h
--- v2.3.47/linux/include/asm-arm/arch-sa1100/io.h	Tue Dec 14 01:27:24 1999
+++ linux/include/asm-arm/arch-sa1100/io.h	Thu Feb 24 22:44:47 2000
@@ -20,7 +20,7 @@
  * Generic virtual read/write
  */
 #define __arch_getb(a)		(*(volatile unsigned char *)(a))
-#define __arch_getl(a)		(*(volatile unsigned long *)(a))
+#define __arch_getl(a)		(*(volatile unsigned int  *)(a))
 
 extern __inline__ unsigned int __arch_getw(unsigned long a)
 {
@@ -33,7 +33,7 @@
 
 
 #define __arch_putb(v,a)	(*(volatile unsigned char *)(a) = (v))
-#define __arch_putl(v,a)	(*(volatile unsigned long *)(a) = (v))
+#define __arch_putl(v,a)	(*(volatile unsigned int  *)(a) = (v))
 
 extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
 {
diff -u --recursive --new-file v2.3.47/linux/include/asm-arm/parport.h linux/include/asm-arm/parport.h
--- v2.3.47/linux/include/asm-arm/parport.h	Fri Jan 28 15:09:09 2000
+++ linux/include/asm-arm/parport.h	Sat Feb 26 20:34:34 2000
@@ -43,6 +43,8 @@
 				count++;
 		} while (*io && (++i < PARPORT_PC_MAX_PORTS));
 	} else {
+		count += parport_pc_init_superio ();
+
 		/* Probe all the likely ports. */
 		if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL))
 			count++;
diff -u --recursive --new-file v2.3.47/linux/include/asm-i386/atomic.h linux/include/asm-i386/atomic.h
--- v2.3.47/linux/include/asm-i386/atomic.h	Tue Dec  7 09:32:49 1999
+++ linux/include/asm-i386/atomic.h	Sat Feb 26 20:45:57 2000
@@ -84,6 +84,17 @@
 	return c != 0;
 }
 
+static __inline__ int atomic_inc_and_test(volatile atomic_t *v)
+{
+	unsigned char c;
+
+	__asm__ __volatile__(
+		LOCK "incl %0; sete %1"
+		:"=m" (__atomic_fool_gcc(v)), "=qm" (c)
+		:"m" (__atomic_fool_gcc(v)));
+	return c != 0;
+}
+
 extern __inline__ int atomic_add_negative(int i, volatile atomic_t *v)
 {
 	unsigned char c;
diff -u --recursive --new-file v2.3.47/linux/include/asm-i386/hardirq.h linux/include/asm-i386/hardirq.h
--- v2.3.47/linux/include/asm-i386/hardirq.h	Thu Feb 10 17:11:20 2000
+++ linux/include/asm-i386/hardirq.h	Sat Feb 26 20:45:59 2000
@@ -2,25 +2,24 @@
 #define __ASM_HARDIRQ_H
 
 #include <linux/threads.h>
-
-extern unsigned int local_irq_count[NR_CPUS];
+#include <linux/irq.h>
 
 /*
  * Are we in an interrupt context? Either doing bottom half
  * or hardware interrupt processing?
  */
 #define in_interrupt() ({ int __cpu = smp_processor_id(); \
-	(local_irq_count[__cpu] + local_bh_count[__cpu] != 0); })
+	(local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
 
-#define in_irq() (local_irq_count[smp_processor_id()] != 0)
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
 
 #ifndef __SMP__
 
-#define hardirq_trylock(cpu)	(local_irq_count[cpu] == 0)
+#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
 #define hardirq_endlock(cpu)	do { } while (0)
 
-#define irq_enter(cpu, irq)	(local_irq_count[cpu]++)
-#define irq_exit(cpu, irq)	(local_irq_count[cpu]--)
+#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
 
 #define synchronize_irq()	barrier()
 
@@ -31,7 +30,16 @@
 
 extern unsigned char global_irq_holder;
 extern unsigned volatile int global_irq_lock;
-extern atomic_t global_irq_count;
+
+static inline int irqs_running (void)
+{
+	int i;
+
+	for (i = 0; i < smp_num_cpus; i++)
+		if (local_irq_count(i))
+			return 1;
+	return 0;
+}
 
 static inline void release_irqlock(int cpu)
 {
@@ -44,8 +52,7 @@
 
 static inline void irq_enter(int cpu, int irq)
 {
-	++local_irq_count[cpu];
-	atomic_inc(&global_irq_count);
+	++local_irq_count(cpu);
 
 	while (test_bit(0,&global_irq_lock)) {
 		/* nothing */;
@@ -54,13 +61,12 @@
 
 static inline void irq_exit(int cpu, int irq)
 {
-	atomic_dec(&global_irq_count);
-	--local_irq_count[cpu];
+	--local_irq_count(cpu);
 }
 
 static inline int hardirq_trylock(int cpu)
 {
-	return !local_irq_count[cpu] && !test_bit(0,&global_irq_lock);
+	return !local_irq_count(cpu) && !test_bit(0,&global_irq_lock);
 }
 
 #define hardirq_endlock(cpu)	do { } while (0)
diff -u --recursive --new-file v2.3.47/linux/include/asm-i386/hw_irq.h linux/include/asm-i386/hw_irq.h
--- v2.3.47/linux/include/asm-i386/hw_irq.h	Fri Jan 21 18:19:17 2000
+++ linux/include/asm-i386/hw_irq.h	Sat Feb 26 20:45:58 2000
@@ -179,13 +179,21 @@
 	"pushl $"#nr"-256\n\t" \
 	"jmp common_interrupt");
 
+extern unsigned long prof_cpu_mask;
 /*
  * x86 profiling function, SMP safe. We might want to do this in
  * assembly totally?
  */
 static inline void x86_do_profile (unsigned long eip)
 {
-	if (prof_buffer && current->pid) {
+	/*
+	 * Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
+	 * (default is all CPUs.)
+	 */
+	if (!((1<<smp_processor_id()) & prof_cpu_mask))
+		return;
+
+	if (prof_buffer) {
 		eip -= (unsigned long) &_stext;
 		eip >>= prof_shift;
 		/*
diff -u --recursive --new-file v2.3.47/linux/include/asm-i386/mpspec.h linux/include/asm-i386/mpspec.h
--- v2.3.47/linux/include/asm-i386/mpspec.h	Fri Jan 21 18:19:17 2000
+++ linux/include/asm-i386/mpspec.h	Fri Feb 25 15:15:54 2000
@@ -152,7 +152,8 @@
 extern unsigned int boot_cpu_id;
 extern unsigned long phys_cpu_present_map;
 extern int smp_found_config;
-extern void init_smp_config(void);
+extern void find_smp_config (void);
+extern void get_smp_config (void);
 extern int nr_ioapics;
 extern int apic_version [NR_CPUS];
 extern int mp_bus_id_to_type [MAX_MP_BUSSES];
diff -u --recursive --new-file v2.3.47/linux/include/asm-i386/parport.h linux/include/asm-i386/parport.h
--- v2.3.47/linux/include/asm-i386/parport.h	Fri Jan 28 15:09:09 2000
+++ linux/include/asm-i386/parport.h	Sat Feb 26 20:34:34 2000
@@ -15,19 +15,10 @@
    than PARPORT_MAX (in <linux/parport.h>).  */
 #define PARPORT_PC_MAX_PORTS  8
 
-/* If parport_cs (PCMCIA) is managing ports for us, we'll need the
- * probing routines forever; otherwise we can lose them at boot time. */
-#ifdef CONFIG_PARPORT_PC_PCMCIA
-#define __maybe_initdata
-#define __maybe_init
-#else
-#define __maybe_initdata __initdata
-#define __maybe_init __init
-#endif
+static int parport_pc_init_pci(int irq, int dma);
+static int parport_pc_init_superio(void);
 
-static int __maybe_init parport_pc_init_pci(int irq, int dma);
-
-static int user_specified __maybe_initdata = 0;
+static int user_specified __devinitdata = 0;
 int __init
 parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
 {
@@ -43,13 +34,16 @@
 				count++;
 		} while (*io && (++i < PARPORT_PC_MAX_PORTS));
 	} else {
-		/* Probe all the likely ports. */
+		count += parport_pc_init_superio ();
+
 		if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL))
 			count++;
 		if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0], NULL))
 			count++;
 		if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0], NULL))
 			count++;
+		
+		/* probe for other PCI parallel devices */
 		count += parport_pc_init_pci (irq[0], dma[0]);
 	}
 
diff -u --recursive --new-file v2.3.47/linux/include/asm-i386/pgtable.h linux/include/asm-i386/pgtable.h
--- v2.3.47/linux/include/asm-i386/pgtable.h	Wed Feb 16 17:03:52 2000
+++ linux/include/asm-i386/pgtable.h	Sat Feb 26 20:45:58 2000
@@ -18,6 +18,7 @@
 #include <linux/threads.h>
 
 extern pgd_t swapper_pg_dir[1024];
+extern void paging_init(void);
 
 /* Caches aren't brain-dead on the intel. */
 #define flush_cache_all()			do { } while (0)
diff -u --recursive --new-file v2.3.47/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h
--- v2.3.47/linux/include/asm-i386/smp.h	Fri Jan 21 18:19:17 2000
+++ linux/include/asm-i386/smp.h	Sat Feb 26 20:45:58 2000
@@ -15,7 +15,9 @@
 #include <asm/fixmap.h>
 #include <asm/bitops.h>
 #include <asm/mpspec.h>
+#ifdef CONFIG_X86_IO_APIC
 #include <asm/io_apic.h>
+#endif
 #include <asm/apic.h>
 #endif
 #endif
diff -u --recursive --new-file v2.3.47/linux/include/asm-i386/softirq.h linux/include/asm-i386/softirq.h
--- v2.3.47/linux/include/asm-i386/softirq.h	Thu Feb 10 17:11:20 2000
+++ linux/include/asm-i386/softirq.h	Sat Feb 26 20:45:59 2000
@@ -4,14 +4,12 @@
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
 
-extern unsigned int local_bh_count[NR_CPUS];
-
-#define cpu_bh_disable(cpu)	do { local_bh_count[(cpu)]++; barrier(); } while (0)
-#define cpu_bh_enable(cpu)	do { barrier(); local_bh_count[(cpu)]--; } while (0)
+#define cpu_bh_disable(cpu)	do { local_bh_count(cpu)++; barrier(); } while (0)
+#define cpu_bh_enable(cpu)	do { barrier(); local_bh_count(cpu)--; } while (0)
 
 #define local_bh_disable()	cpu_bh_disable(smp_processor_id())
 #define local_bh_enable()	cpu_bh_enable(smp_processor_id())
 
-#define in_softirq() (local_bh_count[smp_processor_id()] != 0)
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
 #endif	/* __ASM_SOFTIRQ_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-ia64/offsets.h linux/include/asm-ia64/offsets.h
--- v2.3.47/linux/include/asm-ia64/offsets.h	Sun Feb 13 19:29:04 2000
+++ linux/include/asm-ia64/offsets.h	Thu Feb 24 10:14:29 2000
@@ -10,7 +10,7 @@
 
 #define PF_PTRACED_BIT			4
 
-#define IA64_TASK_SIZE			3280	/* 0xcd0 */
+#define IA64_TASK_SIZE			2800	/* 0xaf0 */
 #define IA64_PT_REGS_SIZE		400	/* 0x190 */
 #define IA64_SWITCH_STACK_SIZE		560	/* 0x230 */
 #define IA64_SIGINFO_SIZE		136	/* 0x88 */
@@ -19,8 +19,8 @@
 #define IA64_TASK_SIGPENDING_OFFSET	16	/* 0x10 */
 #define IA64_TASK_NEED_RESCHED_OFFSET	40	/* 0x28 */
 #define IA64_TASK_PROCESSOR_OFFSET	108	/* 0x6c */
-#define IA64_TASK_THREAD_OFFSET		1424	/* 0x590 */
-#define IA64_TASK_THREAD_KSP_OFFSET	1424	/* 0x590 */
+#define IA64_TASK_THREAD_OFFSET		928	/* 0x3a0 */
+#define IA64_TASK_THREAD_KSP_OFFSET	928	/* 0x3a0 */
 #define IA64_TASK_PID_OFFSET		188	/* 0xbc */
 #define IA64_TASK_MM_OFFSET		88	/* 0x58 */
 #define IA64_PT_REGS_CR_IPSR_OFFSET	0	/* 0x0 */
diff -u --recursive --new-file v2.3.47/linux/include/asm-ia64/page.h linux/include/asm-ia64/page.h
--- v2.3.47/linux/include/asm-ia64/page.h	Wed Feb 16 17:03:52 2000
+++ linux/include/asm-ia64/page.h	Thu Feb 24 10:14:29 2000
@@ -127,9 +127,10 @@
 #define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
 #define PAGE_BUG(page) do { BUG(); } while (0)
 
-extern __inline__ int get_order(unsigned long size)
+extern __inline__ int
+get_order (unsigned long size)
 {
-        double d = size - 1;
+	double d = size - 1;
 	long order;
                 
 	__asm__ ("getf.exp %0=%1" : "=r"(order) : "f"(d));
diff -u --recursive --new-file v2.3.47/linux/include/asm-ia64/pgalloc.h linux/include/asm-ia64/pgalloc.h
--- v2.3.47/linux/include/asm-ia64/pgalloc.h	Thu Feb 10 17:11:20 2000
+++ linux/include/asm-ia64/pgalloc.h	Thu Feb 24 10:14:29 2000
@@ -8,8 +8,8 @@
  * This hopefully works with any (fixed) ia-64 page-size, as defined
  * in <asm/page.h> (currently 8192).
  *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2000 Hewlett-Packard Co
+ * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 2000, Goutham Rao <goutham.rao@intel.com>
  */
 
@@ -252,6 +252,23 @@
 flush_tlb_page (struct vm_area_struct *vma, unsigned long addr)
 {
 	flush_tlb_range(vma->vm_mm, addr, addr + PAGE_SIZE);
+}
+
+/*
+ * Flush the TLB entries mapping the virtually mapped linear page
+ * table corresponding to address range [START-END).
+ */
+static inline void
+flush_tlb_pgtables (struct mm_struct *mm, unsigned long start, unsigned long end)
+{
+	/*
+	 * XXX fix mmap(), munmap() et al to guarantee that there are no mappings
+	 * across region boundaries. --davidm 00/02/23
+	 */
+	if (rgn_index(start) != rgn_index(end)) {
+		printk("flush_tlb_pgtables: can't flush across regions!!\n");
+	}
+	flush_tlb_range(mm, ia64_thash(start), ia64_thash(end));
 }
 
 #endif /* _ASM_IA64_PGALLOC_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-ia64/pgtable.h linux/include/asm-ia64/pgtable.h
--- v2.3.47/linux/include/asm-ia64/pgtable.h	Sun Feb 13 19:29:04 2000
+++ linux/include/asm-ia64/pgtable.h	Thu Feb 24 10:14:29 2000
@@ -294,6 +294,18 @@
  */
 #define pgprot_noncached(prot)	__pgprot((pgprot_val(prot) & ~_PAGE_MA_MASK) | _PAGE_MA_UC)
 
+/*
+ * Return the region index for virtual address ADDRESS.
+ */
+extern __inline__ unsigned long
+rgn_index (unsigned long address)
+{
+	ia64_va a;
+
+	a.l = address;
+	return a.f.reg;
+}
+
 extern __inline__ unsigned long
 pgd_index (unsigned long address)
 {
@@ -347,7 +359,7 @@
  * execution context?).
  *
  */
-#if 0
+#if 1
 # define update_mmu_cache(vma,address,pte)
 #else
 # define update_mmu_cache(vma,address,pte)							\
diff -u --recursive --new-file v2.3.47/linux/include/asm-ia64/processor.h linux/include/asm-ia64/processor.h
--- v2.3.47/linux/include/asm-ia64/processor.h	Thu Feb 10 17:11:20 2000
+++ linux/include/asm-ia64/processor.h	Thu Feb 24 10:14:29 2000
@@ -27,15 +27,11 @@
  */
 #define TASK_SIZE		0xa000000000000000
 
-#ifdef CONFIG_IA32_SUPPORT
-# define TASK_UNMAPPED_BASE	0x40000000	/* XXX fix me! */
-#else
 /*
  * This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#define TASK_UNMAPPED_BASE	0x2000000000000000
-#endif
+#define TASK_UNMAPPED_BASE	(current->thread.map_base)
 
 /*
  * Bus types
@@ -153,7 +149,12 @@
 
 #define IA64_THREAD_FPH_VALID	(__IA64_UL(1) << 0)	/* floating-point high state valid? */
 #define IA64_THREAD_DBG_VALID	(__IA64_UL(1) << 1)	/* debug registers valid? */
-#define IA64_KERNEL_DEATH	(__IA64_UL(1) << 63)	/* used for die_if_kernel() recursion detection */
+#define IA64_THREAD_UAC_NOPRINT	(__IA64_UL(1) << 2)	/* don't log unaligned accesses */
+#define IA64_THREAD_UAC_SIGBUS	(__IA64_UL(1) << 3)	/* generate SIGBUS on unaligned acc. */
+#define IA64_KERNEL_DEATH	(__IA64_UL(1) << 63)	/* see die_if_kernel()... */
+
+#define IA64_THREAD_UAC_SHIFT	2	
+#define IA64_THREAD_UAC_MASK	(IA64_THREAD_UAC_NOPRINT | IA64_THREAD_UAC_SIGBUS)
 
 #ifndef __ASSEMBLY__
 
@@ -258,12 +259,24 @@
 	unsigned long seg;
 } mm_segment_t;
 
+#define SET_UNALIGN_CTL(task,value)								\
+({												\
+	(task)->thread.flags |= ((value) << IA64_THREAD_UAC_SHIFT) & IA64_THREAD_UAC_MASK;	\
+	0;											\
+})
+#define GET_UNALIGN_CTL(task,addr)								\
+({												\
+	put_user(((task)->thread.flags & IA64_THREAD_UAC_MASK) >> IA64_THREAD_UAC_SHIFT,	\
+		 (int *) (addr));								\
+})
+
 struct thread_struct {
 	__u64 ksp;			/* kernel stack pointer */
 	unsigned long flags;		/* various flags */
 	struct ia64_fpreg fph[96];	/* saved/loaded on demand */
 	__u64 dbr[IA64_NUM_DBG_REGS];
 	__u64 ibr[IA64_NUM_DBG_REGS];
+	__u64 map_base;			/* base address for mmap() */
 #ifdef CONFIG_IA32_SUPPORT
 	__u64 fsr;			/* IA32 floating pt status reg */
 	__u64 fcr;			/* IA32 floating pt control reg */
@@ -285,7 +298,8 @@
 	0,				/* flags */	\
 	{{{{0}}}, },			/* fph */	\
 	{0, },				/* dbr */	\
-	{0, }				/* ibr */	\
+	{0, },				/* ibr */	\
+	0x2000000000000000		/* map_base */	\
 	INIT_THREAD_IA32				\
 }
 
@@ -780,6 +794,14 @@
 #endif
 
 #define ia64_rotl(w,n)	ia64_rotr((w),(64)-(n))
+
+extern __inline__ __u64
+ia64_thash (__u64 addr)
+{
+	__u64 result;
+	asm ("thash %0=%1" : "=r"(result) : "r" (addr));
+	return result;
+}
 
 #endif /* !__ASSEMBLY__ */
 
diff -u --recursive --new-file v2.3.47/linux/include/asm-ia64/siginfo.h linux/include/asm-ia64/siginfo.h
--- v2.3.47/linux/include/asm-ia64/siginfo.h	Thu Feb 10 17:11:20 2000
+++ linux/include/asm-ia64/siginfo.h	Thu Feb 24 10:14:29 2000
@@ -54,12 +54,13 @@
 
 		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
 		struct {
-			void *_addr; /* faulting insn/memory ref. */
+			void *_addr;		/* faulting insn/memory ref. */
+			int _imm;		/* immediate value for "break" */
 		} _sigfault;
 
 		/* SIGPOLL */
 		struct {
-			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			long _band;	/* POLL_IN, POLL_OUT, POLL_MSG (XPG requires a "long") */
 			int _fd;
 		} _sigpoll;
 	} _sifields;
@@ -77,6 +78,7 @@
 #define si_int		_sifields._rt._sigval.sival_int
 #define si_ptr		_sifields._rt._sigval.sival_ptr
 #define si_addr		_sifields._sigfault._addr
+#define si_imm		_sifields._sigfault._imm	/* as per UNIX SysV ABI spec */
 #define si_band		_sifields._sigpoll._band
 #define si_fd		_sifields._sigpoll._fd
 
@@ -106,8 +108,9 @@
 #define ILL_PRVREG	6	/* privileged register */
 #define ILL_COPROC	7	/* coprocessor error */
 #define ILL_BADSTK	8	/* internal stack error */
-#define ILL_BADIADDR    9	/* Unimplemented instruction address */
-#define NSIGILL		9
+#define ILL_BADIADDR    9	/* unimplemented instruction address */
+#define __ILL_BREAK	10	/* illegal break */
+#define NSIGILL		10
 
 /*
  * SIGFPE si_codes
@@ -120,14 +123,20 @@
 #define FPE_FLTRES	6	/* floating point inexact result */
 #define FPE_FLTINV	7	/* floating point invalid operation */
 #define FPE_FLTSUB	8	/* subscript out of range */
-#define NSIGFPE		8
+#define __FPE_DECOVF	9	/* decimal overflow */
+#define __FPE_DECDIV	10	/* decimal division by zero */
+#define __FPE_DECERR	11	/* packed decimal error */
+#define __FPE_INVASC	12	/* invalid ASCII digit */
+#define __FPE_INVDEC	13	/* invalid decimal digit */
+#define NSIGFPE		13
 
 /*
  * SIGSEGV si_codes
  */
 #define SEGV_MAPERR	1	/* address not mapped to object */
 #define SEGV_ACCERR	2	/* invalid permissions for mapped object */
-#define NSIGSEGV	2
+#define __SEGV_PSTKOVF	3	/* paragraph stack overflow */
+#define NSIGSEGV	3
 
 /*
  * SIGBUS si_codes
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/asm.h linux/include/asm-mips/asm.h
--- v2.3.47/linux/include/asm-mips/asm.h	Thu Jun 26 12:33:39 1997
+++ linux/include/asm-mips/asm.h	Thu Feb 24 22:52:30 2000
@@ -151,17 +151,17 @@
 /*
  * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
  */
-#if _MIPS_ISA == _MIPS_ISA_MIPS1
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1)
 #define MOVN(rd,rs,rt)                                  \
 		.set	push;				\
-		.set	reorder;			\
+		.set	noreorder;			\
 		beqz	rt,9f;                          \
 		move	rd,rs;                          \
 		.set	pop;				\
 9:
 #define MOVZ(rd,rs,rt)                                  \
 		.set	push;				\
-		.set	reorder;			\
+		.set	noreorder;			\
 		bnez	rt,9f;                          \
 		move	rd,rt;                          \
 		.set	pop;				\
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/asmmacro.h linux/include/asm-mips/asmmacro.h
--- v2.3.47/linux/include/asm-mips/asmmacro.h	Fri May  8 00:13:26 1998
+++ linux/include/asm-mips/asmmacro.h	Thu Feb 24 22:52:30 2000
@@ -4,157 +4,123 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1998 Ralf Baechle
  *
- * $Id: asmmacro.h,v 1.2 1998/05/01 01:35:44 ralf Exp $
+ * $Id: asmmacro.h,v 1.4 1999/08/18 23:37:49 ralf Exp $
  */
 #ifndef __MIPS_ASMMACRO_H
 #define __MIPS_ASMMACRO_H
 
 #include <asm/offset.h>
 
-#define FPU_SAVE_16EVEN(thread, tmp) \
+#define FPU_SAVE_DOUBLE(thread, tmp) \
 	cfc1	tmp,  fcr31;                    \
-	sdc1	$f2,  (THREAD_FPU + 0x010)(thread); \
-	sdc1	$f4,  (THREAD_FPU + 0x020)(thread); \
-	sdc1	$f6,  (THREAD_FPU + 0x030)(thread); \
-	sdc1	$f8,  (THREAD_FPU + 0x040)(thread); \
-	sdc1	$f10, (THREAD_FPU + 0x050)(thread); \
-	sdc1	$f12, (THREAD_FPU + 0x060)(thread); \
-	sdc1	$f14, (THREAD_FPU + 0x070)(thread); \
-	sdc1	$f16, (THREAD_FPU + 0x080)(thread); \
-	sdc1	$f18, (THREAD_FPU + 0x090)(thread); \
-	sdc1	$f20, (THREAD_FPU + 0x0a0)(thread); \
-	sdc1	$f22, (THREAD_FPU + 0x0b0)(thread); \
-	sdc1	$f24, (THREAD_FPU + 0x0c0)(thread); \
-	sdc1	$f26, (THREAD_FPU + 0x0d0)(thread); \
-	sdc1	$f28, (THREAD_FPU + 0x0e0)(thread); \
-	sdc1	$f30, (THREAD_FPU + 0x0f0)(thread); \
-	sw	tmp,  (THREAD_FPU + 0x100)(thread)
+	sdc1	$f0,  (THREAD_FPU + 0x000)(thread); \
+	sdc1	$f2,  (THREAD_FPU + 0x008)(thread); \
+	sdc1	$f4,  (THREAD_FPU + 0x010)(thread); \
+	sdc1	$f6,  (THREAD_FPU + 0x018)(thread); \
+	sdc1	$f8,  (THREAD_FPU + 0x020)(thread); \
+	sdc1	$f10, (THREAD_FPU + 0x028)(thread); \
+	sdc1	$f12, (THREAD_FPU + 0x030)(thread); \
+	sdc1	$f14, (THREAD_FPU + 0x038)(thread); \
+	sdc1	$f16, (THREAD_FPU + 0x040)(thread); \
+	sdc1	$f18, (THREAD_FPU + 0x048)(thread); \
+	sdc1	$f20, (THREAD_FPU + 0x050)(thread); \
+	sdc1	$f22, (THREAD_FPU + 0x058)(thread); \
+	sdc1	$f24, (THREAD_FPU + 0x060)(thread); \
+	sdc1	$f26, (THREAD_FPU + 0x068)(thread); \
+	sdc1	$f28, (THREAD_FPU + 0x070)(thread); \
+	sdc1	$f30, (THREAD_FPU + 0x078)(thread); \
+	sw	tmp,  (THREAD_FPU + 0x080)(thread)
 
-#define FPU_SAVE_16ODD(thread) \
-	sdc1	$f1,  (THREAD_FPU + 0x08)(thread); \
-	sdc1	$f3,  (THREAD_FPU + 0x18)(thread); \
-	sdc1	$f5,  (THREAD_FPU + 0x28)(thread); \
-	sdc1	$f7,  (THREAD_FPU + 0x38)(thread); \
-	sdc1	$f9,  (THREAD_FPU + 0x48)(thread); \
-	sdc1	$f11, (THREAD_FPU + 0x58)(thread); \
-	sdc1	$f13, (THREAD_FPU + 0x68)(thread); \
-	sdc1	$f15, (THREAD_FPU + 0x78)(thread); \
-	sdc1	$f17, (THREAD_FPU + 0x88)(thread); \
-	sdc1	$f19, (THREAD_FPU + 0x98)(thread); \
-	sdc1	$f21, (THREAD_FPU + 0xa8)(thread); \
-	sdc1	$f23, (THREAD_FPU + 0xb8)(thread); \
-	sdc1	$f25, (THREAD_FPU + 0xc8)(thread); \
-	sdc1	$f27, (THREAD_FPU + 0xd8)(thread); \
-	sdc1	$f29, (THREAD_FPU + 0xe8)(thread); \
-	sdc1	$f31, (THREAD_FPU + 0xf8)(thread)
-
-#define FPU_SAVE(thread,tmp)                        \
+#define FPU_SAVE_SINGLE(thread,tmp)                 \
 	cfc1	tmp,  fcr31;                        \
 	swc1	$f0,  (THREAD_FPU + 0x000)(thread); \
-	swc1	$f1,  (THREAD_FPU + 0x008)(thread); \
-	swc1	$f2,  (THREAD_FPU + 0x010)(thread); \
-	swc1	$f3,  (THREAD_FPU + 0x018)(thread); \
-	swc1	$f4,  (THREAD_FPU + 0x020)(thread); \
-	swc1	$f5,  (THREAD_FPU + 0x028)(thread); \
-	swc1	$f6,  (THREAD_FPU + 0x030)(thread); \
-	swc1	$f7,  (THREAD_FPU + 0x038)(thread); \
-	swc1	$f8,  (THREAD_FPU + 0x040)(thread); \
-	swc1	$f9,  (THREAD_FPU + 0x048)(thread); \
-	swc1	$f10, (THREAD_FPU + 0x050)(thread); \
-	swc1	$f11, (THREAD_FPU + 0x058)(thread); \
-	swc1	$f12, (THREAD_FPU + 0x060)(thread); \
-	swc1	$f13, (THREAD_FPU + 0x068)(thread); \
-	swc1	$f14, (THREAD_FPU + 0x070)(thread); \
-	swc1	$f15, (THREAD_FPU + 0x078)(thread); \
-	swc1	$f16, (THREAD_FPU + 0x080)(thread); \
-	swc1	$f17, (THREAD_FPU + 0x088)(thread); \
-	swc1	$f18, (THREAD_FPU + 0x090)(thread); \
-	swc1	$f19, (THREAD_FPU + 0x098)(thread); \
-	swc1	$f20, (THREAD_FPU + 0x0a0)(thread); \
-	swc1	$f21, (THREAD_FPU + 0x0a8)(thread); \
-	swc1	$f22, (THREAD_FPU + 0x0b0)(thread); \
-	swc1	$f23, (THREAD_FPU + 0x0b8)(thread); \
-	swc1	$f24, (THREAD_FPU + 0x0c0)(thread); \
-	swc1	$f25, (THREAD_FPU + 0x0c8)(thread); \
-	swc1	$f26, (THREAD_FPU + 0x0d0)(thread); \
-	swc1	$f27, (THREAD_FPU + 0x0d8)(thread); \
-	swc1	$f28, (THREAD_FPU + 0x0e0)(thread); \
-	swc1	$f29, (THREAD_FPU + 0x0e8)(thread); \
-	swc1	$f30, (THREAD_FPU + 0x0f0)(thread); \
-	swc1	$f31, (THREAD_FPU + 0x0f8)(thread); \
-	sw	tmp,  (THREAD_FPU + 0x100)(thread)
-
-#define FPU_RESTORE_16EVEN(thread, tmp) \
-	lw	tmp,  (THREAD_FPU + 0x100)(thread); \
-	ldc1	$f2,  (THREAD_FPU + 0x010)(thread); \
-	ldc1	$f4,  (THREAD_FPU + 0x020)(thread); \
-	ldc1	$f6,  (THREAD_FPU + 0x030)(thread); \
-	ldc1	$f8,  (THREAD_FPU + 0x040)(thread); \
-	ldc1	$f10, (THREAD_FPU + 0x050)(thread); \
-	ldc1	$f12, (THREAD_FPU + 0x060)(thread); \
-	ldc1	$f14, (THREAD_FPU + 0x070)(thread); \
-	ldc1	$f16, (THREAD_FPU + 0x080)(thread); \
-	ldc1	$f18, (THREAD_FPU + 0x090)(thread); \
-	ldc1	$f20, (THREAD_FPU + 0x0a0)(thread); \
-	ldc1	$f22, (THREAD_FPU + 0x0b0)(thread); \
-	ldc1	$f24, (THREAD_FPU + 0x0c0)(thread); \
-	ldc1	$f26, (THREAD_FPU + 0x0d0)(thread); \
-	ldc1	$f28, (THREAD_FPU + 0x0e0)(thread); \
-	ldc1	$f30, (THREAD_FPU + 0x0f0)(thread); \
+	swc1	$f1,  (THREAD_FPU + 0x004)(thread); \
+	swc1	$f2,  (THREAD_FPU + 0x008)(thread); \
+	swc1	$f3,  (THREAD_FPU + 0x00c)(thread); \
+	swc1	$f4,  (THREAD_FPU + 0x010)(thread); \
+	swc1	$f5,  (THREAD_FPU + 0x014)(thread); \
+	swc1	$f6,  (THREAD_FPU + 0x018)(thread); \
+	swc1	$f7,  (THREAD_FPU + 0x01c)(thread); \
+	swc1	$f8,  (THREAD_FPU + 0x020)(thread); \
+	swc1	$f9,  (THREAD_FPU + 0x024)(thread); \
+	swc1	$f10, (THREAD_FPU + 0x028)(thread); \
+	swc1	$f11, (THREAD_FPU + 0x02c)(thread); \
+	swc1	$f12, (THREAD_FPU + 0x030)(thread); \
+	swc1	$f13, (THREAD_FPU + 0x034)(thread); \
+	swc1	$f14, (THREAD_FPU + 0x038)(thread); \
+	swc1	$f15, (THREAD_FPU + 0x03c)(thread); \
+	swc1	$f16, (THREAD_FPU + 0x040)(thread); \
+	swc1	$f17, (THREAD_FPU + 0x044)(thread); \
+	swc1	$f18, (THREAD_FPU + 0x048)(thread); \
+	swc1	$f19, (THREAD_FPU + 0x04c)(thread); \
+	swc1	$f20, (THREAD_FPU + 0x050)(thread); \
+	swc1	$f21, (THREAD_FPU + 0x054)(thread); \
+	swc1	$f22, (THREAD_FPU + 0x058)(thread); \
+	swc1	$f23, (THREAD_FPU + 0x05c)(thread); \
+	swc1	$f24, (THREAD_FPU + 0x060)(thread); \
+	swc1	$f25, (THREAD_FPU + 0x064)(thread); \
+	swc1	$f26, (THREAD_FPU + 0x068)(thread); \
+	swc1	$f27, (THREAD_FPU + 0x06c)(thread); \
+	swc1	$f28, (THREAD_FPU + 0x070)(thread); \
+	swc1	$f29, (THREAD_FPU + 0x074)(thread); \
+	swc1	$f30, (THREAD_FPU + 0x078)(thread); \
+	swc1	$f31, (THREAD_FPU + 0x07c)(thread); \
+	sw	tmp,  (THREAD_FPU + 0x080)(thread)
+
+#define FPU_RESTORE_DOUBLE(thread, tmp) \
+	lw	tmp,  (THREAD_FPU + 0x080)(thread); \
+	ldc1	$f0,  (THREAD_FPU + 0x000)(thread); \
+	ldc1	$f2,  (THREAD_FPU + 0x008)(thread); \
+	ldc1	$f4,  (THREAD_FPU + 0x010)(thread); \
+	ldc1	$f6,  (THREAD_FPU + 0x018)(thread); \
+	ldc1	$f8,  (THREAD_FPU + 0x020)(thread); \
+	ldc1	$f10, (THREAD_FPU + 0x028)(thread); \
+	ldc1	$f12, (THREAD_FPU + 0x030)(thread); \
+	ldc1	$f14, (THREAD_FPU + 0x038)(thread); \
+	ldc1	$f16, (THREAD_FPU + 0x040)(thread); \
+	ldc1	$f18, (THREAD_FPU + 0x048)(thread); \
+	ldc1	$f20, (THREAD_FPU + 0x050)(thread); \
+	ldc1	$f22, (THREAD_FPU + 0x058)(thread); \
+	ldc1	$f24, (THREAD_FPU + 0x060)(thread); \
+	ldc1	$f26, (THREAD_FPU + 0x068)(thread); \
+	ldc1	$f28, (THREAD_FPU + 0x070)(thread); \
+	ldc1	$f30, (THREAD_FPU + 0x078)(thread); \
 	ctc1	tmp,  fcr31
 
-#define FPU_RESTORE_16ODD(thread)  \
-	ldc1	$f1,  (THREAD_FPU + 0x08)(thread); \
-	ldc1	$f3,  (THREAD_FPU + 0x18)(thread); \
-	ldc1	$f5,  (THREAD_FPU + 0x28)(thread); \
-	ldc1	$f7,  (THREAD_FPU + 0x38)(thread); \
-	ldc1	$f9,  (THREAD_FPU + 0x48)(thread); \
-	ldc1	$f11, (THREAD_FPU + 0x58)(thread); \
-	ldc1	$f13, (THREAD_FPU + 0x68)(thread); \
-	ldc1	$f15, (THREAD_FPU + 0x78)(thread); \
-	ldc1	$f17, (THREAD_FPU + 0x88)(thread); \
-	ldc1	$f19, (THREAD_FPU + 0x98)(thread); \
-	ldc1	$f21, (THREAD_FPU + 0xa8)(thread); \
-	ldc1	$f23, (THREAD_FPU + 0xb8)(thread); \
-	ldc1	$f25, (THREAD_FPU + 0xc8)(thread); \
-	ldc1	$f27, (THREAD_FPU + 0xd8)(thread); \
-	ldc1	$f29, (THREAD_FPU + 0xe8)(thread); \
-	ldc1	$f31, (THREAD_FPU + 0xf8)(thread)
-
-#define FPU_RESTORE(thread,tmp)                     \
-	lw	tmp,  (THREAD_FPU + 0x100)(thread); \
+#define FPU_RESTORE_SINGLE(thread,tmp)              \
+	lw	tmp,  (THREAD_FPU + 0x080)(thread); \
 	lwc1	$f0,  (THREAD_FPU + 0x000)(thread); \
-	lwc1	$f1,  (THREAD_FPU + 0x008)(thread); \
-	lwc1	$f2,  (THREAD_FPU + 0x010)(thread); \
-	lwc1	$f3,  (THREAD_FPU + 0x018)(thread); \
-	lwc1	$f4,  (THREAD_FPU + 0x020)(thread); \
-	lwc1	$f5,  (THREAD_FPU + 0x028)(thread); \
-	lwc1	$f6,  (THREAD_FPU + 0x030)(thread); \
-	lwc1	$f7,  (THREAD_FPU + 0x038)(thread); \
-	lwc1	$f8,  (THREAD_FPU + 0x040)(thread); \
-	lwc1	$f9,  (THREAD_FPU + 0x048)(thread); \
-	lwc1	$f10, (THREAD_FPU + 0x050)(thread); \
-	lwc1	$f11, (THREAD_FPU + 0x058)(thread); \
-	lwc1	$f12, (THREAD_FPU + 0x060)(thread); \
-	lwc1	$f13, (THREAD_FPU + 0x068)(thread); \
-	lwc1	$f14, (THREAD_FPU + 0x070)(thread); \
-	lwc1	$f15, (THREAD_FPU + 0x078)(thread); \
-	lwc1	$f16, (THREAD_FPU + 0x080)(thread); \
-	lwc1	$f17, (THREAD_FPU + 0x088)(thread); \
-	lwc1	$f18, (THREAD_FPU + 0x090)(thread); \
-	lwc1	$f19, (THREAD_FPU + 0x098)(thread); \
-	lwc1	$f20, (THREAD_FPU + 0x0a0)(thread); \
-	lwc1	$f21, (THREAD_FPU + 0x0a8)(thread); \
-	lwc1	$f22, (THREAD_FPU + 0x0b0)(thread); \
-	lwc1	$f23, (THREAD_FPU + 0x0b8)(thread); \
-	lwc1	$f24, (THREAD_FPU + 0x0c0)(thread); \
-	lwc1	$f25, (THREAD_FPU + 0x0c8)(thread); \
-	lwc1	$f26, (THREAD_FPU + 0x0d0)(thread); \
-	lwc1	$f27, (THREAD_FPU + 0x0d8)(thread); \
-	lwc1	$f28, (THREAD_FPU + 0x0e0)(thread); \
-	lwc1	$f29, (THREAD_FPU + 0x0e8)(thread); \
-	lwc1	$f30, (THREAD_FPU + 0x0f0)(thread); \
-	lwc1	$f31, (THREAD_FPU + 0x0f8)(thread); \
+	lwc1	$f1,  (THREAD_FPU + 0x004)(thread); \
+	lwc1	$f2,  (THREAD_FPU + 0x008)(thread); \
+	lwc1	$f3,  (THREAD_FPU + 0x00c)(thread); \
+	lwc1	$f4,  (THREAD_FPU + 0x010)(thread); \
+	lwc1	$f5,  (THREAD_FPU + 0x014)(thread); \
+	lwc1	$f6,  (THREAD_FPU + 0x018)(thread); \
+	lwc1	$f7,  (THREAD_FPU + 0x01c)(thread); \
+	lwc1	$f8,  (THREAD_FPU + 0x020)(thread); \
+	lwc1	$f9,  (THREAD_FPU + 0x024)(thread); \
+	lwc1	$f10, (THREAD_FPU + 0x028)(thread); \
+	lwc1	$f11, (THREAD_FPU + 0x02c)(thread); \
+	lwc1	$f12, (THREAD_FPU + 0x030)(thread); \
+	lwc1	$f13, (THREAD_FPU + 0x034)(thread); \
+	lwc1	$f14, (THREAD_FPU + 0x038)(thread); \
+	lwc1	$f15, (THREAD_FPU + 0x03c)(thread); \
+	lwc1	$f16, (THREAD_FPU + 0x040)(thread); \
+	lwc1	$f17, (THREAD_FPU + 0x044)(thread); \
+	lwc1	$f18, (THREAD_FPU + 0x048)(thread); \
+	lwc1	$f19, (THREAD_FPU + 0x04c)(thread); \
+	lwc1	$f20, (THREAD_FPU + 0x050)(thread); \
+	lwc1	$f21, (THREAD_FPU + 0x054)(thread); \
+	lwc1	$f22, (THREAD_FPU + 0x058)(thread); \
+	lwc1	$f23, (THREAD_FPU + 0x05c)(thread); \
+	lwc1	$f24, (THREAD_FPU + 0x060)(thread); \
+	lwc1	$f25, (THREAD_FPU + 0x064)(thread); \
+	lwc1	$f26, (THREAD_FPU + 0x068)(thread); \
+	lwc1	$f27, (THREAD_FPU + 0x06c)(thread); \
+	lwc1	$f28, (THREAD_FPU + 0x070)(thread); \
+	lwc1	$f29, (THREAD_FPU + 0x074)(thread); \
+	lwc1	$f30, (THREAD_FPU + 0x078)(thread); \
+	lwc1	$f31, (THREAD_FPU + 0x07c)(thread); \
 	ctc1	tmp,  fcr31
 
 #define CPU_SAVE_NONSCRATCH(thread) \
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/atomic.h linux/include/asm-mips/atomic.h
--- v2.3.47/linux/include/asm-mips/atomic.h	Mon Jul 19 13:12:47 1999
+++ linux/include/asm-mips/atomic.h	Thu Feb 24 22:52:30 2000
@@ -11,12 +11,12 @@
  *
  * Copyright (C) 1996, 1997 by Ralf Baechle
  *
- * $Id: atomic.h,v 1.4 1998/05/01 01:35:45 ralf Exp $
+ * $Id: atomic.h,v 1.7 1999/08/13 17:07:27 harald Exp $
  */
 #ifndef __ASM_MIPS_ATOMIC_H
 #define __ASM_MIPS_ATOMIC_H
 
-#include <asm/sgidefs.h>
+#include <linux/config.h>
 
 #ifdef __SMP__
 typedef struct { volatile int counter; } atomic_t;
@@ -30,7 +30,7 @@
 #define atomic_read(v)	((v)->counter)
 #define atomic_set(v,i)	((v)->counter = (i))
 
-#if (_MIPS_ISA == _MIPS_ISA_MIPS1)
+#if !defined(CONFIG_CPU_HAS_LLSC)
 
 #include <asm/system.h>
 
@@ -44,7 +44,7 @@
 
 	save_flags(flags);
 	cli();
-	*v += i;
+	v->counter += i;
 	restore_flags(flags);
 }
 
@@ -54,7 +54,7 @@
 
 	save_flags(flags);
 	cli();
-	*v -= i;
+	v->counter -= i;
 	restore_flags(flags);
 }
 
@@ -64,9 +64,9 @@
 
 	save_flags(flags);
 	cli();
-	temp = *v;
+	temp = v->counter;
 	temp += i;
-	*v = temp;
+	v->counter = temp;
 	restore_flags(flags);
 
 	return temp;
@@ -78,17 +78,31 @@
 
 	save_flags(flags);
 	cli();
-	temp = *v;
+	temp = v->counter;
 	temp -= i;
-	*v = temp;
+	v->counter = temp;
 	restore_flags(flags);
 
 	return temp;
 }
-#endif
 
-#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \
-    (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
+extern __inline__ void atomic_clear_mask(unsigned long mask, unsigned long * v)
+{
+        unsigned long temp;
+        int     flags;
+
+        save_flags(flags);
+        cli();
+        temp = *v;
+        temp &= ~mask;
+        *v = temp;
+        restore_flags(flags);
+
+        return;
+}
+
+#else
+
 /*
  * ... while for MIPS II and better we can use ll/sc instruction.  This
  * implementation is SMP safe ...
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/baget/baget.h linux/include/asm-mips/baget/baget.h
--- v2.3.47/linux/include/asm-mips/baget/baget.h	Fri Jun 25 17:37:52 1999
+++ linux/include/asm-mips/baget/baget.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: baget.h,v 1.2 1999/04/11 17:03:40 harald Exp $
  * baget.h: Definitions specific to Baget/MIPS machines.
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/baget/vac.h linux/include/asm-mips/baget/vac.h
--- v2.3.47/linux/include/asm-mips/baget/vac.h	Fri Jun 25 17:37:52 1999
+++ linux/include/asm-mips/baget/vac.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: vac.h,v 1.2 1999/04/11 17:03:40 harald Exp $
  *
  * vac.h: Various VIC controller defines.  The VIC is a VME controller
  *        used in Baget/MIPS series.
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/baget/vic.h linux/include/asm-mips/baget/vic.h
--- v2.3.47/linux/include/asm-mips/baget/vic.h	Fri Jun 25 17:37:52 1999
+++ linux/include/asm-mips/baget/vic.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: vic.h,v 1.1 1999/01/27 23:59:07 ralf Exp $
  *
  * vic.h: Various VIC controller defines.  The VIC is an interrupt controller
  *        used in Baget/MIPS series.
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/bcache.h linux/include/asm-mips/bcache.h
--- v2.3.47/linux/include/asm-mips/bcache.h	Fri May  8 00:13:26 1998
+++ linux/include/asm-mips/bcache.h	Thu Feb 24 22:52:30 2000
@@ -1,14 +1,14 @@
-/*
- * include/asm-mips/bcache.h
+/* $Id: bcache.h,v 1.2 1999/08/20 21:59:07 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1997 by Ralf Baechle
- *
- * $Id: bcache.h,v 1.1 1998/05/01 01:35:46 ralf Exp $
+ * Copyright (c) 1997, 1999 by Ralf Baechle
  */
+#ifndef _ASM_BCACHE_H
+#define _ASM_BCACHE_H
+
 struct bcache_ops {
 	void (*bc_enable)(void);
 	void (*bc_disable)(void);
@@ -20,3 +20,5 @@
 extern void sni_pcimt_sc_init(void);
 
 extern struct bcache_ops *bcops;
+
+#endif /* _ASM_BCACHE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/bitops.h linux/include/asm-mips/bitops.h
--- v2.3.47/linux/include/asm-mips/bitops.h	Mon Jul 20 17:23:32 1998
+++ linux/include/asm-mips/bitops.h	Thu Feb 24 22:52:30 2000
@@ -1,22 +1,22 @@
-/*
- * include/asm-mips/bitops.h
+/* $Id: bitops.h,v 1.7 1999/08/19 22:56:33 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1994 - 1997  Ralf Baechle (ralf@gnu.org)
+ * Copyright (c) 1994 - 1997, 1999  Ralf Baechle (ralf@gnu.org)
  */
-#ifndef __ASM_MIPS_BITOPS_H
-#define __ASM_MIPS_BITOPS_H
+#ifndef _ASM_BITOPS_H
+#define _ASM_BITOPS_H
 
 #include <linux/types.h>
-#include <linux/byteorder/swab.h>		/* sigh ... */
+#include <asm/byteorder.h>		/* sigh ... */
 
 #ifdef __KERNEL__
 
 #include <asm/sgidefs.h>
 #include <asm/system.h>
+#include <linux/config.h>
 
 /*
  * Only disable interrupt for kernel mode stuff to keep usermode stuff
@@ -25,11 +25,13 @@
 #define __bi_flags unsigned long flags
 #define __bi_cli() __cli()
 #define __bi_save_flags(x) __save_flags(x)
+#define __bi_save_and_cli(x) __save_and_cli(x)
 #define __bi_restore_flags(x) __restore_flags(x)
 #else
 #define __bi_flags
 #define __bi_cli()
 #define __bi_save_flags(x)
+#define __bi_save_and_cli(x)
 #define __bi_restore_flags(x)
 #endif /* __KERNEL__ */
 
@@ -52,8 +54,7 @@
 extern __inline__ int find_next_zero_bit (void * addr, int size, int offset);
 extern __inline__ unsigned long ffz(unsigned long word);
 
-#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \
-    (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
+#if defined(CONFIG_CPU_HAS_LLSC)
 
 /*
  * These functions for MIPS ISA > 1 are interrupt and SMP proof and
@@ -144,6 +145,8 @@
 
 #else /* MIPS I */
 
+#include <asm/mipsregs.h>
+
 extern __inline__ void set_bit(int nr, void * addr)
 {
 	int	mask;
@@ -152,8 +155,7 @@
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	__bi_save_flags(flags);
-	__bi_cli();
+	__bi_save_and_cli(flags);
 	*a |= mask;
 	__bi_restore_flags(flags);
 }
@@ -166,8 +168,7 @@
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	__bi_save_flags(flags);
-	__bi_cli();
+	__bi_save_and_cli(flags);
 	*a &= ~mask;
 	__bi_restore_flags(flags);
 }
@@ -180,8 +181,7 @@
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	__bi_save_flags(flags);
-	__bi_cli();
+	__bi_save_and_cli(flags);
 	*a ^= mask;
 	__bi_restore_flags(flags);
 }
@@ -194,8 +194,7 @@
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	__bi_save_flags(flags);
-	__bi_cli();
+	__bi_save_and_cli(flags);
 	retval = (mask & *a) != 0;
 	*a |= mask;
 	__bi_restore_flags(flags);
@@ -211,8 +210,7 @@
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	__bi_save_flags(flags);
-	__bi_cli();
+	__bi_save_and_cli(flags);
 	retval = (mask & *a) != 0;
 	*a &= ~mask;
 	__bi_restore_flags(flags);
@@ -228,8 +226,7 @@
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	__bi_save_flags(flags);
-	__bi_cli();
+	__bi_save_and_cli(flags);
 	retval = (mask & *a) != 0;
 	*a ^= mask;
 	__bi_restore_flags(flags);
@@ -457,7 +454,7 @@
 
 	ADDR += nr >> 3;
 	mask = 1 << (nr & 0x07);
-	save_flags(flags); cli();
+	save_and_cli(flags);
 	retval = (mask & *ADDR) != 0;
 	*ADDR |= mask;
 	restore_flags(flags);
@@ -471,7 +468,7 @@
 
 	ADDR += nr >> 3;
 	mask = 1 << (nr & 0x07);
-	save_flags(flags); cli();
+	save_and_cli(flags);
 	retval = (mask & *ADDR) != 0;
 	*ADDR &= ~mask;
 	restore_flags(flags);
@@ -562,4 +559,4 @@
 #define minix_test_bit(nr,addr) test_bit(nr,addr)
 #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
 
-#endif /* __ASM_MIPS_BITOPS_H */
+#endif /* _ASM_BITOPS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/bootinfo.h linux/include/asm-mips/bootinfo.h
--- v2.3.47/linux/include/asm-mips/bootinfo.h	Fri Jun 25 17:37:52 1999
+++ linux/include/asm-mips/bootinfo.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: bootinfo.h,v 1.5 1998/08/19 21:58:10 ralf Exp $
+/* $Id: bootinfo.h,v 1.10 2000/01/26 00:07:45 ralf Exp $
  *
  * bootinfo.h -- Definition of the Linux/MIPS boot information structure
  *
@@ -26,9 +26,10 @@
 #define MACH_GROUP_ACN		5
 #define MACH_GROUP_SGI          6 /* Silicon Graphics workstations and servers */
 #define MACH_GROUP_COBALT       7 /* Cobalt servers		 	      */
+#define MACH_GROUP_NEC_DDB	8 /* NEC DDB */
 
 #define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", \
-                      "SNI", "ACN", "SGI", "Cobalt" }
+                      "SNI", "ACN", "SGI", "Cobalt", "NEC DDB" }
 
 /*
  * Valid machtype values for group unknown (low order halfword of mips_machtype)
@@ -102,6 +103,13 @@
 #define GROUP_COBALT_NAMES { "Microserver 27" }
 
 /*
+ * Valid machtype for group NEC DDB
+ */
+#define MACH_NEC_DDB5074	 0	/* NEC DDB Vrc-5074 */
+
+#define GROUP_NEC_DDB_NAMES { "Vrc-5074" }
+
+/*
  * Valid cputype values
  */
 #define CPU_UNKNOWN		0
@@ -161,19 +169,8 @@
 	unsigned short lines;
 } mips_arc_DisplayInfo;
 
-#ifdef CONFIG_SGI
-/* screen info will dissapear... soon */
-//#define DEFAULT_SCREEN_INFO {0, 0, 0, 0, 0, 158, 0, 0, 0, 62, 0, 16}
-#define DEFAULT_SCREEN_INFO {0, 0, 0, 0, 0, 160, 0, 0, 0, 64, 0, 16}
-#define DEFAULT_DRIVE_INFO { {0,}}
-#else
-/* default values for screen_info variable (Colour VGA) */
-#define DEFAULT_SCREEN_INFO {0, 0, 0, 52, 3, 80, 4626, 3, 9, 50, 0x22, 16}
-#endif
-
 /* default values for drive info */
 #define DEFAULT_DRIVE_INFO { {0,}}
-
 
 /*
  * These are the kernel variables initialized from
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/branch.h linux/include/asm-mips/branch.h
--- v2.3.47/linux/include/asm-mips/branch.h	Fri May  8 00:13:26 1998
+++ linux/include/asm-mips/branch.h	Thu Feb 24 22:52:30 2000
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
  *
- * $Id: branch.h,v 1.2 1998/05/04 09:18:56 ralf Exp $
+ * $Id: branch.h,v 1.2 1998/05/04 09:13:00 ralf Exp $
  */
 #include <asm/ptrace.h>
 
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/bugs.h linux/include/asm-mips/bugs.h
--- v2.3.47/linux/include/asm-mips/bugs.h	Fri May  8 00:13:26 1998
+++ linux/include/asm-mips/bugs.h	Thu Feb 24 22:52:30 2000
@@ -1,10 +1,7 @@
-/*
- *  include/asm-mips/bugs.h
- *
- *  Copyright (C) 1995  Waldorf Electronics
- *  Copyright (C) 1997  Ralf Baechle
+/* $Id: bugs.h,v 1.4 1999/08/18 23:37:49 ralf Exp $
  *
- * $Id: bugs.h,v 1.4 1998/05/01 01:35:47 ralf Exp $
+ * Copyright (C) 1995  Waldorf Electronics
+ * Copyright (C) 1997, 1999  Ralf Baechle
  */
 #include <asm/bootinfo.h>
 
@@ -37,7 +34,8 @@
 	}
 }
 
-static void check_bugs(void)
+static void __init
+check_bugs(void)
 {
 	check_wait();
 }
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/cache.h linux/include/asm-mips/cache.h
--- v2.3.47/linux/include/asm-mips/cache.h	Mon Mar 15 16:11:55 1999
+++ linux/include/asm-mips/cache.h	Thu Feb 24 22:52:30 2000
@@ -1,14 +1,21 @@
-/*
- * include/asm-mips/cache.h
+/* $Id: cache.h,v 1.4 2000/02/04 07:40:53 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_CACHE_H
-#define __ASM_MIPS_CACHE_H
+#ifndef _ASM_CACHE_H
+#define _ASM_CACHE_H
 
-/* bytes per L1 cache line */
-#define        L1_CACHE_BYTES  32      /* a guess */
+#include <linux/config.h>
 
-#define        L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_R6000)
+#define L1_CACHE_BYTES	16
+#else
+#define L1_CACHE_BYTES  32	/* A guess */
+#endif
 
-#define        SMP_CACHE_BYTES L1_CACHE_BYTES
-
-#endif /* __ASM_MIPS_CACHE_H */
+#endif /* _ASM_CACHE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/checksum.h linux/include/asm-mips/checksum.h
--- v2.3.47/linux/include/asm-mips/checksum.h	Tue Feb  1 01:35:44 2000
+++ linux/include/asm-mips/checksum.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: checksum.h,v 1.6 1998/09/16 13:30:51 ralf Exp $
+/* $Id: checksum.h,v 1.9 2000/02/18 22:06:19 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -6,8 +6,10 @@
  *
  * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
  */
-#ifndef __ASM_MIPS_CHECKSUM_H
-#define __ASM_MIPS_CHECKSUM_H
+#ifndef _ASM_CHECKSUM_H
+#define _ASM_CHECKSUM_H
+
+#include <asm/uaccess.h>
 
 /*
  * computes the checksum of a memory block at buff, length len,
@@ -36,9 +38,23 @@
 unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len,
                                          unsigned int sum, int *errp);
 
+/*
+ * Copy and checksum to user
+ */
 #define HAVE_CSUM_COPY_USER
-unsigned int csum_and_copy_to_user (const char *src, char *dst,
-                                    int len, int sum, int *err_ptr);
+extern inline unsigned int
+csum_and_copy_to_user (const char *src, char *dst,
+                       int len, int sum, int *err_ptr)
+{
+	sum = csum_partial(src, len, sum);
+
+	if (copy_to_user(dst, src, len)) {
+		*err_ptr = -EFAULT;
+		return -1;
+	}
+
+	return sum;
+}
 
 /*
  * the same as csum_partial, but copies from user space (but on MIPS
@@ -252,4 +268,4 @@
 	return csum_fold(sum);
 }
 
-#endif /* __ASM_MIPS_CHECKSUM_H */
+#endif /* _ASM_CHECKSUM_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/cpu.h linux/include/asm-mips/cpu.h
--- v2.3.47/linux/include/asm-mips/cpu.h	Fri May  8 00:13:26 1998
+++ linux/include/asm-mips/cpu.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: cpu.h,v 1.2 1998/05/01 01:35:49 ralf Exp $
+/* $Id: cpu.h,v 1.1.1.1 1997/06/01 03:17:12 ralf Exp $
  * cpu.h: Values of the PRId register used to match up
  *        various MIPS cpu types.
  *
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/current.h linux/include/asm-mips/current.h
--- v2.3.47/linux/include/asm-mips/current.h	Tue Oct 20 13:52:53 1998
+++ linux/include/asm-mips/current.h	Thu Feb 24 22:52:30 2000
@@ -1,13 +1,14 @@
-/* $Id: current.h,v 1.4 1998/07/20 17:52:19 ralf Exp $
+/* $Id: current.h,v 1.6 1999/09/28 22:27:17 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1998 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_CURRENT_H
-#define __ASM_MIPS_CURRENT_H
+#ifndef _ASM_CURRENT_H
+#define _ASM_CURRENT_H
 
 #ifdef _LANGUAGE_C
 
@@ -24,7 +25,7 @@
 #define _GET_CURRENT(reg)			\
 	lui	reg, %hi(kernelsp);		\
 	.set	push;				\
-	.set	noreorder;			\
+	.set	reorder;			\
 	lw	reg, %lo(kernelsp)(reg);	\
 	.set	pop;				\
 	ori	reg, 8191;			\
@@ -32,4 +33,4 @@
 
 #endif
 
-#endif /* __ASM_MIPS_CURRENT_H */
+#endif /* _ASM_CURRENT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/ddb5074.h linux/include/asm-mips/ddb5074.h
--- v2.3.47/linux/include/asm-mips/ddb5074.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/ddb5074.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,11 @@
+/*
+ *  include/asm-mips/ddb5074.h -- NEC DDB Vrc-5074 definitions
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Suprastructure Center Europe (SUPC-E), Brussels
+ */
+
+extern void ddb5074_led_hex(int hex);
+extern void ddb5074_led_d2(int on);
+extern void ddb5074_led_d3(int on);
+
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/dec/ioasic_ints.h linux/include/asm-mips/dec/ioasic_ints.h
--- v2.3.47/linux/include/asm-mips/dec/ioasic_ints.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/dec/ioasic_ints.h	Thu Feb 24 22:52:30 2000
@@ -68,9 +68,9 @@
 #define MAXINE_DTOP_RECV	0x00000001	/* DTI Recv-Available	*/
 
 /* kn03 aka 3max+ aka DS5000_2x0 */
-#define KN03_TC2		0x00004000
-#define KN03_TC1		0x00002000
-#define KN03_TC0		0x00001000
+#define KN03_TC2		0x00002000
+#define KN03_TC1		0x00001000
+#define KN03_TC0		0x00000800
 #define KN03_SCSI_FIFO		0x00000004	/* ??? Info from Mach	*/
 
 /*
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/dec/machtype.h linux/include/asm-mips/dec/machtype.h
--- v2.3.47/linux/include/asm-mips/dec/machtype.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/dec/machtype.h	Thu Feb 24 22:52:30 2000
@@ -1,12 +1,16 @@
 /*
- * Various machine type definitions
+ * Various machine type macros
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1998 Harald Koerfgen
+ * Copyright (c) 1998, 2000 Harald Koerfgen
  */
+
+#ifndef __ASM_DEC_MACHTYPE_H 
+#define __ASM_DEC_MACHTYPE_H 
+
 #include <asm/bootinfo.h>
 
 #define TURBOCHANNEL	(mips_machtype == MACH_DS5000_200 || \
@@ -18,3 +22,4 @@
 			 mips_machtype == MACH_DS5000_XX  || \
 			 mips_machtype == MACH_DS5000_2X0)
 
+#endif
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/delay.h linux/include/asm-mips/delay.h
--- v2.3.47/linux/include/asm-mips/delay.h	Mon Jul 19 13:12:47 1999
+++ linux/include/asm-mips/delay.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: delay.h,v 1.2 1999/01/04 16:09:20 ralf Exp $
+/* $Id: delay.h,v 1.3 1999/08/18 23:37:49 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -7,10 +7,11 @@
  * Copyright (C) 1994 by Waldorf Electronics
  * Copyright (C) 1995 - 1998 by Ralf Baechle
  */
-#ifndef __ASM_MIPS_DELAY_H
-#define __ASM_MIPS_DELAY_H
+#ifndef _ASM_DELAY_H
+#define _ASM_DELAY_H
 
-extern __inline__ void __delay(int loops)
+extern __inline__ void
+__delay(unsigned long loops)
 {
 	__asm__ __volatile__ (
 		".set\tnoreorder\n"
@@ -49,4 +50,4 @@
 
 #define udelay(usecs) __udelay((usecs),__udelay_val)
 
-#endif /* __ASM_MIPS_DELAY_H */
+#endif /* _ASM_DELAY_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/div64.h linux/include/asm-mips/div64.h
--- v2.3.47/linux/include/asm-mips/div64.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/div64.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,20 @@
+/* $Id: div64.h,v 1.1 2000/01/29 01:42:28 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_DIV64_H
+#define _ASM_DIV64_H
+
+/*
+ * Hey, we're already 64-bit, no
+ * need to play games..
+ */
+#define do_div(n,base) ({ \
+	int __res; \
+	__res = ((unsigned long) n) % (unsigned) base; \
+	n = ((unsigned long) n) / (unsigned) base; \
+	__res; })
+
+#endif /* _ASM_DIV64_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/dma.h linux/include/asm-mips/dma.h
--- v2.3.47/linux/include/asm-mips/dma.h	Fri Sep 10 23:57:36 1999
+++ linux/include/asm-mips/dma.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: dma.h,v 1.2 1998/10/19 21:29:10 ralf Exp $
+/* $Id: dma.h,v 1.7 2000/01/29 01:42:28 ralf Exp $
  * linux/include/asm/dma.h: Defines for using and allocating dma channels.
  * Written by Hennus Bergman, 1992.
  * High DMA channel support & info by Hannu Savolainen
@@ -83,11 +83,7 @@
  * Deskstations or Acer PICA but not the much more versatile DMA logic used
  * for the local devices on Acer PICA or Magnums.
  */
-#ifndef CONFIG_SGI
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + 0x01000000)
-#else
-#define MAX_DMA_ADDRESS		(~0UL)
-#endif
 
 /* 8237 DMA controllers */
 #define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
@@ -298,5 +294,11 @@
 /* These are in kernel/dma.c: */
 extern int request_dma(unsigned int dmanr, const char * device_id);	/* reserve a DMA channel */
 extern void free_dma(unsigned int dmanr);	/* release it again */
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy 	(0)
+#endif
 
 #endif /* __ASM_MIPS_DMA_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/ds1286.h linux/include/asm-mips/ds1286.h
--- v2.3.47/linux/include/asm-mips/ds1286.h	Tue Oct 20 13:52:53 1998
+++ linux/include/asm-mips/ds1286.h	Thu Feb 24 22:52:30 2000
@@ -1,16 +1,18 @@
-/* $Id: ds1286.h,v 1.1 1998/07/09 20:01:30 ralf Exp $
+/* $Id: ds1286.h,v 1.2 1999/08/19 22:56:33 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
  * mc146818rtc.h - register definitions for the Real-Time-Clock / CMOS RAM
  * Copyright Torsten Duwe <duwe@informatik.uni-erlangen.de> 1993
  * derived from Data Sheet, Copyright Motorola 1984 (!).
  * It was written to be part of the Linux operating system.
+ *
+ * Copyright (C) 1998, 1999 Ralf Baechle
  */
-/* permission is hereby granted to copy, modify and redistribute this code
- * in terms of the GNU Library General Public License, Version 2 or later,
- * at your option.
- */
-#ifndef _MC146818RTC_H
-#define _MC146818RTC_H
+#ifndef _ASM_DS1286_h
+#define _ASM_DS1286_h
 
 #include <asm/mc146818rtc.h>
 
@@ -66,4 +68,4 @@
 #define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
 #endif
 
-#endif /* _MC146818RTC_H */
+#endif /* _ASM_DS1286_h */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/elf.h linux/include/asm-mips/elf.h
--- v2.3.47/linux/include/asm-mips/elf.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/elf.h	Thu Feb 24 22:52:30 2000
@@ -1,5 +1,5 @@
 /*
- * $Id: elf.h,v 1.10 1998/05/01 01:35:51 ralf Exp $
+ * $Id: elf.h,v 1.7 1999/08/20 21:59:08 ralf Exp $
  */
 #ifndef __ASM_MIPS_ELF_H
 #define __ASM_MIPS_ELF_H
@@ -21,7 +21,6 @@
 
 /*
  * These are used to set parameters in the core dumps.
- * FIXME(eric) I don't know what the correct endianness to use is.
  */
 #define ELF_CLASS	ELFCLASS32
 #ifdef __MIPSEB__
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/errno.h linux/include/asm-mips/errno.h
--- v2.3.47/linux/include/asm-mips/errno.h	Fri May  8 00:13:26 1998
+++ linux/include/asm-mips/errno.h	Thu Feb 24 22:52:30 2000
@@ -5,10 +5,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995 by Ralf Baechle
+ * Copyright (C) 1995, 1999 by Ralf Baechle
  */
-#ifndef __ASM_MIPS_ERRNO_H
-#define __ASM_MIPS_ERRNO_H
+#ifndef _ASM_ERRNO_H
+#define _ASM_ERRNO_H
 
 /*
  * These error numbers are intended to be MIPS ABI compatible
@@ -144,19 +144,13 @@
 #define ENOMEDIUM	159	/* No medium found */
 #define EMEDIUMTYPE	160	/* Wrong medium type */
 
-/*
- * IRIX 5 error number start from 1000.
- * Stupid enough; ECANCELED gets redefined with a different value ...
-#define ECANCELED       1000
- */
+#define EDQUOT		1133	/* Quota exceeded */
 
-/*
- * IRIX 4 compatibility error numbers.
- */
-#define	EDQUOT		1133	/* Quota exceeded */
-#define ENFSREMOTE	1134	/* ??? */
+#ifdef __KERNEL__
 
 /* The biggest error number defined here or in <linux/errno.h>. */
-#define EMAXERRNO	1134
+#define EMAXERRNO	1133
+
+#endif /* __KERNEL__ */
 
-#endif /* __ASM_MIPS_ERRNO_H */
+#endif /* _ASM_ERRNO_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/fcntl.h linux/include/asm-mips/fcntl.h
--- v2.3.47/linux/include/asm-mips/fcntl.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/fcntl.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: fcntl.h,v 1.3 1998/08/29 20:41:02 ralf Exp $
+/* $Id: fcntl.h,v 1.5 1999/01/04 16:09:21 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/floppy.h linux/include/asm-mips/floppy.h
--- v2.3.47/linux/include/asm-mips/floppy.h	Mon Oct 26 09:57:56 1998
+++ linux/include/asm-mips/floppy.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: floppy.h,v 1.4 1998/05/07 18:38:41 ralf Exp $
+/* $Id: floppy.h,v 1.7 1999/08/18 23:37:49 ralf Exp $
  *
  * Architecture specific parts of the Floppy driver
  *
@@ -8,13 +8,12 @@
  *
  * Copyright (C) 1995, 1996, 1997, 1998 Ralf Baechle
  */
-#ifndef __ASM_MIPS_FLOPPY_H
-#define __ASM_MIPS_FLOPPY_H
+#ifndef _ASM_FLOPPY_H
+#define _ASM_FLOPPY_H
 
 #include <asm/bootinfo.h>
 #include <asm/jazz.h>
 #include <asm/jazzdma.h>
-#include <asm/mipsconfig.h>
 
 struct fd_ops {
 	unsigned char (*fd_inb)(unsigned int port);
@@ -102,4 +101,4 @@
  */
 #define CROSS_64KB(a,s) ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)
 
-#endif /* __ASM_MIPS_FLOPPY_H */
+#endif /* _ASM_FLOPPY_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/fp.h linux/include/asm-mips/fp.h
--- v2.3.47/linux/include/asm-mips/fp.h	Tue Oct 20 13:52:53 1998
+++ linux/include/asm-mips/fp.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: fp.h,v 1.1 1998/07/16 17:01:54 ralf Exp $
+/* $Id: fp.h,v 1.2 1999/07/26 19:42:43 harald Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -12,19 +12,23 @@
  */
 #define enable_cp1()							\
 	__asm__ __volatile__(						\
+		".set\tpush\n\t"					\
 		".set\tnoat\n\t"					\
+		".set\treorder\n\t"					\
 		"mfc0\t$1,$12\n\t"					\
 		"or\t$1,%0\n\t"						\
 		"mtc0\t$1,$12\n\t"					\
-		".set\tat"						\
+		".set\tpop"						\
 		: : "r" (ST0_CU1));
 
 #define disable_cp1()							\
 	__asm__ __volatile__(						\
+		".set\tpush\n\t"					\
 		".set\tnoat\n\t"					\
+		".set\treorder\n\t"					\
 		"mfc0\t$1,$12\n\t"					\
 		"or\t$1,%0\n\t"						\
 		"xor\t$1,%0\n\t"					\
 		"mtc0\t$1,$12\n\t"					\
-		".set\tat"						\
+		".set\tpop"						\
 		: : "r" (ST0_CU1));
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/gdb-stub.h linux/include/asm-mips/gdb-stub.h
--- v2.3.47/linux/include/asm-mips/gdb-stub.h	Tue Oct 20 13:52:53 1998
+++ linux/include/asm-mips/gdb-stub.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: gdb-stub.h,v 1.3 1998/07/20 17:52:19 ralf Exp $
+/* $Id: gdb-stub.h,v 1.3 1998/08/25 09:21:55 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/gfx.h linux/include/asm-mips/gfx.h
--- v2.3.47/linux/include/asm-mips/gfx.h	Tue Dec 16 12:46:06 1997
+++ linux/include/asm-mips/gfx.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,9 @@
-/*
+/* $Id: gfx.h,v 1.5 1999/08/19 22:56:33 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
  * This is the user-visible SGI GFX interface.
  *
  * This must be used verbatim into the GNU libc.  It does not include
@@ -6,6 +11,8 @@
  *
  * miguel@nuclecu.unam.mx
  */
+#ifndef _ASM_GFX_H
+#define _ASM_GFX_H
 
 /* The iocls, yes, they do not make sense, but such is life */
 #define GFX_BASE             100
@@ -45,3 +52,5 @@
 extern void *vmalloc_uncached (unsigned long size);
 extern int vmap_page_range (unsigned long from, unsigned long size, unsigned long vaddr);
 #endif
+
+#endif /* _ASM_GFX_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/hardirq.h linux/include/asm-mips/hardirq.h
--- v2.3.47/linux/include/asm-mips/hardirq.h	Tue Sep  7 12:14:07 1999
+++ linux/include/asm-mips/hardirq.h	Thu Feb 24 22:52:30 2000
@@ -1,13 +1,14 @@
-/* $Id: hardirq.h,v 1.5 1998/08/29 21:20:21 ralf Exp $
+/* $Id: hardirq.h,v 1.7 2000/02/23 00:41:38 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997, 1998 by Ralf Baechle
+ * Copyright (C) 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_HARDIRQ_H
-#define __ASM_MIPS_HARDIRQ_H
+#ifndef _ASM_HARDIRQ_H
+#define _ASM_HARDIRQ_H
 
 #include <linux/threads.h>
 
@@ -19,14 +20,15 @@
  */
 #define in_interrupt() ({ int __cpu = smp_processor_id(); \
 	(local_irq_count[__cpu] + local_bh_count[__cpu] != 0); })
+#define in_irq() (local_irq_count[smp_processor_id()] != 0)
 
 #ifndef __SMP__
 
 #define hardirq_trylock(cpu)	(local_irq_count[cpu] == 0)
 #define hardirq_endlock(cpu)	do { } while (0)
 
-#define hardirq_enter(cpu)	(local_irq_count[cpu]++)
-#define hardirq_exit(cpu)	(local_irq_count[cpu]--)
+#define irq_enter(cpu)		(local_irq_count[cpu]++)
+#define irq_exit(cpu)		(local_irq_count[cpu]--)
 
 #define synchronize_irq()	barrier();
 
@@ -35,4 +37,4 @@
 #error No habla MIPS SMP
 
 #endif /* __SMP__ */
-#endif /* __ASM_MIPS_HARDIRQ_H */
+#endif /* _ASM_HARDIRQ_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/hdreg.h linux/include/asm-mips/hdreg.h
--- v2.3.47/linux/include/asm-mips/hdreg.h	Thu May 13 11:00:09 1999
+++ linux/include/asm-mips/hdreg.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: hdreg.h,v 1.4 1998/05/08 21:05:26 davem Exp $
+/* $Id: hdreg.h,v 1.1 1999/06/17 14:09:00 ralf Exp $
  *
  *  linux/include/asm-mips/hdreg.h
  *
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/highmem.h linux/include/asm-mips/highmem.h
--- v2.3.47/linux/include/asm-mips/highmem.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/highmem.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,28 @@
+/* $Id: highmem.h,v 1.2 2000/01/29 01:42:28 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 by Ralf Baechle
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#include <linux/init.h>
+#include <asm/pgtable.h>
+
+/* declarations for highmem.c */
+extern unsigned long highstart_pfn, highend_pfn;
+
+extern pte_t *kmap_pte;
+extern pgprot_t kmap_prot;
+
+#define kmap_init()			do { } while(0)
+#define kmap(page)			page_address(page)
+#define kunmap(page)			do { } while(0)
+#define kmap_atomic(page, type)		page_address(page)
+#define kunmap_atomic(page, type)	do { } while(0)
+
+#endif /* _ASM_HIGHMEM_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/ide.h linux/include/asm-mips/ide.h
--- v2.3.47/linux/include/asm-mips/ide.h	Fri Aug  6 11:16:54 1999
+++ linux/include/asm-mips/ide.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: ide.h,v 1.4 1998/05/08 21:05:26 davem Exp $
+/* $Id: ide.h,v 1.6 1999/10/09 00:01:42 ralf Exp $
  *
  *  linux/include/asm-mips/ide.h
  *
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/init.h linux/include/asm-mips/init.h
--- v2.3.47/linux/include/asm-mips/init.h	Tue Aug 31 17:29:14 1999
+++ linux/include/asm-mips/init.h	Thu Feb 24 22:52:30 2000
@@ -1,27 +1 @@
-/* $Id: init.h,v 1.3 1999/02/15 02:22:10 ralf Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright 1998, 1999 Ralf Baechle
- */
-#ifndef __MIPS_INIT_H
-#define __MIPS_INIT_H
-
-#define __init __attribute__ ((__section__ (".text.init")))
-#define __initdata __attribute__ ((__section__ (".data.init")))
-
-#if __GNUC__ >= 2 && __GNUC_MINOR__ >= 8
-#define __initlocaldata  __initdata
-#else
-#define __initlocaldata
-#endif
-
-/* For assembly routines */
-#define __INIT		.section	.text.init,"ax"
-#define __FINIT		.previous
-#define __INITDATA	.section	.data.init,"a"
-#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
-
-#endif /* __MIPS_INIT_H */
+#error "<asm/init.h> should never be used - use <linux/init.h> instead"
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/inventory.h linux/include/asm-mips/inventory.h
--- v2.3.47/linux/include/asm-mips/inventory.h	Fri May  8 00:13:26 1998
+++ linux/include/asm-mips/inventory.h	Thu Feb 24 22:52:30 2000
@@ -1,5 +1,5 @@
 /*
- * $Id: inventory.h,v 1.2 1998/05/01 01:35:54 ralf Exp $
+ * $Id: inventory.h,v 1.2 1997/12/06 23:55:49 ralf Exp $
  */
 #ifndef __ASM_MIPS_INVENTORY_H
 #define __ASM_MIPS_INVENTORY_H
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/io.h linux/include/asm-mips/io.h
--- v2.3.47/linux/include/asm-mips/io.h	Tue Dec  7 09:32:50 1999
+++ linux/include/asm-mips/io.h	Thu Feb 24 22:52:30 2000
@@ -1,12 +1,23 @@
-#ifndef __ASM_MIPS_IO_H
-#define __ASM_MIPS_IO_H
+/* $Id: io.h,v 1.13 2000/02/24 00:13:19 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995 Waldorf GmbH
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
 
 /*
  * Slowdown I/O port space accesses for antique hardware.
  */
 #undef CONF_SLOWDOWN_IO
 
-#include <asm/mipsconfig.h>
+#include <linux/config.h>
+
 #include <asm/addrspace.h>
 
 /*
@@ -142,25 +153,53 @@
  * 24-31 on SNI.
  * XXX more SNI hacks.
  */
-#define readb(addr) (*(volatile unsigned char *) (0xa0000000 + (unsigned long)(addr)))
-#define readw(addr) (*(volatile unsigned short *) (0xa0000000 + (unsigned long)(addr)))
-#define readl(addr) (*(volatile unsigned int *) (0xa0000000 + (unsigned long)(addr)))
-
-#define writeb(b,addr) (*(volatile unsigned char *) (0xa0000000 + (unsigned long)(addr)) = (b))
-#define writew(b,addr) (*(volatile unsigned short *) (0xa0000000 + (unsigned long)(addr)) = (b))
-#define writel(b,addr) (*(volatile unsigned int *) (0xa0000000 + (unsigned long)(addr)) = (b))
-
-#define memset_io(a,b,c)	memset((void *)(0xa0000000 + (unsigned long)a),(b),(c))
-#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(0xa0000000 + (unsigned long)(b)),(c))
-#define memcpy_toio(a,b,c)	memcpy((void *)(0xa0000000 + (unsigned long)(a)),(b),(c))
+#define readb(addr) (*(volatile unsigned char *)(addr))
+#define readw(addr) (*(volatile unsigned short *)(addr))
+#define readl(addr) (*(volatile unsigned int *)(addr))
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+
+#define writeb(b,addr) (*(volatile unsigned char *)(addr)) = (b)
+#define writew(b,addr) (*(volatile unsigned short *)(addr)) = (b)
+#define writel(b,addr) (*(volatile unsigned int *)(addr)) = (b)
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+
+#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
 
 /* END SNI HACKS ... */
 
 /*
+ * ISA space is 'always mapped' on currently supported MIPS systems, no need
+ * to explicitly ioremap() it. The fact that the ISA IO space is mapped
+ * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
+ * are physical addresses. The following constant pointer can be
+ * used as the IO-area pointer (it can be iounmapped as well, so the
+ * analogy with PCI is quite large):
+ */
+#define __ISA_IO_base ((char *)(PAGE_OFFSET))
+
+#define isa_readb(a) readb(a)
+#define isa_readw(a) readw(a)
+#define isa_readl(a) readl(a)
+#define isa_writeb(b,a) writeb(b,a)
+#define isa_writew(w,a) writew(w,a)
+#define isa_writel(l,a) writel(l,a)
+
+#define isa_memset_io(a,b,c)     memset_io((a),(b),(c))
+#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),(b),(c))
+#define isa_memcpy_toio(a,b,c)   memcpy_toio((a),(b),(c))
+
+/*
  * We don't have csum_partial_copy_fromio() yet, so we cheat here and
  * just copy it. The net code will then do the checksum later.
  */
-#define eth_io_copy_and_sum(skb,src,len,unused)	memcpy_fromio((skb)->data,(src),(len))
+#define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len))
+#define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(b),(c),(d))
 
 static inline int check_signature(unsigned long io_addr,
                                   const unsigned char *signature, int length)
@@ -177,6 +216,7 @@
 out:
 	return retval;
 }
+#define isa_check_signature(io, s, l) check_signature(i,s,l)
 
 /*
  * Talk about misusing macros..
@@ -395,8 +435,12 @@
  *    be discarded.  This operation is necessary before dma operations
  *    to the memory.
  */
-extern void (*dma_cache_wback_inv)(unsigned long start, unsigned long size);
-extern void (*dma_cache_wback)(unsigned long start, unsigned long size);
-extern void (*dma_cache_inv)(unsigned long start, unsigned long size);
+extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
+extern void (*_dma_cache_wback)(unsigned long start, unsigned long size);
+extern void (*_dma_cache_inv)(unsigned long start, unsigned long size);
+
+#define dma_cache_wback_inv(start,size)	_dma_cache_wback_inv(start,size)
+#define dma_cache_wback(start,size)	_dma_cache_wback(start,size)
+#define dma_cache_inv(start,size)	_dma_cache_inv(start,size)
 
-#endif /* __ASM_MIPS_IO_H */
+#endif /* _ASM_IO_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/ioctls.h linux/include/asm-mips/ioctls.h
--- v2.3.47/linux/include/asm-mips/ioctls.h	Tue Oct 20 13:52:53 1998
+++ linux/include/asm-mips/ioctls.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: ioctls.h,v 1.5 1998/08/19 21:58:11 ralf Exp $
+/* $Id: ioctls.h,v 1.8 1998/08/25 09:21:56 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/ipcbuf.h linux/include/asm-mips/ipcbuf.h
--- v2.3.47/linux/include/asm-mips/ipcbuf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/ipcbuf.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,28 @@
+#ifndef _ASM_IPCBUF_H
+#define _ASM_IPCBUF_H
+
+/* 
+ * The ipc64_perm structure for alpha architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit seq
+ * - 2 miscellaneous 64-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t	key;
+	__kernel_uid_t	uid;
+	__kernel_gid_t	gid;
+	__kernel_uid_t	cuid;
+	__kernel_gid_t	cgid;
+	__kernel_mode_t	mode; 
+	unsigned short	seq;
+	unsigned short	__pad1;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+};
+
+#endif /* _ASM_IPCBUF_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/irq.h linux/include/asm-mips/irq.h
--- v2.3.47/linux/include/asm-mips/irq.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/irq.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: irq.h,v 1.4 1998/05/28 03:18:13 ralf Exp $
+/* $Id: irq.h,v 1.7 2000/02/23 00:41:38 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -7,8 +7,8 @@
  * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
  * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
  */
-#ifndef __ASM_MIPS_IRQ_H
-#define __ASM_MIPS_IRQ_H
+#ifndef _ASM_IRQ_H
+#define _ASM_IRQ_H
 
 #define NR_IRQS 64
 
@@ -19,9 +19,10 @@
 struct irqaction;
 extern int i8259_setup_irq(int irq, struct irqaction * new);
 extern void disable_irq(unsigned int);
+#define disable_irq_nosync	disable_irq
 extern void enable_irq(unsigned int);
 
 /* Machine specific interrupt initialization  */
 extern void (*irq_setup)(void);
 
-#endif /* __ASM_MIPS_IRQ_H */
+#endif /* _ASM_IRQ_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/isadep.h linux/include/asm-mips/isadep.h
--- v2.3.47/linux/include/asm-mips/isadep.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/isadep.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,37 @@
+/*
+ * Various ISA level dependant constants.
+ * Most of the following constants reflect the different layout
+ * of Coprocessor 0 registers.
+ *
+ * Copyright (c) 1998 Harald Koerfgen
+ *
+ * $Id: isadep.h,v 1.2 1999/08/13 17:07:27 harald Exp $
+ */
+#include <linux/config.h>
+
+#ifndef __ASM_MIPS_ISADEP_H
+#define __ASM_MIPS_ISADEP_H
+
+#if defined(CONFIG_CPU_R3000)
+/*
+ * R2000 or R3000
+ */
+
+/*
+ * kernel or user mode? (CP0_STATUS)
+ */
+#define KU_MASK 0x08
+#define	KU_USER 0x08
+#define KU_KERN 0x00
+
+#else
+/*
+ * kernel or user mode?
+ */
+#define KU_MASK 0x18
+#define	KU_USER 0x10
+#define KU_KERN 0x00
+
+#endif
+
+#endif /* __ASM_MIPS_ISADEP_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/jazz.h linux/include/asm-mips/jazz.h
--- v2.3.47/linux/include/asm-mips/jazz.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/jazz.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: jazz.h,v 1.8 1998/09/16 22:52:41 ralf Exp $
+/* $Id: jazz.h,v 1.10 1998/10/18 13:16:02 tsbogend Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/jazzdma.h linux/include/asm-mips/jazzdma.h
--- v2.3.47/linux/include/asm-mips/jazzdma.h	Fri May  8 00:13:26 1998
+++ linux/include/asm-mips/jazzdma.h	Thu Feb 24 22:52:30 2000
@@ -1,7 +1,7 @@
 /*
  * Helpfile for jazzdma.c -- Mips Jazz R4030 DMA controller support
  *
- * $Id: jazzdma.h,v 1.6 1998/05/01 01:35:57 ralf Exp $
+ * $Id: jazzdma.h,v 1.6 1998/03/04 09:51:22 ralf Exp $
  */
 #ifndef __ASM_MIPS_JAZZDMA_H
 #define __ASM_MIPS_JAZZDMA_H
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/keyboard.h linux/include/asm-mips/keyboard.h
--- v2.3.47/linux/include/asm-mips/keyboard.h	Wed Jun 30 11:24:55 1999
+++ linux/include/asm-mips/keyboard.h	Thu Feb 24 22:52:30 2000
@@ -1,17 +1,17 @@
-/*
- * CPU specific parts of the keyboard driver
+/* $Id: keyboard.h,v 1.14 1999/08/19 22:56:33 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * $Id: keyboard.h,v 1.12 1998/09/16 22:52:41 ralf Exp $
+ * Copyright (C) 1994 - 1999 Ralf Baechle
  */
-#ifndef __ASM_MIPS_KEYBOARD_H
-#define __ASM_MIPS_KEYBOARD_H
+#ifndef _ASM_KEYBOARD_H
+#define _ASM_KEYBOARD_H
 
 #ifdef __KERNEL__
 
+#include <linux/config.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <asm/bootinfo.h>
@@ -72,4 +72,4 @@
 
 #endif /* __KERNEL */
 
-#endif /* __ASM_MIPS_KEYBOARD_H */
+#endif /* _ASM_KEYBOARD_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/linux_logo.h linux/include/asm-mips/linux_logo.h
--- v2.3.47/linux/include/asm-mips/linux_logo.h	Tue Aug  4 16:06:57 1998
+++ linux/include/asm-mips/linux_logo.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,5 @@
-/* $Id: linux_logo.h,v 1.1 1998/07/30 16:30:31 jj Exp $
+/* $Id: linux_logo.h,v 1.4 1999/01/04 16:09:23 ralf Exp $
+ *
  * include/asm-mips/linux_logo.h: This is a linux logo
  *                                to be displayed on boot.
  *
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/mc146818rtc.h linux/include/asm-mips/mc146818rtc.h
--- v2.3.47/linux/include/asm-mips/mc146818rtc.h	Tue Oct 20 13:52:53 1998
+++ linux/include/asm-mips/mc146818rtc.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: mc146818rtc.h,v 1.3 1998/06/25 20:19:26 ralf Exp $
+/* $Id: mc146818rtc.h,v 1.3 1999/08/19 22:56:33 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -8,8 +8,8 @@
  *
  * Copyright (C) 1996, 1997, 1998 Ralf Baechle
  */
-#ifndef __ASM_MIPS_MC146818RTC_H
-#define __ASM_MIPS_MC146818RTC_H
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
 
 #include <asm/io.h>
 
@@ -43,4 +43,4 @@
 
 extern struct rtc_ops *rtc_ops;
 
-#endif /* __ASM_MIPS_MC146818RTC_H */
+#endif /* _ASM_MC146818RTC_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/md.h linux/include/asm-mips/md.h
--- v2.3.47/linux/include/asm-mips/md.h	Tue Oct 20 13:52:53 1998
+++ linux/include/asm-mips/md.h	Wed Dec 31 16:00:00 1969
@@ -1,14 +0,0 @@
-/* $Id: md.h,v 1.1 1998/08/17 10:20:14 ralf Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#ifndef __ASM_MD_H
-#define __ASM_MD_H
-
-/* #define HAVE_ARCH_XORBLOCK */
-
-#define MD_XORBLOCK_ALIGNMENT	sizeof(long)
-
-#endif /* __ASM_MD_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/mipsconfig.h linux/include/asm-mips/mipsconfig.h
--- v2.3.47/linux/include/asm-mips/mipsconfig.h	Tue Dec 16 12:46:10 1997
+++ linux/include/asm-mips/mipsconfig.h	Wed Dec 31 16:00:00 1969
@@ -1,19 +0,0 @@
-/*
- * include/asm-mips/mipsconfig.h
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1994, 1995, 1996, 1997 by Ralf Baechle
- */
-#ifndef __ASM_MIPS_MIPSCONFIG_H
-#define __ASM_MIPS_MIPSCONFIG_H
-
-/* Pgdir is 1 page mapped at 0xff800000. */
-#define TLBMAP			0xff800000
-
-/* The virtual address where we'll map the pgdir. */
-#define TLB_ROOT		0xff000000
-
-#endif /* __ASM_MIPS_MIPSCONFIG_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/mipsregs.h linux/include/asm-mips/mipsregs.h
--- v2.3.47/linux/include/asm-mips/mipsregs.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/mipsregs.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: mipsregs.h,v 1.6 1998/08/17 11:27:08 ralf Exp $
+/* $Id: mipsregs.h,v 1.6 1999/07/26 19:42:43 harald Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -103,7 +103,10 @@
 #define read_32bit_cp0_register(source)                         \
 ({ int __res;                                                   \
         __asm__ __volatile__(                                   \
-        "mfc0\t%0,"STR(source)                                  \
+	".set\tpush\n\t"					\
+	".set\treorder\n\t"					\
+        "mfc0\t%0,"STR(source)"\n\t"                            \
+	".set\tpop"						\
         : "=r" (__res));                                        \
         __res;})
 
@@ -121,7 +124,8 @@
 
 #define write_32bit_cp0_register(register,value)                \
         __asm__ __volatile__(                                   \
-        "mtc0\t%0,"STR(register)                                \
+        "mtc0\t%0,"STR(register)"\n\t"				\
+	"nop"							\
         : : "r" (value));
 
 #define write_64bit_cp0_register(register,value)                \
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/mman.h linux/include/asm-mips/mman.h
--- v2.3.47/linux/include/asm-mips/mman.h	Thu Jun 26 12:33:40 1997
+++ linux/include/asm-mips/mman.h	Thu Feb 24 22:52:30 2000
@@ -46,9 +46,9 @@
 /*
  * Flags for msync
  */
-#define MS_SYNC		0		/* synchronous memory sync */
-#define MS_ASYNC	1		/* sync memory asynchronously */
-#define MS_INVALIDATE	2		/* invalidate mappings & caches */
+#define MS_ASYNC	0x0001		/* sync memory asynchronously */
+#define MS_INVALIDATE	0x0002		/* invalidate mappings & caches */
+#define MS_SYNC		0x0004		/* synchronous memory sync */
 
 /*
  * Flags for mlockall
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/mmu_context.h linux/include/asm-mips/mmu_context.h
--- v2.3.47/linux/include/asm-mips/mmu_context.h	Thu Feb 10 17:11:20 2000
+++ linux/include/asm-mips/mmu_context.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: mmu_context.h,v 1.3 1998/10/16 19:22:54 ralf Exp $
+/* $Id: mmu_context.h,v 1.8 2000/02/23 00:41:38 ralf Exp $
  *
  * Switch a MMU context.
  *
@@ -6,61 +6,46 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_MMU_CONTEXT_H
-#define __ASM_MIPS_MMU_CONTEXT_H
+#ifndef _ASM_MMU_CONTEXT_H
+#define _ASM_MMU_CONTEXT_H
 
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
-{
-}
+#include <linux/config.h>
+#include <asm/pgalloc.h>
 
 /* Fuck.  The f-word is here so you can grep for it :-)  */
 extern unsigned long asid_cache;
+extern pgd_t *current_pgd;
+
+#if defined(CONFIG_CPU_R3000)
+
+#define ASID_INC	0x40
+#define ASID_MASK	0xfc0
 
-/* I patch, therefore I am ...  */
-#define ASID_INC(asid)						\
- ({ unsigned long __asid = asid;				\
-   __asm__("1:\taddiu\t%0,0\t\t\t\t# patched\n\t"		\
-           ".section\t__asid_inc,\"a\"\n\t"			\
-           ".word\t1b\n\t"					\
-           ".previous"						\
-           :"=r" (__asid)					\
-           :"0" (__asid));					\
-   __asid; })
-#define ASID_MASK(asid)						\
- ({ unsigned long __asid = asid;				\
-   __asm__("1:\tandi\t%0,%1,0\t\t\t# patched\n\t"			\
-           ".section\t__asid_mask,\"a\"\n\t"			\
-           ".word\t1b\n\t"					\
-           ".previous"						\
-           :"=r" (__asid)					\
-           :"r" (__asid));					\
-   __asid; })
-#define ASID_VERSION_MASK					\
- ({ unsigned long __asid;					\
-   __asm__("1:\tli\t%0,0\t\t\t\t# patched\n\t"			\
-           ".section\t__asid_version_mask,\"a\"\n\t"		\
-           ".word\t1b\n\t"					\
-           ".previous"						\
-           :"=r" (__asid));					\
-   __asid; })
-#define ASID_FIRST_VERSION					\
- ({ unsigned long __asid = asid;				\
-   __asm__("1:\tli\t%0,0\t\t\t\t# patched\n\t"			\
-           ".section\t__asid_first_version,\"a\"\n\t"		\
-           ".word\t1b\n\t"					\
-           ".previous"						\
-           :"=r" (__asid));					\
-   __asid; })
+#else /* FIXME: not correct for R6000, R8000 */
+
+#define ASID_INC	0x1
+#define ASID_MASK	0xff
+
+#endif
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+{
+}
 
-#define ASID_FIRST_VERSION_R3000 0x1000
-#define ASID_FIRST_VERSION_R4000 0x100
+/*
+ *  All unused by hardware upper bits will be considered
+ *  as a software asid extension.
+ */
+#define ASID_VERSION_MASK  ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
+#define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)
 
 extern inline void
 get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
 {
-	if (!ASID_MASK((asid = ASID_INC(asid)))) {
+	if (! ((asid += ASID_INC) & ASID_MASK) ) {
 		flush_tlb_all(); /* start new asid cycle */
 		if (!asid)      /* fix version if needed */
 			asid = ASID_FIRST_VERSION;
@@ -68,71 +53,50 @@
 	mm->context = asid_cache = asid;
 }
 
-extern inline void
-get_mmu_context(struct task_struct *p)
-{
-	struct mm_struct *mm = p->mm;
-
-	if (mm) {
-		unsigned long asid = asid_cache;
-		/* Check if our ASID is of an older version and thus invalid */
-		if ((mm->context ^ asid) & ASID_VERSION_MASK)
-			get_new_mmu_context(mm, asid);
-	}
-}
-
 /*
  * Initialize the context related info for a new mm_struct
  * instance.
  */
-extern inline void init_new_context(struct mm_struct *mm)
+extern inline void
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 {
 	mm->context = 0;
 }
 
+extern inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+                             struct task_struct *tsk, unsigned cpu)
+{
+	unsigned long asid = asid_cache;
+
+	/* Check if our ASID is of an older version and thus invalid */
+	if ((next->context ^ asid) & ASID_VERSION_MASK)
+		get_new_mmu_context(next, asid);
+
+	current_pgd = next->pgd;
+	set_entryhi(next->context);
+}
+
 /*
  * Destroy context related info for an mm_struct that is about
  * to be put to rest.
  */
 extern inline void destroy_context(struct mm_struct *mm)
 {
-	mm->context = 0;
+	/* Nothing to do.  */
 }
 
 /*
  * After we have set current->mm to a new value, this activates
  * the context for the new mm so we see the new mappings.
  */
-extern inline void activate_context(struct task_struct *tsk)
-{
-	get_mmu_context(tsk);
-	set_entryhi(tsk->mm->context);
-}
-
-extern void __asid_setup(unsigned int inc, unsigned int mask,
-                         unsigned int version_mask, unsigned int first_version);
-
-extern inline void r3000_asid_setup(void)
-{
-	__asid_setup(0x40, 0xfc0, 0xf000, ASID_FIRST_VERSION_R3000);
-}
-
-extern inline void r6000_asid_setup(void)
-{
-	panic("r6000_asid_setup: implement me");	/* No idea ...  */
-}
-
-extern inline void tfp_asid_setup(void)
+extern inline void
+activate_mm(struct mm_struct *prev, struct mm_struct *next)
 {
-	panic("tfp_asid_setup: implement me");	/* No idea ...  */
-}
+	/* Unconditionally get a new ASID.  */
+	get_new_mmu_context(next, asid_cache);
 
-extern inline void r4xx0_asid_setup(void)
-{
-	__asid_setup(1, 0xff, 0xff00, ASID_FIRST_VERSION_R4000);
+	current_pgd = next->pgd;
+	set_entryhi(next->context);
 }
 
-/* R10000 has the same ASID mechanism as the R4000.  */
-#define andes_asid_setup r4xx0_asid_setup
-
-#endif /* __ASM_MIPS_MMU_CONTEXT_H */
+#endif /* _ASM_MMU_CONTEXT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/msgbuf.h linux/include/asm-mips/msgbuf.h
--- v2.3.47/linux/include/asm-mips/msgbuf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/msgbuf.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,27 @@
+#ifndef _ASM_MSGBUF_H
+#define _ASM_MSGBUF_H
+
+/* 
+ * The msqid64_ds structure for alpha architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 2 miscellaneous 64-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused1;
+	unsigned long  __unused2;
+};
+
+#endif /* _ASM_MSGBUF_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/namei.h linux/include/asm-mips/namei.h
--- v2.3.47/linux/include/asm-mips/namei.h	Wed Jun  9 16:24:15 1999
+++ linux/include/asm-mips/namei.h	Thu Feb 24 22:52:30 2000
@@ -3,7 +3,7 @@
  *
  * Included from linux/fs/namei.c
  *
- * $Id: namei.h,v 1.10 1998/10/28 08:13:24 jj Exp $
+ * $Id: namei.h,v 1.7 1999/06/17 13:30:37 ralf Exp $
  */
 #ifndef __ASM_MIPS_NAMEI_H
 #define __ASM_MIPS_NAMEI_H
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/newport.h linux/include/asm-mips/newport.h
--- v2.3.47/linux/include/asm-mips/newport.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/newport.h	Wed Dec 31 16:00:00 1969
@@ -1,593 +0,0 @@
-/* $Id: newport.h,v 1.1 1998/08/19 21:58:12 ralf Exp $
- *
- * newport.h: Defines and register layout for NEWPORT graphics
- *            hardware.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-
-#ifndef _SGI_NEWPORT_H
-#define _SGI_NEWPORT_H
-
-
-typedef volatile unsigned long npireg_t;
-
-union npfloat {
-	volatile float f;
-	npireg_t       i;
-};
-
-typedef union npfloat npfreg_t;
-
-union np_dcb {
-	npireg_t all;
-	struct { volatile unsigned short s0, s1; } hwords;
-	struct { volatile unsigned char b0, b1, b2, b3; } bytes;
-};
-
-struct newport_rexregs {
-	npireg_t drawmode1;      /* GL extra mode bits */
-	
-#define DM1_PLANES         0x00000007
-#define    DM1_NOPLANES    0x00000000
-#define    DM1_RGBPLANES   0x00000001
-#define    DM1_RGBAPLANES  0x00000002
-#define    DM1_OLAYPLANES  0x00000004
-#define    DM1_PUPPLANES   0x00000005
-#define    DM1_CIDPLANES   0x00000006
-	
-#define NPORT_DMODE1_DDMASK      0x00000018
-#define NPORT_DMODE1_DD4         0x00000000
-#define NPORT_DMODE1_DD8         0x00000008
-#define NPORT_DMODE1_DD12        0x00000010
-#define NPORT_DMODE1_DD24        0x00000018
-#define NPORT_DMODE1_DSRC        0x00000020
-#define NPORT_DMODE1_YFLIP       0x00000040
-#define NPORT_DMODE1_RWPCKD      0x00000080
-#define NPORT_DMODE1_HDMASK      0x00000300
-#define NPORT_DMODE1_HD4         0x00000000
-#define NPORT_DMODE1_HD8         0x00000100
-#define NPORT_DMODE1_HD12        0x00000200
-#define NPORT_DMODE1_HD32        0x00000300
-#define NPORT_DMODE1_RWDBL       0x00000400
-#define NPORT_DMODE1_ESWAP       0x00000800 /* Endian swap */
-#define NPORT_DMODE1_CCMASK      0x00007000
-#define NPORT_DMODE1_CCLT        0x00001000
-#define NPORT_DMODE1_CCEQ        0x00002000
-#define NPORT_DMODE1_CCGT        0x00004000
-#define NPORT_DMODE1_RGBMD       0x00008000
-#define NPORT_DMODE1_DENAB       0x00010000 /* Dither enable */
-#define NPORT_DMODE1_FCLR        0x00020000 /* Fast clear */
-#define NPORT_DMODE1_BENAB       0x00040000 /* Blend enable */
-#define NPORT_DMODE1_SFMASK      0x00380000
-#define NPORT_DMODE1_SF0         0x00000000
-#define NPORT_DMODE1_SF1         0x00080000
-#define NPORT_DMODE1_SFDC        0x00100000
-#define NPORT_DMODE1_SFMDC       0x00180000
-#define NPORT_DMODE1_SFSA        0x00200000
-#define NPORT_DMODE1_SFMSA       0x00280000
-#define NPORT_DMODE1_DFMASK      0x01c00000
-#define NPORT_DMODE1_DF0         0x00000000
-#define NPORT_DMODE1_DF1         0x00400000
-#define NPORT_DMODE1_DFSC        0x00800000
-#define NPORT_DMODE1_DFMSC       0x00c00000
-#define NPORT_DMODE1_DFSA        0x01000000
-#define NPORT_DMODE1_DFMSA       0x01400000
-#define NPORT_DMODE1_BBENAB      0x02000000 /* Back blend enable */
-#define NPORT_DMODE1_PFENAB      0x04000000 /* Pre-fetch enable */
-#define NPORT_DMODE1_ABLEND      0x08000000 /* Alpha blend */
-#define NPORT_DMODE1_LOMASK      0xf0000000
-#define NPORT_DMODE1_LOZERO      0x00000000
-#define NPORT_DMODE1_LOAND       0x10000000
-#define NPORT_DMODE1_LOANDR      0x20000000
-#define NPORT_DMODE1_LOSRC       0x30000000
-#define NPORT_DMODE1_LOANDI      0x40000000
-#define NPORT_DMODE1_LODST       0x50000000
-#define NPORT_DMODE1_LOXOR       0x60000000
-#define NPORT_DMODE1_LOOR        0x70000000
-#define NPORT_DMODE1_LONOR       0x80000000
-#define NPORT_DMODE1_LOXNOR      0x90000000
-#define NPORT_DMODE1_LONDST      0xa0000000
-#define NPORT_DMODE1_LOORR       0xb0000000
-#define NPORT_DMODE1_LONSRC      0xc0000000
-#define NPORT_DMODE1_LOORI       0xd0000000
-#define NPORT_DMODE1_LONAND      0xe0000000
-#define NPORT_DMODE1_LOONE       0xf0000000
-
-	npireg_t drawmode0;      /* REX command register */
-
-	/* These bits define the graphics opcode being performed. */
-#define NPORT_DMODE0_OPMASK   0x00000003 /* Opcode mask */
-#define NPORT_DMODE0_NOP      0x00000000 /* No operation */
-#define NPORT_DMODE0_RD       0x00000001 /* Read operation */
-#define NPORT_DMODE0_DRAW     0x00000002 /* Draw operation */
-#define NPORT_DMODE0_S2S      0x00000003 /* Screen to screen operation */
-
-	/* The following decide what addressing mode(s) are to be used */
-#define NPORT_DMODE0_AMMASK   0x0000001c /* Address mode mask */
-#define NPORT_DMODE0_SPAN     0x00000000 /* Spanning address mode */
-#define NPORT_DMODE0_BLOCK    0x00000004 /* Block address mode */
-#define NPORT_DMODE0_ILINE    0x00000008 /* Iline address mode */
-#define NPORT_DMODE0_FLINE    0x0000000c /* Fline address mode */
-#define NPORT_DMODE0_ALINE    0x00000010 /* Aline address mode */
-#define NPORT_DMODE0_TLINE    0x00000014 /* Tline address mode */
-#define NPORT_DMODE0_BLINE    0x00000018 /* Bline address mode */
-
-	/* And now some misc. operation control bits. */
-#define NPORT_DMODE0_DOSETUP  0x00000020
-#define NPORT_DMODE0_CHOST    0x00000040
-#define NPORT_DMODE0_AHOST    0x00000080
-#define NPORT_DMODE0_STOPX    0x00000100
-#define NPORT_DMODE0_STOPY    0x00000200
-#define NPORT_DMODE0_SK1ST    0x00000400
-#define NPORT_DMODE0_SKLST    0x00000800
-#define NPORT_DMODE0_ZPENAB   0x00001000
-#define NPORT_DMODE0_LISPENAB 0x00002000
-#define NPORT_DMODE0_LISLST   0x00004000
-#define NPORT_DMODE0_L32      0x00008000
-#define NPORT_DMODE0_ZOPQ     0x00010000
-#define NPORT_DMODE0_LISOPQ   0x00020000
-#define NPORT_DMODE0_SHADE    0x00040000
-#define NPORT_DMODE0_LRONLY   0x00080000
-#define NPORT_DMODE0_XYOFF    0x00100000
-#define NPORT_DMODE0_CLAMP    0x00200000
-#define NPORT_DMODE0_ENDPF    0x00400000
-#define NPORT_DMODE0_YSTR     0x00800000
-
-	npireg_t lsmode;      /* Mode for line stipple ops */
-	npireg_t lspattern;   /* Pattern for line stipple ops */
-	npireg_t lspatsave;   /* Backup save pattern */
-	npireg_t zpattern;    /* Pixel zpattern */
-	npireg_t colorback;   /* Background color */
-	npireg_t colorvram;   /* Clear color for fast vram */
-	npireg_t alpharef;    /* Reference value for afunctions */
-	unsigned long pad0;
-	npireg_t smask0x;     /* Window GL relative screen mask 0 */
-	npireg_t smask0y;     /* Window GL relative screen mask 0 */
-	npireg_t _setup;
-	npireg_t _stepz;
-	npireg_t _lsrestore;
-	npireg_t _lssave;
-
-	unsigned long _pad1[0x30];
-
-	/* Iterators, full state for context switch */
-	npfreg_t _xstart;	/* X-start point (current) */
-	npfreg_t _ystart;	/* Y-start point (current) */
-	npfreg_t _xend;		/* x-end point */
-	npfreg_t _yend;		/* y-end point */
-	npireg_t xsave;		/* copy of xstart integer value for BLOCk addressing MODE */
-	npireg_t xymove;	/* x.y offset from xstart, ystart for relative operations */
-	npfreg_t bresd;
-	npfreg_t bress1;;
-	npireg_t bresoctinc1;
-	volatile int bresrndinc2;
-	npireg_t brese1;
-	npireg_t bress2;
-	npireg_t aweight0;
-	npireg_t aweight1;
-	npfreg_t xstartf;
-	npfreg_t ystartf;
-	npfreg_t xendf;
-	npfreg_t yendf;
-	npireg_t xstarti;
-	npfreg_t xendf1;
-	npireg_t xystarti;
-	npireg_t xyendi;
-	npireg_t xstartendi;
-
-	unsigned long _unused2[0x29];
-
-	npfreg_t colorred;
-	npfreg_t coloralpha;
-	npfreg_t colorgrn;
-	npfreg_t colorblue;
-	npfreg_t slopered;
-	npfreg_t slopealpha;
-	npfreg_t slopegrn;
-	npfreg_t slopeblue;
-	npireg_t wrmask;
-	npireg_t colori;
-	npfreg_t colorx;
-	npfreg_t slopered1;
-	npireg_t hostrw0;
-	npireg_t hostrw1;
-	npireg_t dcbmode;
-#define NPORT_DMODE_WMASK   0x00000003
-#define NPORT_DMODE_W4      0x00000000
-#define NPORT_DMODE_W1      0x00000001
-#define NPORT_DMODE_W2      0x00000002
-#define NPORT_DMODE_W3      0x00000003
-#define NPORT_DMODE_EDPACK  0x00000004
-#define NPORT_DMODE_ECINC   0x00000008
-#define NPORT_DMODE_CMASK   0x00000070
-#define NPORT_DMODE_AMASK   0x00000780
-#define NPORT_DMODE_AVC2    0x00000000
-#define NPORT_DMODE_ACMALL  0x00000080
-#define NPORT_DMODE_ACM0    0x00000100
-#define NPORT_DMODE_ACM1    0x00000180
-#define NPORT_DMODE_AXMALL  0x00000200
-#define NPORT_DMODE_AXM0    0x00000280
-#define NPORT_DMODE_AXM1    0x00000300
-#define NPORT_DMODE_ABT     0x00000380
-#define NPORT_DMODE_AVCC1   0x00000400
-#define NPORT_DMODE_AVAB1   0x00000480
-#define NPORT_DMODE_ALG3V0  0x00000500
-#define NPORT_DMODE_A1562   0x00000580
-#define NPORT_DMODE_ESACK   0x00000800
-#define NPORT_DMODE_EASACK  0x00001000
-#define NPORT_DMODE_CWMASK  0x0003e000
-#define NPORT_DMODE_CHMASK  0x007c0000
-#define NPORT_DMODE_CSMASK  0x0f800000
-#define NPORT_DMODE_SENDIAN 0x10000000
-
-	unsigned long _unused3;
-
-	union np_dcb dcbdata0;
-	npireg_t dcbdata1;
-};
-
-struct newport_cregs {
-	npireg_t smask1x;
-	npireg_t smask1y;
-	npireg_t smask2x;
-	npireg_t smask2y;
-	npireg_t smask3x;
-	npireg_t smask3y;
-	npireg_t smask4x;
-	npireg_t smask4y;
-	npireg_t topscan;
-	npireg_t xywin;
-	npireg_t clipmode;
-#define NPORT_CMODE_SM0   0x00000001
-#define NPORT_CMODE_SM1   0x00000002
-#define NPORT_CMODE_SM2   0x00000004
-#define NPORT_CMODE_SM3   0x00000008
-#define NPORT_CMODE_SM4   0x00000010
-#define NPORT_CMODE_CMSK  0x00001e00
-
-	unsigned long _unused0;
-	unsigned long config;
-#define NPORT_CFG_G32MD   0x00000001
-#define NPORT_CFG_BWIDTH  0x00000002
-#define NPORT_CFG_ERCVR   0x00000004
-#define NPORT_CFG_BDMSK   0x00000078
-#define NPORT_CFG_GDMSK   0x00000f80
-#define NPORT_CFG_GD0     0x00000080
-#define NPORT_CFG_GD1     0x00000100
-#define NPORT_CFG_GD2     0x00000200
-#define NPORT_CFG_GD3     0x00000400
-#define NPORT_CFG_GD4     0x00000800
-#define NPORT_CFG_GFAINT  0x00001000
-#define NPORT_CFG_TOMSK   0x0000e000
-#define NPORT_CFG_VRMSK   0x00070000
-#define NPORT_CFG_FBTYP   0x00080000
-
-	npireg_t _unused1;
-	npireg_t stat;
-#define NPORT_STAT_VERS   0x00000007
-#define NPORT_STAT_GBUSY  0x00000008
-#define NPORT_STAT_BBUSY  0x00000010
-#define NPORT_STAT_VRINT  0x00000020
-#define NPORT_STAT_VIDINT 0x00000040
-#define NPORT_STAT_GLMSK  0x00001f80
-#define NPORT_STAT_BLMSK  0x0007e000
-#define NPORT_STAT_BFIRQ  0x00080000
-#define NPORT_STAT_GFIRQ  0x00100000
-
-	npireg_t ustat;
-	npireg_t dreset;
-};
-
-struct newport_regs {
-	struct newport_rexregs set;
-	unsigned long _unused0[0x16e];
-	struct newport_rexregs go;
-	unsigned long _unused1[0x22e];
-	struct newport_cregs cset;
-	unsigned long _unused2[0x1ef];
-	struct newport_cregs cgo;
-};
-extern struct newport_regs *npregs;
-
-
-typedef struct {
-	unsigned int drawmode1;
-	unsigned int drawmode0;
-	unsigned int lsmode;   
-	unsigned int lspattern;
-	unsigned int lspatsave;
-	unsigned int zpattern; 
-	unsigned int colorback;
-	unsigned int colorvram;
-	unsigned int alpharef; 
-	unsigned int smask0x;  
-	unsigned int smask0y;  
-	unsigned int _xstart;  
-	unsigned int _ystart;  
-	unsigned int _xend;    
-	unsigned int _yend;    
-	unsigned int xsave;    
-	unsigned int xymove;   
-	unsigned int bresd;    
-	unsigned int bress1;   
-	unsigned int bresoctinc1;
-	unsigned int bresrndinc2;
-	unsigned int brese1;     
-	unsigned int bress2;     
-	
-	unsigned int aweight0;    
-	unsigned int aweight1;    
-	unsigned int colorred;    
-	unsigned int coloralpha;  
-	unsigned int colorgrn;    
-	unsigned int colorblue;   
-	unsigned int slopered;    
-	unsigned int slopealpha;  
-	unsigned int slopegrn;    
-	unsigned int slopeblue;   
-	unsigned int wrmask;      
-	unsigned int hostrw0;     
-	unsigned int hostrw1;     
-	
-        /* configregs */
-	
-	unsigned int smask1x;    
-	unsigned int smask1y;    
-	unsigned int smask2x;    
-	unsigned int smask2y;    
-	unsigned int smask3x;    
-	unsigned int smask3y;    
-	unsigned int smask4x;    
-	unsigned int smask4y;    
-	unsigned int topscan;    
-	unsigned int xywin;      
-	unsigned int clipmode;   
-	unsigned int config;     
-	
-        /* dcb registers */
-	unsigned int dcbmode;   
-	unsigned int dcbdata0;  
-	unsigned int dcbdata1;
-} newport_ctx;
-
-/* Reading/writing VC2 registers. */
-#define VC2_REGADDR_INDEX      0x00000000
-#define VC2_REGADDR_IREG       0x00000010
-#define VC2_REGADDR_RAM        0x00000030
-#define VC2_PROTOCOL           (NPORT_DMODE_EASACK | 0x00800000 | 0x00040000)
-
-#define VC2_VLINET_ADDR        0x000
-#define VC2_VFRAMET_ADDR       0x400
-#define VC2_CGLYPH_ADDR        0x500
-
-/* Now the Indexed registers of the VC2. */
-#define VC2_IREG_VENTRY        0x00
-#define VC2_IREG_CENTRY        0x01
-#define VC2_IREG_CURSX         0x02
-#define VC2_IREG_CURSY         0x03
-#define VC2_IREG_CCURSX        0x04
-#define VC2_IREG_DENTRY        0x05
-#define VC2_IREG_SLEN          0x06
-#define VC2_IREG_RADDR         0x07
-#define VC2_IREG_VFPTR         0x08
-#define VC2_IREG_VLSPTR        0x09
-#define VC2_IREG_VLIR          0x0a
-#define VC2_IREG_VLCTR         0x0b
-#define VC2_IREG_CTPTR         0x0c
-#define VC2_IREG_WCURSY        0x0d
-#define VC2_IREG_DFPTR         0x0e
-#define VC2_IREG_DLTPTR        0x0f
-#define VC2_IREG_CONTROL       0x10
-#define VC2_IREG_CONFIG        0x20
-
-extern inline void newport_vc2_set(struct newport_regs *regs, unsigned char vc2ireg,
-				   unsigned short val)
-{
-	regs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_INDEX | NPORT_DMODE_W3 |
-			   NPORT_DMODE_ECINC | VC2_PROTOCOL);
-	regs->set.dcbdata0.all = (vc2ireg << 24) | (val << 8);
-}
-
-extern inline unsigned short newport_vc2_get(struct newport_regs *regs,
-					     unsigned char vc2ireg)
-{
-	regs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_INDEX | NPORT_DMODE_W1 |
-			   NPORT_DMODE_ECINC | VC2_PROTOCOL);
-	regs->set.dcbdata0.bytes.b3 = vc2ireg;
-	regs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_IREG | NPORT_DMODE_W2 |
-			   NPORT_DMODE_ECINC | VC2_PROTOCOL);
-	return regs->set.dcbdata0.hwords.s1;
-}
-
-/* VC2 Control register bits */
-#define VC2_CTRL_EVIRQ     0x0001
-#define VC2_CTRL_EDISP     0x0002
-#define VC2_CTRL_EVIDEO    0x0004
-#define VC2_CTRL_EDIDS     0x0008
-#define VC2_CTRL_ECURS     0x0010
-#define VC2_CTRL_EGSYNC    0x0020
-#define VC2_CTRL_EILACE    0x0040
-#define VC2_CTRL_ECDISP    0x0080
-#define VC2_CTRL_ECCURS    0x0100
-#define VC2_CTRL_ECG64     0x0200
-#define VC2_CTRL_GLSEL     0x0400
-
-/* Controlling the color map on NEWPORT. */
-#define NCMAP_REGADDR_AREG   0x00000000
-#define NCMAP_REGADDR_ALO    0x00000000
-#define NCMAP_REGADDR_AHI    0x00000010
-#define NCMAP_REGADDR_PBUF   0x00000020
-#define NCMAP_REGADDR_CREG   0x00000030
-#define NCMAP_REGADDR_SREG   0x00000040
-#define NCMAP_REGADDR_RREG   0x00000060
-#define NCMAP_PROTOCOL       (0x00008000 | 0x00040000 | 0x00800000)
-
-static inline void newport_cmap_setaddr(struct newport_regs *regs,
-					unsigned short addr)
-{
-	regs->set.dcbmode = (NPORT_DMODE_ACMALL | NCMAP_PROTOCOL |
-			   NPORT_DMODE_SENDIAN | NPORT_DMODE_ECINC |
-			   NCMAP_REGADDR_AREG | NPORT_DMODE_W2);
-	regs->set.dcbdata0.hwords.s1 = addr;
-	regs->set.dcbmode = (NPORT_DMODE_ACMALL | NCMAP_PROTOCOL |
-			   NCMAP_REGADDR_PBUF | NPORT_DMODE_W3);
-}
-
-static inline void newport_cmap_setrgb(struct newport_regs *regs,
-				       unsigned char red,
-				       unsigned char green,
-				       unsigned char blue)
-{
-	regs->set.dcbdata0.all =
-		(red << 24) |
-		(green << 16) |
-		(blue << 8);
-}
-
-/* Miscellaneous NEWPORT routines. */
-#define BUSY_TIMEOUT 100000
-static inline int newport_wait(void)
-{
-	int i = 0;
-
-	while(i < BUSY_TIMEOUT)
-		if(!(npregs->cset.stat & NPORT_STAT_GBUSY))
-			break;
-	if(i == BUSY_TIMEOUT)
-		return 1;
-	return 0;
-}
-
-static inline int newport_bfwait(void)
-{
-	int i = 0;
-
-	while(i < BUSY_TIMEOUT)
-		if(!(npregs->cset.stat & NPORT_STAT_BBUSY))
-			break;
-	if(i == BUSY_TIMEOUT)
-		return 1;
-	return 0;
-}
-
-/* newport.c and cons_newport.c routines */
-extern struct graphics_ops *newport_probe (int, const char **);
-
-void newport_save    (void *);
-void newport_restore (void *);
-void newport_reset   (void);
-int  newport_ioctl   (int card, int cmd, unsigned long arg);
-
-/*
- * DCBMODE register defines:
- */
-
-/* Widht of the data being transfered for each DCBDATA[01] word */
-#define DCB_DATAWIDTH_4 0x0
-#define DCB_DATAWIDTH_1 0x1
-#define DCB_DATAWIDTH_2 0x2
-#define DCB_DATAWIDTH_3 0x3
-
-/* If set, all of DCBDATA will be moved, otherwise only DATAWIDTH bytes */
-#define DCB_ENDATAPACK   (1 << 2)
-
-/* Enables DCBCRS auto increment after each DCB transfer */
-#define DCB_ENCRSINC     (1 << 3)
-
-/* shift for accessing the control register select address (DBCCRS, 3 bits) */
-#define DCB_CRS_SHIFT    4
-
-/* DCBADDR (4 bits): display bus slave address */
-#define DCB_ADDR_SHIFT   7
-#define DCB_VC2          (0 <<  DCB_ADDR_SHIFT)
-#define DCB_CMAP_ALL     (1 <<  DCB_ADDR_SHIFT)
-#define DCB_CMAP0        (2 <<  DCB_ADDR_SHIFT)
-#define DCB_CMAP1        (3 <<  DCB_ADDR_SHIFT)
-#define DCB_XMAP_ALL     (4 <<  DCB_ADDR_SHIFT)
-#define DCB_XMAP0        (5 <<  DCB_ADDR_SHIFT)
-#define DCB_XMAP1        (6 <<  DCB_ADDR_SHIFT)
-#define DCB_BT445        (7 <<  DCB_ADDR_SHIFT)
-#define DCB_VCC1         (8 <<  DCB_ADDR_SHIFT)
-#define DCB_VAB1         (9 <<  DCB_ADDR_SHIFT)
-#define DCB_LG3_BDVERS0  (10 << DCB_ADDR_SHIFT)
-#define DCB_LG3_ICS1562  (11 << DCB_ADDR_SHIFT)
-#define DCB_RESERVED     (15 << DCB_ADDR_SHIFT)
-
-/* DCB protocol ack types */
-#define DCB_ENSYNCACK    (1 << 11)
-#define DCB_ENASYNCACK   (1 << 12)
-
-#define DCB_CSWIDTH_SHIFT 13
-#define DCB_CSHOLD_SHIFT  18
-#define DCB_CSSETUP_SHIFT 23
-
-/* XMAP9 specific defines */
-/*   XMAP9 -- registers as seen on the DCBMODE register*/
-#   define XM9_CRS_CONFIG            (0 << DCB_CRS_SHIFT)
-#       define XM9_PUPMODE           (1 << 0)
-#       define XM9_ODD_PIXEL         (1 << 1)
-#       define XM9_8_BITPLANES       (1 << 2)
-#       define XM9_SLOW_DCB          (1 << 3)
-#       define XM9_VIDEO_RGBMAP_MASK (3 << 4)
-#       define XM9_EXPRESS_VIDEO     (1 << 6)
-#       define XM9_VIDEO_OPTION      (1 << 7)
-#   define XM9_CRS_REVISION          (1 << DCB_CRS_SHIFT)
-#   define XM9_CRS_FIFO_AVAIL        (2 << DCB_CRS_SHIFT)
-#       define XM9_FIFO_0_AVAIL      0
-#       define XM9_FIFO_1_AVAIL      1
-#       define XM9_FIFO_2_AVAIL      3
-#       define XM9_FIFO_3_AVAIL      2
-#       define XM9_FIFO_FULL         XM9_FIFO_0_AVAIL
-#       define XM9_FIFO_EMPTY        XM9_FIFO_3_AVAIL
-#   define XM9_CRS_CURS_CMAP_MSB     (3 << DCB_CRS_SHIFT)
-#   define XM9_CRS_PUP_CMAP_MSB      (4 << DCB_CRS_SHIFT)
-#   define XM9_CRS_MODE_REG_DATA     (5 << DCB_CRS_SHIFT)
-#   define XM9_CRS_MODE_REG_INDEX    (7 << DCB_CRS_SHIFT)
-
-
-#define DCB_CYCLES(setup,hold,width)                \
-                  ((hold << DCB_CSHOLD_SHIFT)  |    \
-		   (setup << DCB_CSSETUP_SHIFT)|    \
-		   (width << DCB_CSWIDTH_SHIFT))
-
-#define W_DCB_XMAP9_PROTOCOL       DCB_CYCLES (2, 1, 0)
-#define WSLOW_DCB_XMAP9_PROTOCOL   DCB_CYCLES (5, 5, 0)
-#define WAYSLOW_DCB_XMAP9_PROTOCOL DCB_CYCLES (12, 12, 0)
-#define R_DCB_XMAP9_PROTOCOL       DCB_CYCLES (2, 1, 3)
-
-static inline void
-xmap9FIFOWait (struct newport_regs *rex)
-{
-        rex->set.dcbmode = DCB_XMAP0 | XM9_CRS_FIFO_AVAIL |
-		DCB_DATAWIDTH_1 | R_DCB_XMAP9_PROTOCOL;
-        newport_bfwait ();
-	
-        while ((rex->set.dcbdata0.bytes.b3 & 3) != XM9_FIFO_EMPTY)
-		;
-}
-
-static inline void
-xmap9SetModeReg (struct newport_regs *rex, unsigned int modereg, unsigned int data24, int cfreq)
-{
-        if (cfreq > 119)
-            rex->set.dcbmode = DCB_XMAP_ALL | XM9_CRS_MODE_REG_DATA |
-                        DCB_DATAWIDTH_4 | W_DCB_XMAP9_PROTOCOL;
-        else if (cfreq > 59)
-            rex->set.dcbmode = DCB_XMAP_ALL | XM9_CRS_MODE_REG_DATA |
-		    DCB_DATAWIDTH_4 | WSLOW_DCB_XMAP9_PROTOCOL;    
-        else
-            rex->set.dcbmode = DCB_XMAP_ALL | XM9_CRS_MODE_REG_DATA |
-                        DCB_DATAWIDTH_4 | WAYSLOW_DCB_XMAP9_PROTOCOL; 
-        rex->set.dcbdata0.all = ((modereg) << 24) | (data24 & 0xffffff);
-}
-
-#define BT445_PROTOCOL		DCB_CYCLES(1,1,3)
-
-#define BT445_CSR_ADDR_REG	(0 << DCB_CRS_SHIFT)
-#define BT445_CSR_REVISION	(2 << DCB_CRS_SHIFT)
-
-#define BT445_REVISION_REG	0x01
-
-#endif /* !(_SGI_NEWPORT_H) */
-
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/ng1.h linux/include/asm-mips/ng1.h
--- v2.3.47/linux/include/asm-mips/ng1.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/ng1.h	Thu Feb 24 22:52:30 2000
@@ -1,7 +1,13 @@
-/*
- * SGI/Newport video card ioctl definitions
+/* $Id: ng1.h,v 1.4 1999/08/19 22:56:33 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
+ * SGI/Newport video card ioctl definitions
  */
+#ifndef _ASM_NG1_H
+#define _ASM_NG1_H
 
 typedef struct {
         int flags;
@@ -47,4 +53,4 @@
         unsigned char blue  [256];
 };
 
-
+#endif /* _ASM_NG1_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/ng1hw.h linux/include/asm-mips/ng1hw.h
--- v2.3.47/linux/include/asm-mips/ng1hw.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/ng1hw.h	Thu Feb 24 22:52:30 2000
@@ -1,572 +1,222 @@
-/* This is the hardware interface for newport graphics.  It's taken from
-   IRIX.
+/* $Id: ng1hw.h,v 1.5 1999/11/07 10:18:31 ulfc Exp $
+ * 
+ * ng1hw.h: Tweaks the newport.h structures and definations to be compatible
+ * 	    with IRIX.  Quite ugly, but it works.
+ *
+ * Copyright (C) 1999 Ulf Carlsson (ulfc@thepuffingroup.com)
+ *
+ */
+
+#ifndef _SGI_NG1HW_H
+#define _SGI_NG1HW_H
 
-   Alex deVries <puffin@redhat.com>
+#include <video/newport.h>
 
-*/
+#define rex3regs	newport_rexregs
+#define configregs	newport_cregs
+#define float_long	npfreg_t
 
+typedef struct newport_rexregs Rex3regs;
+typedef struct newport_cregs Configregs;
+typedef union np_dcb DCB_reg;
 
-#ifndef __SYS_NG1HW_H__
-#define __SYS_NG1HW_H__
-
-#ident "$Revision: 1.1 $"
-
-#define BIT(n)	(0x1 << n)
-
-
-#ifndef REX_ASMCODE
-
-typedef union {
-    volatile float flt;
-    volatile unsigned int word;
-} float_long;
-
-typedef volatile unsigned int vol_ulong;
-typedef volatile unsigned int fixed16;
-
-typedef union {
-    vol_ulong   byword;
-    struct {
-	volatile unsigned short s0;
-	volatile unsigned short s1;
-    } byshort;
-    struct {
-	volatile unsigned char b0, b1, b2;
-	volatile unsigned char b3;
-    } bybyte;
-} DCB_reg;
-
-#ifndef REXSIM
-typedef struct rex3regs {	/* THE CHIP */
-    vol_ulong drawmode1;	/* extra mode bits for GL 	0x0000 */
-    vol_ulong drawmode0;	/* command register 		0x0004 */
-
-    vol_ulong lsmode;		/* line stipple mode		0x0008 */
-    vol_ulong lspattern;	/* 32 bit pixel lspattern	0x000c */
-    vol_ulong lspatsave;	/* save register for lspattern	0x0010 */
-    vol_ulong zpattern;		/* 32 bit pixel zpattern	0x0014 */
-
-    vol_ulong colorback;	/* background color		0x0018 */
-    vol_ulong colorvram;	/* fast vram clear color	0x001c */
-    vol_ulong alpharef;		/* afunction reference value	0x0020 */
-
-    vol_ulong pad0;		/* padding 			0x0024 */	
-
-    vol_ulong smask0x;		/* screen mask 0, window rel,	0x0028 */
-    vol_ulong smask0y;		/* exclusively for the GL	0x002c */
-    vol_ulong _setup;		/* do line/span setup, no iter  0x0030 */
-    vol_ulong _stepz;		/* Enable ZPATTERN for this pix 0x0034 */
-    vol_ulong _lsrestore;	/* Restore lspattern,count	0x0038 */
-    vol_ulong _lssave;		/* Backup lspattern,count	0x003c */
-
-    char _pad1[0x100-0x40];
-
-    float_long _xstart;		/* 16.4(7) current x		0x0100 */
-    float_long _ystart;		/* 16.4(7) current y		0x0104 */
-    float_long _xend;		/* 16.4(7)			0x0108 */
-    float_long _yend;		/* 16.4(7)			0x010c */
-    vol_ulong xsave;		/* 16	x save for blocks	0x0110 */
-    vol_ulong xymove;		/* x,y copy dest offset		0x0114 */
-    float_long bresd;		/* s19.8 bres d error term	0x0118 */
-    float_long bress1;		/* s2.15 bres s coverage term	0x011c */
-    vol_ulong bresoctinc1;	/* 3(4)17.3 octant+inc1 value	0x0120 */
-    volatile int bresrndinc2;	/* 8(3)18.3 bres inc2 value	0x0124 */
-    vol_ulong brese1;		/* 1.15 bres e1 (minor slope)	0x0128 */
-    vol_ulong bress2;           /* s18.8 bres s2 coverage term  0x012c */
-    vol_ulong aweight0;		/* antialiasing weights		0x0130 */
-    vol_ulong aweight1;		/* antialiasing weights		0x0134 */
-    float_long xstartf;		/* 12.4(7) GL version of _xstart0x0138 */
-    float_long ystartf;		/* 12.4(7)			0x013c */
-    float_long xendf;		/* 12.4(7)			0x0140 */
-    float_long yendf;		/* 12.4(7)			0x0144 */
-    fixed16 xstarti;		/* 16 integer format for xstart 0x0148 */
-    float_long xendf1;		/* 12.4(7) same as xend		0x014c */
-    fixed16 xystarti;		/* 16,16			0x0150 */
-    fixed16 xyendi;		/* 16,16			0x0154 */
-    fixed16 xstartendi;		/* 16,16			0x0158 */
-    char _pad2[0x200-0x15c];
-    float_long colorred;	/* o12.11 red (also foreground)	0x0200 */
-    float_long coloralpha;	/* o8.11 alpha			0x0204 */
-    float_long colorgrn;	/* o8.11 green			0x0208 */
-    float_long colorblue;	/* o8.11 blue			0x020c */
-    float_long slopered;	/* s9.11			0x0210 */
-    float_long slopealpha;	/* s9.11			0x0214 */
-    float_long slopegrn;	/* s9.11			0x0218 */
-    float_long slopeblue;	/* s9.11			0x021c */
-    vol_ulong wrmask;		/* writemask			0x0220 */
-    vol_ulong colori;		/* packed bgr/ci		0x0224 */
-    float_long colorx;		/* 12.11 red (no overflow)	0x0228 */
-    float_long slopered1;	/* same as slopered		0x022c */
-    vol_ulong hostrw0;		/* host PIO/DMA port (msw)	0x0230 */
-    vol_ulong hostrw1;		/* host PIO/DMA port (lsw)	0x0234 */
-    vol_ulong dcbmode;		/* display ctrl bus mode reg 	0x0238 */
-    volatile int pad3;						/* 0x023c */
-    DCB_reg dcbdata0;		/* display ctrl bus port (msw)	0x0240 */
-    vol_ulong dcbdata1;		/* display ctrl bus port (lsw)	0x0244 */
-} Rex3regs;
-	
-
-typedef struct configregs {
-    vol_ulong smask1x;		/* screenmask1 right,left edges 0x1300 */
-    vol_ulong smask1y;		/* screenmask1 bottom,top edges 0x1304 */
-    vol_ulong smask2x;		/* screenmask2 right,left edges 0x1308 */
-    vol_ulong smask2y;		/* screenmask2 bottom,top edges 0x130c */
-    vol_ulong smask3x;		/* screenmask3 right,left edges 0x1310 */
-    vol_ulong smask3y;		/* screenmask3 bottom,top edges 0x1314 */
-    vol_ulong smask4x;		/* screenmask4 right,left edges 0x1318 */
-    vol_ulong smask4y;		/* screenmask4 bottom,top edges 0x131c */
-    vol_ulong topscan;		/* y coord of top screen line	0x1320 */
-    vol_ulong xywin;		/* window offset 		0x1324 */
-    vol_ulong clipmode;		/* cid,smask settings 		0x1328 */
-    vol_ulong pad0;		/*				0x132c */
-    vol_ulong config;		/* miscellaneous  config bits 	0x1330 */
-    vol_ulong pad1;		/*				0x1334 */
-    vol_ulong status;		/* chip busy, FIFO, int status  0x1338 */
-				/* read clears interrupt status bits   */
-    vol_ulong ustatus;		/* padding on rex rev a, 'read-only' 0x133c */
-				/* copy of status on rex rev b.	       */
-    vol_ulong dcbreset;		/* resets DCB and flushes BFIFO 0x1340 */
-} Configregs;
-
-typedef struct rex3chip {
-		/* page 0 */    
-	struct rex3regs set;		/* 0x0000 */
-	char _pad0[0x7fc-sizeof(struct rex3regs)];
-	volatile unsigned int dummy; /* 0x7fc */
-	struct rex3regs go;		/* 0x0800 */
 
-	char _pad1[0x1300-0x800-sizeof(struct rex3regs)];
+/* It looks like I can't do a simple tweak with this structure because the IRIX
+ * version is just *too* stupid.  Ok, here's a new version of it..
+ */
 
-		/* page 1 */
+struct rex3chip {
+	struct newport_rexregs set;
+	unsigned long _unused0[0x16e];
+	struct newport_rexregs go;
+	unsigned long _unused1[0x22e];
 	struct {
-	    struct configregs set; 	/* 0x1300 */
-	    char _pad0[0x800-sizeof(struct configregs)];
-	    struct configregs go; 	/* 0x1b00 */
+		struct newport_cregs set;
+		unsigned long _unused2[0x1ef];
+		struct newport_cregs go;
 	} p1;
-} rex3Chip, Rex3chip;
+};
 
+typedef struct rex3chip rex3Chip;
+typedef struct rex3chip Rex3chip;
 
-#endif /* REX_ASMCODE */
-#endif /* REXSIM */
+/* Tweak the defines .. */
 
-/* Since alot of flags went away, define here as null bits
-   and leave the code as it is for now, 
-   marking where we have to change stuff.
-
-   NONE of these should be defined !   - billt
-   */
-
-#define LSCONTINUE 0
-#define SHADECONTINUE 0
-#define XYCONTINUE 0
-#define XMAJOR 0
-#define YMAJOR 0
-#define QUADMODE 0
-#define LRQPOLY 0
-/* RGBMODE, DITHER now live in DM1 */
-#define RGBMODECMD 0
-#define DITHER 0
-#define DITHERRANGE 0
-/* BLOCK is a function of ADDRMODE */
-#define BLOCK 0
-#define STOPONX 0
-#define STOPONY 0
-/* COLORCOMPARE is a combo of 3 bits (<, = , >) */
-#define COLORCOMP 0
-/* FRACTIONS are gone... */
-#define INITFRAC 0
-#define FRACTION1 0
-
-/* -- some old AUX1 junk -- */
-#define DOUBLEBUF 0
-#define DBLDST0 0
-#define DBLDST1 0
-#define DBLSRC 0
-#define COLORAUX 0
-
-
-/* --- a couple of old cmds also only for conversion --- */
-#define REX_LDPIXEL 0x1
-#define REX_ANTIAUX 0
-#define REX_DRAW 0
-#define LOGICSRC 0
-/* --- Blech! locicops are in DM1 too! */
-#define REX_LO_ZERO REX_LO_ZERO 
-#define REX_LO_AND DM1_LO_AND
-#define REX_LO_ANDR DM1_LO_ANDR
-#define REX_LO_SRC DM1_LO_SRC
-#define REX_LO_ANDI DM1_LO_ANDI
-#define REX_LO_DST DM1_LO_DST
-#define REX_LO_XOR DM1_LO_XOR
-#define REX_LO_OR DM1_LO_OR
-#define REX_LO_NOR DM1_LO_NOR
-#define REX_LO_XNOR DM1_LO_XNOR
-#define REX_LO_NDST DM1_LO_NDST
-#define REX_LO_ORR DM1_LO_ORR
-#define REX_LO_NSRC DM1_LO_NSRC
-#define REX_LO_ORI DM1_LO_ORI
-#define REX_LO_NAND DM1_LO_NAND
-#define REX_LO_ONE DM1_LO_ONE
-
-
-/*
- *  drawmode flags
- */
-#define DM0_OPCODE	0x3		/* opcode(1:0)	*/
-#	define DM0_NOP		0x0
-#	define DM0_READ		0x1
-#	define DM0_DRAW		0x2
-#	define DM0_SCR2SCR	0x3
-#define DM0_ADRMODE_SHIFT	2	/* adrmode(2:0)	*/
-#	define DM0_ADRMODE	(0x7<<DM0_ADRMODE_SHIFT)
-#	define DM0_SPAN		(0x0<<DM0_ADRMODE_SHIFT)
-#	define DM0_BLOCK	(0x1<<DM0_ADRMODE_SHIFT)
-#	define DM0_ILINE	(0x2<<DM0_ADRMODE_SHIFT)
-#	define DM0_FLINE	(0x3<<DM0_ADRMODE_SHIFT)
-#	define DM0_ALINE	(0x4<<DM0_ADRMODE_SHIFT)
-#ifdef OLDJUNK
-
-/* XXX These definitions are obsolete */
-
-#	define DM0_AELINE	(0x5<<DM0_ADRMODE_SHIFT)
-#	define DM0_ACWEDGE	(0x6<<DM0_ADRMODE_SHIFT)
-#	define DM0_ACCWEDGE	(0x7<<DM0_ADRMODE_SHIFT)
-
-#else
-
-/* XXX These are according to 11/2/92 spec */
-
-#       define DM0_TLINE        (0x5<<DM0_ADRMODE_SHIFT)
-#       define DM0_BLINE        (0x6<<DM0_ADRMODE_SHIFT)
-
-#endif /* OLDJUNK */
-
-#define DM0_DOSETUP	BIT(5)
-#define DM0_COLORHOST	BIT(6)
-#define DM0_ALPHAHOST	BIT(7)
-#define DM0_STOPONX	BIT(8)
-#define DM0_STOPONY	BIT(9)
-#define DM0_STOPONXY	(DM0_STOPONX | DM0_STOPONY)
-#define DM0_SKIPFIRST	BIT(10)
-#define DM0_SKIPLAST	BIT(11)
-#define DM0_ENZPATTERN	BIT(12)
-#define DM0_ENLSPATTERN	BIT(13)
-#define DM0_LSADVLAST	BIT(14)
-#define DM0_LENGTH32	BIT(15)
-#define DM0_ZOPAQUE	BIT(16)
-#define DM0_LSOPAQUE	BIT(17)
-#define DM0_SHADE	BIT(18)
-#define DM0_LRONLY	BIT(19)
-
-#ifdef OLDJUNK
-
-/* XXX These definitions are obsolete */
-
-#define DM0_CICLAMP     BIT(20)
-#define DM0_ENDPTFILTER BIT(21)
-
-#else
-
-/* XXX These are according to 11/2/92 spec */
-
-#define DM0_XYOFFSET    BIT(20)
-#define DM0_CICLAMP     BIT(21)
-#define DM0_ENDPTFILTER BIT(22)
-
-#endif	/* OLDJUNK */
-/* New Feature in REX REV B */
-#define	DM0_YSTRIDE	BIT(23)
+#define DM0_OPCODE		NPORT_DMODE0_OPMASK
+#define DM0_NOP			NPORT_DMODE0_NOP
+#define DM0_READ		NPORT_DMODE0_RD
+#define DM0_DRAW		NPORT_DMODE0_DRAW
+#define DM0_SCR2SCR		NPORT_DMODE0_S2S
+
+#define DM0_ADRMODE_SHIFT	2
+#define DM0_ADRMODE		NPORT_DMODE0_AMMASK
+#define DM0_SPAN		NPORT_DMODE0_SPAN
+#define DM0_BLOCK		NPORT_DMODE0_BLOCK
+#define DM0_ILINE		NPORT_DMODE0_ILINE
+#define DM0_FLINE		NPORT_DMODE0_FLINE
+#define DM0_ALINE		NPORT_DMODE0_ALINE
+#define DM0_TLINE		NPORT_DMODE0_TLINE
+#define DM0_BLINE               NPORT_DMODE0_BLINE
+
+#define DM0_DOSETUP		NPORT_DMODE0_DOSETUP
+#define DM0_COLORHOST		NPORT_DMODE0_CHOST
+#define DM0_ALPHAHOST		NPORT_DMODE0_AHOST
+#define DM0_STOPONX		NPORT_DMODE0_STOPX
+#define DM0_STOPONY		NPORT_DMODE0_STOPY
+#define DM0_STOPONXY		(NPORT_DMODE0_STOPX | NPORT_DMODE0_STOPY)
+#define DM0_SKIPFIRST		NPORT_DMODE0_SK1ST
+#define DM0_SKIPLAST		NPORT_DMODE0_SKLST
+#define DM0_ENZPATTERN		NPORT_DMODE0_ZPENAB
+#define DM0_ENLSPATTERN		NPORT_DMODE0_LISPENAB
+#define DM0_LSADVLAST		NPORT_DMODE0_LISLST
+#define DM0_LENGTH32		NPORT_DMODE0_L32
+#define DM0_ZOPAQUE		NPORT_DMODE0_ZOPQ
+#define DM0_LSOPAQUE		NPORT_DMODE0_LISOPQ
+#define DM0_SHADE		NPORT_DMODE0_SHADE
+#define DM0_LRONLY		NPORT_DMODE0_LRONLY
+#define DM0_XYOFFSET		NPORT_DMODE0_XYOFF
+#define DM0_CICLAMP		NPORT_DMODE0_CLAMP
+#define DM0_ENDPTFILTER		NPORT_DMODE0_ENDPF
+#define	DM0_YSTRIDE		NPORT_DMODE0_YSTR 
 
 #define DM1_PLANES_SHIFT	0
-#define DM1_PLANES	0x7		/* planes(2:0)	*/
-#	define DM1_NOPLANES	0x0
-#	define DM1_RGBPLANES	0x1
-#	define DM1_RGBAPLANES	0x2
-#	define DM1_OLAYPLANES	0x4
-#	define DM1_PUPPLANES	0x5
-#	define DM1_CIDPLANES	0x6
-#define DM1_DRAWDEPTH_SHIFT	3	/* drawdepth(1:0)	*/
-#define DM1_DRAWDEPTH_MASK      (3 << DM1_DRAWDEPTH_SHIFT)
-#	define DM1_DRAWDEPTH	(0x3 << DM1_DRAWDEPTH_SHIFT)	
-#	define DM1_DRAWDEPTH4	(0x0 << DM1_DRAWDEPTH_SHIFT)
-#	define DM1_DRAWDEPTH8	(0x1 << DM1_DRAWDEPTH_SHIFT)
-#	define DM1_DRAWDEPTH12	(0x2 << DM1_DRAWDEPTH_SHIFT)
-#	define DM1_DRAWDEPTH24	(0x3 << DM1_DRAWDEPTH_SHIFT)
-#define DM1_DBLSRC		BIT(5)
-#define DM1_YFLIP		BIT(6)
-#define DM1_RWPACKED		BIT(7)
-#define DM1_HOSTDEPTH_SHIFT 	8	/* hostdepth(1:0)	*/
-#define DM1_HOSTDEPTH_MASK      (3 << DM1_HOSTDEPTH_SHIFT)
-#	define DM1_HOSTDEPTH	(0x3 << DM1_HOSTDEPTH_SHIFT)
-#	define DM1_HOSTDEPTH4	(0x0 << DM1_HOSTDEPTH_SHIFT)
-#	define DM1_HOSTDEPTH8	(0x1 << DM1_HOSTDEPTH_SHIFT)
-#	define DM1_HOSTDEPTH12	(0x2 << DM1_HOSTDEPTH_SHIFT)
-#	define DM1_HOSTDEPTH32	(0x3 << DM1_HOSTDEPTH_SHIFT)
-#define DM1_RWDOUBLE		BIT(10)
-#define DM1_SWAPENDIAN		BIT(11)
-#define DM1_COLORCOMPARE_SHIFT  12	/* compare (2:0)	*/
-#define DM1_COLORCOMPARE_MASK  (7 << DM1_COLORCOMPARE_SHIFT)
-#	define DM1_COLORCOMPARE (0x7 << DM1_COLORCOMPARE_SHIFT)
-#	define DM1_COLORCOMPLT	BIT(12)
-#	define DM1_COLORCOMPEQ	BIT(13)
-#	define DM1_COLORCOMPGT	BIT(14)
-#define DM1_RGBMODE		BIT(15)
-#define DM1_ENDITHER		BIT(16)
-#define DM1_FASTCLEAR		BIT(17)
-#define DM1_ENBLEND		BIT(18)
-#define DM1_SF_SHIFT		19	/* sfactor(2:0)	*/
-#define DM1_SF_MASK   		(7 << DM1_SF_SHIFT)
-#	define DM1_SF		(0x7 << DM1_SF_SHIFT)
-#	define DM1_SF_ZERO	(0x0 << DM1_SF_SHIFT)
-#	define DM1_SF_ONE	(0x1 << DM1_SF_SHIFT)
-#	define DM1_SF_DC	(0x2 << DM1_SF_SHIFT)
-#	define DM1_SF_MDC	(0x3 << DM1_SF_SHIFT)
-#	define DM1_SF_SA	(0x4 << DM1_SF_SHIFT)
-#	define DM1_SF_MSA	(0x5 << DM1_SF_SHIFT)
-#define DM1_DF_SHIFT		22	/* dfactor(2:0)	*/
-#define DM1_DF_MASK     (7 << DM1_DF_SHIFT)
-#	define DM1_DF		(0x7 << DM1_DF_SHIFT)
-#	define DM1_DF_ZERO	(0x0 << DM1_DF_SHIFT)
-#	define DM1_DF_ONE	(0x1 << DM1_DF_SHIFT)
-#	define DM1_DF_SC	(0x2 << DM1_DF_SHIFT)
-#	define DM1_DF_MSC	(0x3 << DM1_DF_SHIFT)
-#	define DM1_DF_SA	(0x4 << DM1_DF_SHIFT)
-#	define DM1_DF_MSA	(0x5 << DM1_DF_SHIFT)
-#define DM1_ENBACKBLEND		BIT(25)
-#define DM1_ENPREFETCH		BIT(26)
-#define DM1_BLENDALPHA		BIT(27)
-#define DM1_LO_SHIFT		28	/* logicop(3:0)	*/
-#	define DM1_LO		(0xF << DM1_LO_SHIFT)
-#       define DM1_LO_MASK      DM1_LO
-#	define DM1_LO_ZERO	(0x0 << DM1_LO_SHIFT)
-#	define DM1_LO_AND	(0x1 << DM1_LO_SHIFT)
-#	define DM1_LO_ANDR	(0x2 << DM1_LO_SHIFT)
-#	define DM1_LO_SRC	(0x3 << DM1_LO_SHIFT)
-#	define DM1_LO_ANDI	(0x4 << DM1_LO_SHIFT)
-#	define DM1_LO_DST	(0x5 << DM1_LO_SHIFT)
-#	define DM1_LO_XOR	(0x6 << DM1_LO_SHIFT)
-#	define DM1_LO_OR	(0x7 << DM1_LO_SHIFT)
-#	define DM1_LO_NOR	(0x8 << DM1_LO_SHIFT)
-#	define DM1_LO_XNOR	(0x9 << DM1_LO_SHIFT)
-#	define DM1_LO_NDST	(0xa << DM1_LO_SHIFT)
-#	define DM1_LO_ORR	(0xb << DM1_LO_SHIFT)
-#	define DM1_LO_NSRC	(0xc << DM1_LO_SHIFT)
-#	define DM1_LO_ORI	(0xd << DM1_LO_SHIFT)
-#	define DM1_LO_NAND	(0xe << DM1_LO_SHIFT)
-#	define DM1_LO_ONE	(0xf << DM1_LO_SHIFT)
-
+/* The rest of the DM1 planes defines are in newport.h */
 
+#define DM1_DRAWDEPTH_SHIFT	3
+#define DM1_DRAWDEPTH_MASK	NPORT_DMODE1_DDMASK
+#define DM1_DRAWDEPTH		NPORT_DMODE1_DD24 /* An alias? */
+#define DM1_DRAWDEPTH4		NPORT_DMODE1_DD4
+#define DM1_DRAWDEPTH8		NPORT_DMODE1_DD8
+#define DM1_DRAWDEPTH12		NPORT_DMODE1_DD12
+#define DM1_DRAWDEPTH24		NPORT_DMODE1_DD24
+
+#define DM1_DBLSRC		NPORT_DMODE1_DSRC
+#define DM1_YFLIP		NPORT_DMODE1_YFLIP
+#define DM1_RWPACKED		NPORT_DMODE1_RWPCKD
+
+#define DM1_HOSTDEPTH_SHIFT 	8
+#define DM1_HOSTDEPTH_MASK	NPORT_DMODE1_HDMASK
+#define DM1_HOSTDEPTH		NPORT_DMODE1_HD32 /* An alias? */
+#define DM1_HOSTDEPTH4		NPORT_DMODE1_HD4
+#define DM1_HOSTDEPTH8		NPORT_DMODE1_HD8
+#define DM1_HOSTDEPTH12		NPORT_DMODE1_HD12
+#define DM1_HOSTDEPTH32		NPORT_DMODE1_HD32
+
+#define DM1_RWDOUBLE		NPORT_DMODE1_RWDBL
+#define DM1_SWAPENDIAN		NPORT_DMODE1_ESWAP
+
+#define DM1_COLORCOMPARE_SHIFT	12
+#define DM1_COLORCOMPARE_MASK	NPORT_DMODE1_CCMASK
+#define DM1_COLORCOMPARE	NPORT_DMODE1_CCMASK
+#define DM1_COLORCOMPLT		NPORT_DMODE1_CCLT
+#define DM1_COLORCOMPEQ		NPORT_DMODE1_CCEQ
+#define DM1_COLORCOMPGT		NPORT_DMODE1_CCGT
+
+#define DM1_RGBMODE		NPORT_DMODE1_RGBMD
+#define DM1_ENDITHER		NPORT_DMODE1_DENAB
+#define DM1_FASTCLEAR		NPORT_DMODE1_FCLR
+#define DM1_ENBLEND		NPORT_DMODE1_BENAB
+
+#define DM1_SF_SHIFT		19
+#define DM1_SF_MASK   		NPORT_DMODE1_SFMASK
+#define DM1_SF			NPORT_DMODE1_SFMASK 
+#define DM1_SF_ZERO		NPORT_DMODE1_SF0
+#define DM1_SF_ONE		NPORT_DMODE1_SF1
+#define DM1_SF_DC		NPORT_DMODE1_SFDC
+#define DM1_SF_MDC		NPORT_DMODE1_SFMDC
+#define DM1_SF_SA		NPORT_DMODE1_SFSA
+#define DM1_SF_MSA		NPORT_DMODE1_SFMSA
 
-/*
- * Clipmode register bits
- */
-
-#define SMASK0	BIT(0)
-#define SMASK1	BIT(1)
-#define SMASK2	BIT(2)
-#define SMASK3	BIT(3)
-#define SMASK4	BIT(4)
-#define ALL_SMASKS	31
+#define DM1_DF_SHIFT		22	/* dfactor(2:0)	*/
+#define DM1_DF_MASK		NPORT_DMODE1_DFMASK 
+#define DM1_DF			NPORT_DMODE1_DFMASK 
+#define DM1_DF_ZERO		NPORT_DMODE1_DF0
+#define DM1_DF_ONE		NPORT_DMODE1_DF1
+#define DM1_DF_SC		NPORT_DMODE1_DFSC
+#define DM1_DF_MSC		NPORT_DMODE1_DFMSC
+#define DM1_DF_SA		NPORT_DMODE1_DFSA
+#define DM1_DF_MSA		NPORT_DMODE1_DFMSA
+
+#define DM1_ENBACKBLEND		NPORT_DMODE1_BBENAB
+#define DM1_ENPREFETCH		NPORT_DMODE1_PFENAB
+#define DM1_BLENDALPHA		NPORT_DMODE1_ABLEND
+
+#define DM1_LO_SHIFT		28
+#define DM1_LO			NPORT_DMODE1_LOMASK
+#define DM1_LO_MASK      	NPORT_DMODE1_LOMASK
+#define DM1_LO_ZERO		NPORT_DMODE1_LOZERO
+#define DM1_LO_AND		NPORT_DMODE1_LOAND
+#define DM1_LO_ANDR		NPORT_DMODE1_LOANDR
+#define DM1_LO_SRC		NPORT_DMODE1_LOSRC
+#define DM1_LO_ANDI		NPORT_DMODE1_LOANDI
+#define DM1_LO_DST		NPORT_DMODE1_LODST
+#define DM1_LO_XOR		NPORT_DMODE1_LOXOR
+#define DM1_LO_OR		NPORT_DMODE1_LOOR
+#define DM1_LO_NOR		NPORT_DMODE1_LONOR
+#define DM1_LO_XNOR		NPORT_DMODE1_LOXNOR
+#define DM1_LO_NDST		NPORT_DMODE1_LONDST
+#define DM1_LO_ORR		NPORT_DMODE1_LOORR
+#define DM1_LO_NSRC		NPORT_DMODE1_LONSRC
+#define DM1_LO_ORI		NPORT_DMODE1_LOORI
+#define DM1_LO_NAND		NPORT_DMODE1_LONAND
+#define DM1_LO_ONE		NPORT_DMODE1_LOONE
+
+#define SMASK0			NPORT_CMODE_SM0
+#define SMASK1			NPORT_CMODE_SM1
+#define SMASK2			NPORT_CMODE_SM2
+#define SMASK3			NPORT_CMODE_SM3
+#define SMASK4			NPORT_CMODE_SM4
+#define ALL_SMASKS		0x1f
 
 #define CM_CIDMATCH_SHIFT       9
-#define CM_CIDMATCH_MASK        (0xf << CM_CIDMATCH_SHIFT)
+#define CM_CIDMATCH_MASK        NPORT_CMODE_CMSK
 
-
-/*
- * Status register bits
- */
-
-#define REX3VERSION_MASK 7
-#define GFXBUSY         BIT(3)
-#define BACKBUSY        BIT(4)
-#define VRINT           BIT(5)
-#define VIDEOINT        BIT(6)
+#define REX3VERSION_MASK	NPORT_STAT_VERS
+#define GFXBUSY        		NPORT_STAT_GBUSY
+#define BACKBUSY        	NPORT_STAT_BBUSY
+#define VRINT           	NPORT_STAT_VRINT
+#define VIDEOINT        	NPORT_STAT_VIDINT
 #define GFIFO_LEVEL_SHIFT       7
-#define GFIFO_LEVEL_MASK        (0x3f << GFIFO_LEVEL_SHIFT)
+#define GFIFO_LEVEL_MASK        NPORT_STAT_GLMSK 
 #define BFIFO_LEVEL_SHIFT       13
-#define BFIFO_LEVEL_MASK        (0x1f << BFIFO_LEVEL_SHIFT)
-#define BFIFO_INT        BIT(18)
-#define GFIFO_INT        BIT(19)
-
-
-/*
- * Config register bits
- */
-
-#define GIO32MODE       BIT(0)
-#define BUSWIDTH        BIT(1)
-#define EXTREGXCVR      BIT(2)
-#define BFIFODEPTH_SHIFT        3
-#define BFIFODEPTH_MASK         (0xf << BFIFODEPTH_SHIFT)
-#define BFIFOABOVEINT   BIT(7)
+#define BFIFO_LEVEL_MASK        NPORT_STAT_BLMSK 
+#define BFIFO_INT        	NPORT_STAT_BFIRQ
+#define GFIFO_INT        	NPORT_STAT_GFIRQ
+
+#define GIO32MODE		NPORT_CFG_G32MD 
+#define BUSWIDTH		NPORT_CFG_BWIDTH
+#define EXTREGXCVR		NPORT_CFG_ERCVR 
+#define BFIFODEPTH_SHIFT	3
+#define BFIFODEPTH_MASK		NPORT_CFG_BDMSK
+#define BFIFOABOVEINT		NPORT_CFG_BFAINT
 #define GFIFODEPTH_SHIFT        8
-#define GFIFODEPTH_MASK         (0x1f << GFIFODEPTH_SHIFT)
-#define GFIFOABOVEINT   BIT(13)
-#define TIMEOUT_SHIFT   14
-#define TIMEOUT_MASK    (7 << TIMEOUT_SHIFT)
-#define VREFRESH_SHIFT  17
-#define VREFRESH_MASK   (0x7 << VREFRESH_SHIFT)
-#define FB_TYPE         BIT(20)
-
-/*
- * Display Control Bus (DCB) macros
- */
+#define GFIFODEPTH_MASK		NPORT_CFG_GDMSK 
+#define GFIFOABOVEINT		NPORT_CFG_GFAINT
+#define TIMEOUT_SHIFT		14
+#define TIMEOUT_MASK		NPORT_CFG_TOMSK 
+#define VREFRESH_SHIFT		17
+#define VREFRESH_MASK		NPORT_CFG_VRMSK
+#define FB_TYPE			NPORT_CFG_FBTYP
+
+#define DCB_DATAWIDTH_MASK	(0x3)
+
+#define DCB_CRS_MASK		(0x7 << DCB_CRS_SHIFT)
+#define DCB_ADDR_MASK		(0xf << DCB_ADDR_SHIFT)
+#define DCB_CSWIDTH_MASK	(0x1f << DCB_CSWIDTH_SHIFT)
+#define DCB_CSHOLD_MASK		(0x1f << DCB_CSHOLD_SHIFT)
+#define DCB_CSSETUP_MASK	(0x1f << DCB_CSSETUP_SHIFT)
 
-#define DCB_DATAWIDTH_MASK  (0x3)
-#define DCB_ENDATAPACK      BIT(2)
-#define DCB_ENCRSINC        BIT(3)
-#define DCB_CRS_SHIFT    4
-#define DCB_CRS_MASK     (0x7 << DCB_CRS_SHIFT)
-#define DCB_ADDR_SHIFT   7
-#define DCB_ADDR_MASK    (0xf << DCB_ADDR_SHIFT)
-#define DCB_ENSYNCACK       BIT(11)
-#define DCB_ENASYNCACK      BIT(12)
-#define DCB_CSWIDTH_SHIFT   13
-#define DCB_CSWIDTH_MASK    (0x1f << CSWIDTH_SHIFT)
-#define DCB_CSHOLD_SHIFT    18
-#define DCB_CSHOLD_MASK     (0x1f << CSHOLD_SHIFT)
-#define DCB_CSSETUP_SHIFT   23
-#define DCB_CSSETUP_MASK    (0x1f << CSSETUP_SHIFT)
-#define DCB_SWAPENDIAN      BIT(28)
+#define DCB_SWAPENDIAN		(1 << 28)
 
-
-/*
- * Some values for DCBMODE fields
- */
-#define DCB_DATAWIDTH_4		0x0
-#define DCB_DATAWIDTH_1		0x1
-#define DCB_DATAWIDTH_2		0x2
-#define DCB_DATAWIDTH_3		0x3
-
-
-/*
- * DCB_ADDR values to select the various dcb slave devices
- */
-#define DCB_VC2          (0 << DCB_ADDR_SHIFT)
-#define DCB_CMAP_ALL     (1 << DCB_ADDR_SHIFT)
-#define DCB_CMAP0        (2 << DCB_ADDR_SHIFT)
-#define DCB_CMAP1        (3 << DCB_ADDR_SHIFT)
-#define DCB_XMAP_ALL     (4 << DCB_ADDR_SHIFT)
-#define DCB_XMAP0        (5 << DCB_ADDR_SHIFT)
-#define DCB_XMAP1        (6 << DCB_ADDR_SHIFT)
-#define DCB_BT445        (7 << DCB_ADDR_SHIFT)
-#define DCB_VCC1         (8 << DCB_ADDR_SHIFT)
-#define DCB_VAB1         (9 << DCB_ADDR_SHIFT)
-#define DCB_LG3_BDVERS0      (10 << DCB_ADDR_SHIFT)
-#define DCB_LG3_ICS1562      (11 << DCB_ADDR_SHIFT)
-#define DCB_RESERVED     (15 << DCB_ADDR_SHIFT)
-
-/*
- * New DCB Addresses which are used in (new) Indigo2 Video and Galileo 1.5
- * since these boards have to work with Mardi Gras also. Yet, these
- * are not necessarily the MGRAS address, these translate to the Mardi Gras
- * addresses when the lower 2 bits are swapped (which will happen on 
- * the Newport to new video board flex cable).
- */
-#define DCB_VAB1_NEW     (9 << DCB_ADDR_SHIFT)
-/*
- * While the Presenter is currently using address 12 and
- * conflicting with the CC1, it has been changed for Mardi Gras
- * To use the new video boards with Newport (an unreleased product)
- * the presenter probe must be disabled by changing the presenter
- * DCB address in gfx/kern/sys/pcd.h (and possibly
- * lotus/stand/arcs/lib/libsk/graphics/NEWPORT/pcd.h), so 
- * it is probed at address 11.  This will of course not work with
- * the presenter card but it will allow you to test new video
- * boards will Newport
- */
-
-#define DCB_VCC1_NEW     (12 << DCB_ADDR_SHIFT)
-/*#define DCB_VCC1_NEW     (8 << DCB_ADDR_SHIFT)*/
-
-/*
- * Addresses being used for Galileo 1.5.
- */
-#define DCB_VCC1_GAL     (8 << DCB_ADDR_SHIFT) /* was 12 and will return */
-#define DCB_VAB1_GAL     (9 << DCB_ADDR_SHIFT)
-#define DCB_TMI_CSC      (13 << DCB_ADDR_SHIFT)
-#define DCB_GAL          (14 << DCB_ADDR_SHIFT)
-
-/*
- * LG3 - (Newport for Fullhouse) board defines
- */
-/* Version 0 register */
-#define LG3_VC2_UNRESET BIT(0)
-#define	LG3_GFX_UNRESET	BIT(1)
-#define LG3_PLL_UNRESET BIT(2)
-#define LG3_DLHD_MASTER BIT(3)
-
-#define LG3_BDVERS_PROTOCOL ((2 << DCB_CSWIDTH_SHIFT) | (1 << DCB_CSHOLD_SHIFT) | (1 << DCB_CSSETUP_SHIFT))
-
-#define lg3BdVersGet(rex3, data)			 		\
-        rex3->set.dcbmode = DCB_LG3_BDVERS0 | \
-		LG3_BDVERS_PROTOCOL | DCB_DATAWIDTH_1 ;			\
-        data = rex3->set.dcbdata0.bybyte.b3
-
-#define lg3BdVersSet(rex3, data)			 		\
-        rex3->set.dcbmode = DCB_LG3_BDVERS0 | \
-		LG3_BDVERS_PROTOCOL | DCB_DATAWIDTH_1 ;		\
-	rex3->set.dcbdata0.bybyte.b3 = (data)
-
-#define Ics1562Set(rex3, data)			 		\
-        rex3->set.dcbmode = DCB_LG3_ICS1562 | LG3_BDVERS_PROTOCOL | DCB_DATAWIDTH_1 ; \
-	rex3->set.dcbdata0.bybyte.b3 = (data)
-
-#define	LG3_BD_001	0x7
-#define	LG3_BD_002	0x0
-/*
- * Lsmode register bits
- */
-#define LSRCOUNT_SHIFT  0
-#define LSRCOUNT_MASK   (0xff << LSRCOUNT_SHIFT)
-#define LSREPEAT_SHIFT  8
-#define LSREPEAT_MASK   (0xff << LSREPEAT_SHIFT)
-#define LSRCNTSAVE_SHIFT        16
-#define LSRCNTSAVE_MASK (0xff << LSRCNTSAVE_SHIFT)
-#define LSLENGTH_SHIFT  24
-#define LSLENGTH_MASK   (0xf << LSLENGTH_SHIFT)
-
-#if	defined ( _KERNEL ) && defined ( REX3_RUNTIME_REV_CHECK )
-
-extern void _newport_poll_status (register struct rex3chip *, register int);
-
-#define REX3WAIT(rex3)  _newport_poll_status (rex3, GFXBUSY)
-#define BFIFOWAIT(rex3)  _newport_poll_status (rex3, BACKBUSY)
-
-#else
-
-/* XXX  When we drop support for rex rev b,
- * change status to ustatus in the macros below.
- */
 #define REX3WAIT(rex3)  while ((rex3)->p1.set.status & GFXBUSY)
 #define BFIFOWAIT(rex3)  while ((rex3)->p1.set.status & BACKBUSY)
 
-#endif
-
-/*
- * Legal GIO bus addresses for Newport graphics boards.
- */
 #define REX3_GIO_ADDR_0         0x1f0f0000
 #define REX3_GIO_ADDR_1         0x1f4f0000
 #define REX3_GIO_ADDR_2         0x1f8f0000
 #define REX3_GIO_ADDR_3         0x1fcf0000
 
-#define NG1_XSIZE       1280    /* screen size in x */
-#define NG1_YSIZE       1024    /* screen size in y */
+#define NG1_XSIZE		1280
+#define NG1_YSIZE		1024
 
-/*
- * XXX Correct values TBD.  Depends on video timing
- */
-#define CURSOR_XOFF 29
-#define CURSOR_YOFF 31
-
-#ifdef _STANDALONE
-struct rex3chip;
-struct ng1_info;
-void Ng1RegisterInit(struct rex3chip *, struct ng1_info *);
-extern int ng1checkboard(void);
-extern void vc2LoadSRAM(struct rex3chip *, unsigned short *,
-		unsigned int , unsigned int);
 #endif
-
-#endif /* __SYS_NG1HW_H__ */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/nile4.h linux/include/asm-mips/nile4.h
--- v2.3.47/linux/include/asm-mips/nile4.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/nile4.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,310 @@
+/*
+ *  asm-mips/nile4.h -- NEC Vrc-5074 Nile 4 definitions
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Suprastructure Center Europe (SUPC-E), Brussels
+ *
+ *  This file is based on the following documentation:
+ *
+ *	NEC Vrc 5074 System Controller Data Sheet, June 1998
+ *
+ *  $Id: nile4.h,v 1.1 2000/01/26 00:07:45 ralf Exp $
+ */
+
+#include <asm/addrspace.h>
+
+
+#define NILE4_BASE		0xbfa00000
+#define NILE4_SIZE		0x00200000		/* 2 MB */
+
+
+    /*
+     *  Physical Device Address Registers (PDARs)
+     */
+
+#define NILE4_SDRAM0	0x0000	/* SDRAM Bank 0 [R/W] */
+#define NILE4_SDRAM1	0x0008	/* SDRAM Bank 1 [R/W] */
+#define NILE4_DCS2	0x0010	/* Device Chip-Select 2 [R/W] */
+#define NILE4_DCS3	0x0018	/* Device Chip-Select 3 [R/W] */
+#define NILE4_DCS4	0x0020	/* Device Chip-Select 4 [R/W] */
+#define NILE4_DCS5	0x0028	/* Device Chip-Select 5 [R/W] */
+#define NILE4_DCS6	0x0030	/* Device Chip-Select 6 [R/W] */
+#define NILE4_DCS7	0x0038	/* Device Chip-Select 7 [R/W] */
+#define NILE4_DCS8	0x0040	/* Device Chip-Select 8 [R/W] */
+#define NILE4_PCIW0	0x0060	/* PCI Address Window 0 [R/W] */
+#define NILE4_PCIW1	0x0068	/* PCI Address Window 1 [R/W] */
+#define NILE4_INTCS	0x0070	/* Controller Internal Registers and Devices */
+				/* [R/W] */
+#define NILE4_BOOTCS	0x0078	/* Boot ROM Chip-Select [R/W] */
+
+
+    /*
+     *  CPU Interface Registers
+     */
+
+#define NILE4_CPUSTAT	0x0080	/* CPU Status [R/W] */
+#define NILE4_INTCTRL	0x0088	/* Interrupt Control [R/W] */
+#define NILE4_INTSTAT0	0x0090	/* Interrupt Status 0 [R] */
+#define NILE4_INTSTAT1	0x0098	/* Interrupt Status 1 and CPU Interrupt */
+				/* Enable [R/W] */
+#define NILE4_INTCLR	0x00A0	/* Interrupt Clear [R/W] */
+#define NILE4_INTPPES	0x00A8	/* PCI Interrupt Control [R/W] */
+
+
+    /*
+     *  Memory-Interface Registers
+     */
+
+#define NILE4_MEMCTRL	0x00C0	/* Memory Control */
+#define NILE4_ACSTIME	0x00C8	/* Memory Access Timing [R/W] */
+#define NILE4_CHKERR	0x00D0	/* Memory Check Error Status [R] */
+
+
+    /*
+     *  PCI-Bus Registers
+     */
+
+#define NILE4_PCICTRL	0x00E0	/* PCI Control [R/W] */
+#define NILE4_PCIARB	0x00E8	/* PCI Arbiter [R/W] */
+#define NILE4_PCIINIT0	0x00F0	/* PCI Master (Initiator) 0 [R/W] */
+#define NILE4_PCIINIT1	0x00F8	/* PCI Master (Initiator) 1 [R/W] */
+#define NILE4_PCIERR	0x00B8	/* PCI Error [R/W] */
+
+
+    /*
+     *  Local-Bus Registers
+     */
+
+#define NILE4_LCNFG	0x0100	/* Local Bus Configuration [R/W] */
+#define NILE4_LCST2	0x0110	/* Local Bus Chip-Select Timing 2 [R/W] */
+#define NILE4_LCST3	0x0118	/* Local Bus Chip-Select Timing 3 [R/W] */
+#define NILE4_LCST4	0x0120	/* Local Bus Chip-Select Timing 4 [R/W] */
+#define NILE4_LCST5	0x0128	/* Local Bus Chip-Select Timing 5 [R/W] */
+#define NILE4_LCST6	0x0130	/* Local Bus Chip-Select Timing 6 [R/W] */
+#define NILE4_LCST7	0x0138	/* Local Bus Chip-Select Timing 7 [R/W] */
+#define NILE4_LCST8	0x0140	/* Local Bus Chip-Select Timing 8 [R/W] */
+#define NILE4_DCSFN	0x0150	/* Device Chip-Select Muxing and Output */
+				/* Enables [R/W] */
+#define NILE4_DCSIO	0x0158	/* Device Chip-Selects As I/O Bits [R/W] */
+#define NILE4_BCST	0x0178	/* Local Boot Chip-Select Timing [R/W] */
+
+
+    /*
+     *  DMA Registers
+     */
+
+#define NILE4_DMACTRL0	0x0180	/* DMA Control 0 [R/W] */
+#define NILE4_DMASRCA0	0x0188	/* DMA Source Address 0 [R/W] */
+#define NILE4_DMADESA0	0x0190	/* DMA Destination Address 0 [R/W] */
+#define NILE4_DMACTRL1	0x0198	/* DMA Control 1 [R/W] */
+#define NILE4_DMASRCA1	0x01A0	/* DMA Source Address 1 [R/W] */
+#define NILE4_DMADESA1	0x01A8	/* DMA Destination Address 1 [R/W] */
+
+
+    /*
+     *  Timer Registers
+     */
+
+#define NILE4_T0CTRL	0x01C0	/* SDRAM Refresh Control [R/W] */
+#define NILE4_T0CNTR	0x01C8	/* SDRAM Refresh Counter [R/W] */
+#define NILE4_T1CTRL	0x01D0	/* CPU-Bus Read Time-Out Control [R/W] */
+#define NILE4_T1CNTR	0x01D8	/* CPU-Bus Read Time-Out Counter [R/W] */
+#define NILE4_T2CTRL	0x01E0	/* General-Purpose Timer Control [R/W] */
+#define NILE4_T2CNTR	0x01E8	/* General-Purpose Timer Counter [R/W] */
+#define NILE4_T3CTRL	0x01F0	/* Watchdog Timer Control [R/W] */
+#define NILE4_T3CNTR	0x01F8	/* Watchdog Timer Counter [R/W] */
+
+
+    /*
+     *  PCI Configuration Space Registers
+     */
+
+#define NILE4_PCI_BASE	0x0200
+
+#define NILE4_VID	0x0200	/* PCI Vendor ID [R] */
+#define NILE4_DID	0x0202	/* PCI Device ID [R] */
+#define NILE4_PCICMD	0x0204	/* PCI Command [R/W] */
+#define NILE4_PCISTS	0x0206	/* PCI Status [R/W] */
+#define NILE4_REVID	0x0208	/* PCI Revision ID [R] */
+#define NILE4_CLASS	0x0209	/* PCI Class Code [R] */
+#define NILE4_CLSIZ	0x020C	/* PCI Cache Line Size [R/W] */
+#define NILE4_MLTIM	0x020D	/* PCI Latency Timer [R/W] */
+#define NILE4_HTYPE	0x020E	/* PCI Header Type [R] */
+#define NILE4_BIST	0x020F	/* BIST [R] (unimplemented) */
+#define NILE4_BARC	0x0210	/* PCI Base Address Register Control [R/W] */
+#define NILE4_BAR0	0x0218	/* PCI Base Address Register 0 [R/W] */
+#define NILE4_BAR1	0x0220	/* PCI Base Address Register 1 [R/W] */
+#define NILE4_CIS	0x0228	/* PCI Cardbus CIS Pointer [R] */
+				/* (unimplemented) */
+#define NILE4_SSVID	0x022C	/* PCI Sub-System Vendor ID [R/W] */
+#define NILE4_SSID	0x022E	/* PCI Sub-System ID [R/W] */
+#define NILE4_ROM	0x0230	/* Expansion ROM Base Address [R] */
+				/* (unimplemented) */
+#define NILE4_INTLIN	0x023C	/* PCI Interrupt Line [R/W] */
+#define NILE4_INTPIN	0x023D	/* PCI Interrupt Pin [R] */
+#define NILE4_MINGNT	0x023E	/* PCI Min_Gnt [R] (unimplemented) */
+#define NILE4_MAXLAT	0x023F	/* PCI Max_Lat [R] (unimplemented) */
+#define NILE4_BAR2	0x0240	/* PCI Base Address Register 2 [R/W] */
+#define NILE4_BAR3	0x0248	/* PCI Base Address Register 3 [R/W] */
+#define NILE4_BAR4	0x0250	/* PCI Base Address Register 4 [R/W] */
+#define NILE4_BAR5	0x0258	/* PCI Base Address Register 5 [R/W] */
+#define NILE4_BAR6	0x0260	/* PCI Base Address Register 6 [R/W] */
+#define NILE4_BAR7	0x0268	/* PCI Base Address Register 7 [R/W] */
+#define NILE4_BAR8	0x0270	/* PCI Base Address Register 8 [R/W] */
+#define NILE4_BARB	0x0278	/* PCI Base Address Register BOOT [R/W] */
+
+
+    /*
+     *  Serial-Port Registers
+     */
+
+#define NILE4_UART_BASE	0x0300
+
+#define NILE4_UARTRBR	0x0300	/* UART Receiver Data Buffer [R] */
+#define NILE4_UARTTHR	0x0300	/* UART Transmitter Data Holding [W] */
+#define NILE4_UARTIER	0x0308	/* UART Interrupt Enable [R/W] */
+#define NILE4_UARTDLL	0x0300	/* UART Divisor Latch LSB [R/W] */
+#define NILE4_UARTDLM	0x0308	/* UART Divisor Latch MSB [R/W] */
+#define NILE4_UARTIIR	0x0310	/* UART Interrupt ID [R] */
+#define NILE4_UARTFCR	0x0310	/* UART FIFO Control [W] */
+#define NILE4_UARTLCR	0x0318	/* UART Line Control [R/W] */
+#define NILE4_UARTMCR	0x0320	/* UART Modem Control [R/W] */
+#define NILE4_UARTLSR	0x0328	/* UART Line Status [R/W] */
+#define NILE4_UARTMSR	0x0330	/* UART Modem Status [R/W] */
+#define NILE4_UARTSCR	0x0338	/* UART Scratch [R/W] */
+
+#define NILE4_UART_BASE_BAUD	520833	/* 100 MHz / 12 / 16 */
+
+
+    /*
+     *  Interrupt Lines
+     */
+
+#define NILE4_INT_CPCE	0	/* CPU-Interface Parity-Error Interrupt */
+#define NILE4_INT_CNTD	1	/* CPU No-Target Decode Interrupt */
+#define NILE4_INT_MCE	2	/* Memory-Check Error Interrupt */
+#define NILE4_INT_DMA	3	/* DMA Controller Interrupt */
+#define NILE4_INT_UART	4	/* UART Interrupt */
+#define NILE4_INT_WDOG	5	/* Watchdog Timer Interrupt */
+#define NILE4_INT_GPT	6	/* General-Purpose Timer Interrupt */
+#define NILE4_INT_LBRTD	7	/* Local-Bus Ready Timer Interrupt */
+#define NILE4_INT_INTA	8	/* PCI Interrupt Signal INTA# */
+#define NILE4_INT_INTB	9	/* PCI Interrupt Signal INTB# */
+#define NILE4_INT_INTC	10	/* PCI Interrupt Signal INTC# */
+#define NILE4_INT_INTD	11	/* PCI Interrupt Signal INTD# */
+#define NILE4_INT_INTE	12	/* PCI Interrupt Signal INTE# (ISA cascade) */
+#define NILE4_INT_RESV	13	/* Reserved */
+#define NILE4_INT_PCIS	14	/* PCI SERR# Interrupt */
+#define NILE4_INT_PCIE	15	/* PCI Internal Error Interrupt */
+
+
+    /*
+     *  Nile 4 Register Access
+     */
+
+static inline void nile4_sync(void)
+{
+    volatile u32 *p = (volatile u32 *)0xbfc00000;
+    (void)(*p);
+}
+
+static inline void nile4_out32(u32 offset, u32 val)
+{
+    *(volatile u32 *)(NILE4_BASE+offset) = val;
+    nile4_sync();
+}
+
+static inline u32 nile4_in32(u32 offset)
+{
+    u32 val = *(volatile u32 *)(NILE4_BASE+offset);
+    nile4_sync();
+    return val;
+}
+
+static inline void nile4_out16(u32 offset, u16 val)
+{
+    *(volatile u16 *)(NILE4_BASE+offset) = val;
+    nile4_sync();
+}
+
+static inline u16 nile4_in16(u32 offset)
+{
+    u16 val = *(volatile u16 *)(NILE4_BASE+offset);
+    nile4_sync();
+    return val;
+}
+
+static inline void nile4_out8(u32 offset, u8 val)
+{
+    *(volatile u8 *)(NILE4_BASE+offset) = val;
+    nile4_sync();
+}
+
+static inline u8 nile4_in8(u32 offset)
+{
+    u8 val = *(volatile u8 *)(NILE4_BASE+offset);
+    nile4_sync();
+    return val;
+}
+
+
+    /*
+     *  Physical Device Address Registers
+     */
+
+extern void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width,
+			   int on_memory_bus, int visible);
+
+
+    /*
+     *  PCI Master Registers
+     */
+
+#define NILE4_PCICMD_IACK	0	/* PCI Interrupt Acknowledge */
+#define NILE4_PCICMD_IO		1	/* PCI I/O Space */
+#define NILE4_PCICMD_MEM	3	/* PCI Memory Space */
+#define NILE4_PCICMD_CFG	5	/* PCI Configuration Space */
+
+
+    /*
+     *  PCI Address Spaces
+     *
+     *  Note that these are multiplexed using PCIINIT[01]!
+     */
+
+#define NILE4_PCI_IO_BASE	0xa6000000
+#define NILE4_PCI_MEM_BASE	0xa8000000
+#define NILE4_PCI_CFG_BASE	NILE4_PCI_MEM_BASE
+#define NILE4_PCI_IACK_BASE	NILE4_PCI_IO_BASE
+
+
+extern void nile4_set_pmr(u32 pmr, u32 type, u32 addr);
+
+
+    /*
+     *  Interrupt Programming
+     */
+
+#define NUM_I8259_INTERRUPTS	16
+#define NUM_NILE4_INTERRUPTS	16
+
+#define IRQ_I8259_CASCADE	NILE4_INT_INTE
+#define is_i8259_irq(irq)	((irq) < NUM_I8259_INTERRUPTS)
+#define nile4_to_irq(n)		((n)+NUM_I8259_INTERRUPTS)
+#define irq_to_nile4(n)		((n)-NUM_I8259_INTERRUPTS)
+
+extern void nile4_map_irq(int nile4_irq, int cpu_irq);
+extern void nile4_map_irq_all(int cpu_irq);
+extern void nile4_enable_irq(int nile4_irq);
+extern void nile4_disable_irq(int nile4_irq);
+extern void nile4_disable_irq_all(void);
+extern u16 nile4_get_irq_stat(int cpu_irq);
+extern void nile4_enable_irq_output(int cpu_irq);
+extern void nile4_disable_irq_output(int cpu_irq);
+extern void nile4_set_pci_irq_polarity(int pci_irq, int high);
+extern void nile4_set_pci_irq_level_or_edge(int pci_irq, int level);
+extern void nile4_clear_irq(int nile4_irq);
+extern void nile4_clear_irq_mask(u32 mask);
+extern u8 nile4_i8259_iack(void);
+extern void nile4_dump_irq_status(void);	/* Debug */
+
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/offset.h linux/include/asm-mips/offset.h
--- v2.3.47/linux/include/asm-mips/offset.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/offset.h	Thu Feb 24 22:52:30 2000
@@ -49,53 +49,50 @@
 #define TASK_FLAGS         4
 #define TASK_SIGPENDING    8
 #define TASK_NEED_RESCHED  20
-#define TASK_COUNTER       24
-#define TASK_PRIORITY      28
-#define TASK_MM            928
+#define TASK_COUNTER       32
+#define TASK_PRIORITY      36
+#define TASK_MM            44
+#define TASK_STRUCT_SIZE   904
 
 /* MIPS specific thread_struct offsets. */
-#define THREAD_REG16   568
-#define THREAD_REG17   572
-#define THREAD_REG18   576
-#define THREAD_REG19   580
-#define THREAD_REG20   584
-#define THREAD_REG21   588
-#define THREAD_REG22   592
-#define THREAD_REG23   596
-#define THREAD_REG29   600
-#define THREAD_REG30   604
-#define THREAD_REG31   608
-#define THREAD_STATUS  612
-#define THREAD_FPU     616
-#define THREAD_BVADDR  880
-#define THREAD_BUADDR  884
-#define THREAD_ECODE   888
-#define THREAD_TRAPNO  892
-#define THREAD_PGDIR   896
-#define THREAD_MFLAGS  900
-#define THREAD_CURDS   904
-#define THREAD_TRAMP   908
-#define THREAD_OLDCTX  912
+#define THREAD_REG16   584
+#define THREAD_REG17   588
+#define THREAD_REG18   592
+#define THREAD_REG19   596
+#define THREAD_REG20   600
+#define THREAD_REG21   604
+#define THREAD_REG22   608
+#define THREAD_REG23   612
+#define THREAD_REG29   616
+#define THREAD_REG30   620
+#define THREAD_REG31   624
+#define THREAD_STATUS  628
+#define THREAD_FPU     632
+#define THREAD_BVADDR  768
+#define THREAD_BUADDR  772
+#define THREAD_ECODE   776
+#define THREAD_TRAPNO  780
+#define THREAD_MFLAGS  784
+#define THREAD_CURDS   788
+#define THREAD_TRAMP   792
+#define THREAD_OLDCTX  796
 
 /* Linux mm_struct offsets. */
-#define MM_COUNT      16
+#define MM_USERS      16
 #define MM_PGD        12
-#define MM_CONTEXT    52
+#define MM_CONTEXT    64
 
 /* Linux sigcontext offsets. */
-#define SC_REGMASK    0
-#define SC_STATUS     4
-#define SC_PC         8
 #define SC_REGS       16
 #define SC_FPREGS     272
+#define SC_MDHI       544
+#define SC_MDLO       552
+#define SC_PC         8
+#define SC_STATUS     4
 #define SC_OWNEDFP    528
 #define SC_FPC_CSR    532
 #define SC_FPC_EIR    536
-#define SC_SSFLAGS    540
-#define SC_MDHI       544
-#define SC_MDLO       552
 #define SC_CAUSE      560
 #define SC_BADVADDR   564
-#define SC_SIGSET     568
 
 #endif /* !(_MIPS_OFFSET_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/page.h linux/include/asm-mips/page.h
--- v2.3.47/linux/include/asm-mips/page.h	Wed Feb 16 17:03:52 2000
+++ linux/include/asm-mips/page.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: page.h,v 1.6 1999/01/04 16:09:24 ralf Exp $
+/* $Id: page.h,v 1.9 2000/02/24 00:13:19 ralf Exp $
  *
  * Definitions for page handling
  *
@@ -6,10 +6,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 - 1998 by Ralf Baechle
+ * Copyright (C) 1994 - 1999 by Ralf Baechle
  */
-#ifndef __ASM_MIPS_PAGE_H
-#define __ASM_MIPS_PAGE_H
+#ifndef __ASM_PAGE_H
+#define __ASM_PAGE_H
 
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT	12
@@ -18,14 +18,17 @@
 
 #ifdef __KERNEL__
 
-#define STRICT_MM_TYPECHECKS
-
 #ifndef _LANGUAGE_ASSEMBLY
 
-extern void (*clear_page)(unsigned long page);
-extern void (*copy_page)(unsigned long to, unsigned long from);
+#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
+#define PAGE_BUG(page) do {  BUG(); } while (0)
+
+extern void (*_clear_page)(void * page);
+extern void (*_copy_page)(void * to, void * from);
+
+#define clear_page(page)	_clear_page(page)
+#define copy_page(to, from)	_copy_page(to, from)
 
-#ifdef STRICT_MM_TYPECHECKS
 /*
  * These are used to make use of C type-checking..
  */
@@ -44,27 +47,6 @@
 #define __pgd(x)	((pgd_t) { (x) } )
 #define __pgprot(x)	((pgprot_t) { (x) } )
 
-#else /* !defined (STRICT_MM_TYPECHECKS) */
-/*
- * .. while these make it easier on the compiler
- */
-typedef unsigned long pte_t;
-typedef unsigned long pmd_t;
-typedef unsigned long pgd_t;
-typedef unsigned long pgprot_t;
-
-#define pte_val(x)	(x)
-#define pmd_val(x)	(x)
-#define pgd_val(x)	(x)
-#define pgprot_val(x)	(x)
-
-#define __pte(x)	(x)
-#define __pmd(x)	(x)
-#define __pgd(x)	(x)
-#define __pgprot(x)	(x)
-
-#endif /* !defined (STRICT_MM_TYPECHECKS) */
-
 /* Pure 2^n version of get_order */
 extern __inline__ int get_order(unsigned long size)
 {
@@ -95,4 +77,4 @@
 
 #endif /* defined (__KERNEL__) */
 
-#endif /* __ASM_MIPS_PAGE_H */
+#endif /* __ASM_PAGE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/param.h linux/include/asm-mips/param.h
--- v2.3.47/linux/include/asm-mips/param.h	Tue Jan 17 22:54:13 1995
+++ linux/include/asm-mips/param.h	Thu Feb 24 22:52:30 2000
@@ -2,7 +2,35 @@
 #define __ASM_MIPS_PARAM_H
 
 #ifndef HZ
-#define HZ 100
+
+#include <linux/config.h>
+
+#ifdef CONFIG_DECSTATION
+   /*
+    * log2(HZ), change this here if you want another
+    * HZ value. This is also used in dec_time_init.
+    * Minimum is 1, Maximum is 15.
+    */
+#  define LOG_2_HZ 7
+#  define HZ (1 << LOG_2_HZ)
+   /*
+    * Ye olde division-by-multiplication trick.
+    *
+    * This works only if 100 / HZ <= 1
+    */
+#  define QUOTIENT ((1UL << (32 - LOG_2_HZ)) * 100)
+#  define HZ_TO_STD(a)                            \
+   ({ int __res;                                  \
+        __asm__(                                  \
+           "multu\t%0,%2\n\t"			  \
+           "mfhi\t%0"				  \
+        : "=r" (__res): "0" (a), "r" (QUOTIENT)); \
+        __res;})
+#else
+#  define HZ 100
+#  define HZ_TO_STD(a) (a)
+#endif
+
 #endif
 
 #define EXEC_PAGESIZE	4096
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/parport.h linux/include/asm-mips/parport.h
--- v2.3.47/linux/include/asm-mips/parport.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/parport.h	Sat Feb 26 20:34:34 2000
@@ -0,0 +1,61 @@
+/* $Id: parport.h,v 1.2 2000/02/18 00:24:48 ralf Exp $
+ *
+ * parport.h: ia32-specific parport initialisation
+ *
+ * Copyright (C) 1999  Tim Waugh <tim@cyberelk.demon.co.uk>
+ *
+ * This file should only be included by drivers/parport/parport_pc.c.
+ */
+#ifndef _ASM_PARPORT_H
+#define _ASM_PARPORT_H 1
+
+#include <linux/config.h>
+
+/* Maximum number of ports to support.  It is useless to set this greater
+   than PARPORT_MAX (in <linux/parport.h>).  */
+#define PARPORT_PC_MAX_PORTS  8
+
+/* If parport_cs (PCMCIA) is managing ports for us, we'll need the
+ * probing routines forever; otherwise we can lose them at boot time. */
+#ifdef CONFIG_PARPORT_PC_PCMCIA
+#define __maybe_initdata
+#define __maybe_init
+#else
+#define __maybe_initdata __initdata
+#define __maybe_init __init
+#endif
+
+static int __maybe_init parport_pc_init_pci(int irq, int dma);
+
+static int user_specified __maybe_initdata = 0;
+int __init
+parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
+{
+	int count = 0, i = 0;
+
+	if (io && *io) {
+		/* Only probe the ports we were given. */
+		user_specified = 1;
+		do {
+			if (!*io_hi) *io_hi = 0x400 + *io;
+			if (parport_pc_probe_port(*(io++), *(io_hi++),
+						  *(irq++), *(dma++), NULL))
+				count++;
+		} while (*io && (++i < PARPORT_PC_MAX_PORTS));
+	} else {
+		count += parport_pc_init_superio ();
+
+		/* Probe all the likely ports. */
+		if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL))
+			count++;
+		if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0], NULL))
+			count++;
+		if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0], NULL))
+			count++;
+		count += parport_pc_init_pci (irq[0], dma[0]);
+	}
+
+        return count;
+}
+
+#endif /* !(_ASM_PARPORT_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/pci.h linux/include/asm-mips/pci.h
--- v2.3.47/linux/include/asm-mips/pci.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/pci.h	Thu Feb 24 22:52:30 2000
@@ -1,42 +1,199 @@
-/* $Id: pci.h,v 1.4 1998/05/08 01:44:30 ralf Exp $
+/* $Id: pci.h,v 1.9 2000/02/24 00:13:19 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
+ */
+#ifndef _ASM_PCI_H
+#define _ASM_PCI_H
+
+/* Can be used to override the logic in pci_scan_bus for skipping
+   already-configured bus numbers - to be used for buggy BIOSes
+   or architectures with incomplete PCI setup by the loader */
+
+#define pcibios_assign_all_busses()	0
+
+#define PCIBIOS_MIN_IO		0x1000
+#define PCIBIOS_MIN_MEM		0x10000000
+
+#ifdef __KERNEL__
+
+/*
+ * Dynamic DMA mapping stuff.
+ * MIPS has everything mapped statically.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include <asm/io.h>
+
+struct pci_dev;
+
+/*
+ * Allocate and map kernel buffer using consistent mode DMA for a device.
+ * hwdev should be valid struct pci_dev pointer for PCI devices,
+ * NULL for PCI-like buses (ISA, EISA).
+ * Returns non-NULL cpu-view pointer to the buffer if successful and
+ * sets *dma_addrp to the pci side dma address as well, else *dma_addrp
+ * is undefined.
+ */
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+				  dma_addr_t *dma_handle);
+
+/*
+ * Free and unmap a consistent DMA buffer.
+ * cpu_addr is what was returned from pci_alloc_consistent,
+ * size must be the same as what as passed into pci_alloc_consistent,
+ * and likewise dma_addr must be the same as what *dma_addrp was set to.
+ *
+ * References to the memory and mappings associated with cpu_addr/dma_addr
+ * past this call are illegal.
+ */
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+				void *vaddr, dma_addr_t dma_handle);
+
+/*
+ * Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+					size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	dma_cache_wback_inv((unsigned long)ptr, size);
+
+	return virt_to_bus(ptr);
+}
+
+/*
+ * Unmap a single streaming mode DMA translation.  The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call.  All
+ * other usages are undefined.
  *
- * Declarations for the MIPS specific implementation of the PCI BIOS32 services.
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
  */
-#ifndef __ASM_MIPS_PCI_H
-#define __ASM_MIPS_PCI_H
+extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+				    size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/* Nothing to do */
+}
 
-struct pci_ops {
-	void (*pcibios_fixup) (void);
-	int (*pcibios_read_config_byte) (unsigned char bus,
-	                                 unsigned char dev_fn,
-	                                 unsigned char where,
-	                                 unsigned char *val);
-	int (*pcibios_read_config_word) (unsigned char bus,
-	                                 unsigned char dev_fn,
-	                                 unsigned char where,
-	                                 unsigned short *val);
-	int (*pcibios_read_config_dword) (unsigned char bus,
-	                                  unsigned char dev_fn,
-	                                  unsigned char where,
-	                                  unsigned int *val);
-	int (*pcibios_write_config_byte) (unsigned char bus,
-	                                  unsigned char dev_fn,
-	                                  unsigned char where,
-	                                  unsigned char val);
-	int (*pcibios_write_config_word) (unsigned char bus,
-	                                  unsigned char dev_fn,
-	                                  unsigned char where,
-	                                  unsigned short val);
-	int (*pcibios_write_config_dword) (unsigned char bus,
-	                                   unsigned char dev_fn,
-	                                   unsigned char where,
-	                                   unsigned int val);
-};
+/*
+ * Map a set of buffers described by scatterlist in streaming
+ * mode for DMA.  This is the scather-gather version of the
+ * above pci_map_single interface.  Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length.  They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ *       DMA address/length pairs than there are SG table elements.
+ *       (for example via virtual mapping capabilities)
+ *       The routine returns the number of addr/length pairs actually
+ *       used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+			     int nents, int direction)
+{
+#ifndef CONFIG_COHERENT_IO
+	int i;
+#endif
+
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+#ifndef CONFIG_COHERENT_IO
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nents; i++, sg++)
+		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
+#endif
+
+	return nents;
+}
+
+/*
+ * Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+				int nents, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/* Nothing to do */
+}
+
+/*
+ * Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so.  At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+extern inline void pci_dma_sync_single(struct pci_dev *hwdev,
+				       dma_addr_t dma_handle,
+				       size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	dma_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), size);
+}
+
+/*
+ * Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+extern inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+				   struct scatterlist *sg,
+				   int nelems, int direction)
+{
+#ifndef CONFIG_COHERENT_IO
+	int i;
+#endif
+
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+#ifndef CONFIG_COHERENT_IO
+	for (i = 0; i < nelems; i++, sg++)
+		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
+#endif
+}
+
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg)	(virt_to_bus((sg)->address))
+#define sg_dma_len(sg)		((sg)->length)
 
-extern struct pci_ops *pci_ops;
+#endif /* __KERNEL__ */
 
-#endif /* __ASM_MIPS_PCI_H */
+#endif /* _ASM_PCI_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/pgalloc.h linux/include/asm-mips/pgalloc.h
--- v2.3.47/linux/include/asm-mips/pgalloc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/pgalloc.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,214 @@
+/* $Id: pgalloc.h,v 1.4 2000/02/24 00:13:19 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 2000 by Ralf Baechle at alii
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PGALLOC_H
+#define _ASM_PGALLOC_H
+
+/* TLB flushing:
+ *
+ *  - flush_tlb_all() flushes all processes TLB entries
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB entries
+ *  - flush_tlb_page(mm, vmaddr) flushes a single page
+ *  - flush_tlb_range(mm, start, end) flushes a range of pages
+ */
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_range(struct mm_struct *mm, unsigned long start,
+			       unsigned long end);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+                                      unsigned long start, unsigned long end)
+{
+	/* Nothing to do on MIPS.  */
+}
+
+
+/*
+ * Allocate and free page tables. The xxx_kernel() versions are
+ * used to allocate a kernel page table - this turns on ASN bits
+ * if any.
+ */
+
+#define pgd_quicklist (current_cpu_data.pgd_quick)
+#define pmd_quicklist ((unsigned long *)0)
+#define pte_quicklist (current_cpu_data.pte_quick)
+#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
+
+extern __inline__ pgd_t *get_pgd_slow(void)
+{
+	pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL), *init;
+
+	if (ret) {
+		init = pgd_offset(&init_mm, 0);
+		pgd_init((unsigned long)ret);
+		memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+	}
+	return ret;
+}
+
+extern __inline__ pgd_t *get_pgd_fast(void)
+{
+	unsigned long *ret;
+
+	if((ret = pgd_quicklist) != NULL) {
+		pgd_quicklist = (unsigned long *)(*ret);
+		ret[0] = ret[1];
+		pgtable_cache_size--;
+	} else
+		ret = (unsigned long *)get_pgd_slow();
+	return (pgd_t *)ret;
+}
+
+extern __inline__ void free_pgd_fast(pgd_t *pgd)
+{
+	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
+	pgd_quicklist = (unsigned long *) pgd;
+	pgtable_cache_size++;
+}
+
+extern __inline__ void free_pgd_slow(pgd_t *pgd)
+{
+	free_page((unsigned long)pgd);
+}
+
+extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
+extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long address_preadjusted);
+
+extern __inline__ pte_t *get_pte_fast(void)
+{
+	unsigned long *ret;
+
+	if((ret = (unsigned long *)pte_quicklist) != NULL) {
+		pte_quicklist = (unsigned long *)(*ret);
+		ret[0] = ret[1];
+		pgtable_cache_size--;
+	}
+	return (pte_t *)ret;
+}
+
+extern __inline__ void free_pte_fast(pte_t *pte)
+{
+	*(unsigned long *)pte = (unsigned long) pte_quicklist;
+	pte_quicklist = (unsigned long *) pte;
+	pgtable_cache_size++;
+}
+
+extern __inline__ void free_pte_slow(pte_t *pte)
+{
+	free_page((unsigned long)pte);
+}
+
+/* We don't use pmd cache, so these are dummy routines */
+extern __inline__ pmd_t *get_pmd_fast(void)
+{
+	return (pmd_t *)0;
+}
+
+extern __inline__ void free_pmd_fast(pmd_t *pmd)
+{
+}
+
+extern __inline__ void free_pmd_slow(pmd_t *pmd)
+{
+}
+
+extern void __bad_pte(pmd_t *pmd);
+extern void __bad_pte_kernel(pmd_t *pmd);
+
+#define pte_free_kernel(pte)    free_pte_fast(pte)
+#define pte_free(pte)           free_pte_fast(pte)
+#define pgd_free(pgd)           free_pgd_fast(pgd)
+#define pgd_alloc()             get_pgd_fast()
+
+extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
+{
+	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+
+	if (pmd_none(*pmd)) {
+		pte_t *page = get_pte_fast();
+		if (page) {
+			pmd_val(*pmd) = (unsigned long)page;
+			return page + address;
+		}
+		return get_pte_kernel_slow(pmd, address);
+	}
+	if (pmd_bad(*pmd)) {
+		__bad_pte_kernel(pmd);
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + address;
+}
+
+extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
+{
+	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+
+	if (pmd_none(*pmd)) {
+		pte_t *page = get_pte_fast();
+		if (page) {
+			pmd_val(*pmd) = (unsigned long)page;
+			return page + address;
+		}
+		return get_pte_slow(pmd, address);
+	}
+	if (pmd_bad(*pmd)) {
+		__bad_pte(pmd);
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + address;
+}
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+extern inline void pmd_free(pmd_t * pmd)
+{
+}
+
+extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
+{
+	return (pmd_t *) pgd;
+}
+
+#define pmd_free_kernel		pmd_free
+#define pmd_alloc_kernel	pmd_alloc
+
+extern int do_check_pgt_cache(int, int);
+
+extern inline void set_pgdir(unsigned long address, pgd_t entry)
+{
+	struct task_struct * p;
+	pgd_t *pgd;
+#ifdef __SMP__
+	int i;
+#endif	
+
+	read_lock(&tasklist_lock);
+	for_each_task(p) {
+		if (!p->mm)
+			continue;
+		*pgd_offset(p->mm,address) = entry;
+	}
+	read_unlock(&tasklist_lock);
+#ifndef __SMP__
+	for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+		pgd[address >> PGDIR_SHIFT] = entry;
+#else
+	/* To pgd_alloc/pgd_free, one holds master kernel lock and so does our
+	   callee, so we can modify pgd caches of other CPUs as well. -jj */
+	for (i = 0; i < NR_CPUS; i++)
+		for (pgd = (pgd_t *)cpu_data[i].pgd_quick; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+			pgd[address >> PGDIR_SHIFT] = entry;
+#endif
+}
+
+#endif /* _ASM_PGALLOC_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/pgtable.h linux/include/asm-mips/pgtable.h
--- v2.3.47/linux/include/asm-mips/pgtable.h	Sun Feb 13 19:29:04 2000
+++ linux/include/asm-mips/pgtable.h	Thu Feb 24 22:52:30 2000
@@ -1,21 +1,23 @@
-/* $Id: pgtable.h,v 1.19 1998/10/26 19:59:39 davem Exp $
+/* $Id: pgtable.h,v 1.30 2000/02/24 00:13:19 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 - 1998 by Ralf Baechle at alii
+ * Copyright (C) 1994 - 1999 by Ralf Baechle at alii
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_PGTABLE_H
-#define __ASM_MIPS_PGTABLE_H
+#ifndef _ASM_PGTABLE_H
+#define _ASM_PGTABLE_H
 
 #include <asm/addrspace.h>
-#include <asm/mipsconfig.h>
+#include <asm/page.h>
 
 #ifndef _LANGUAGE_ASSEMBLY
 
 #include <linux/linkage.h>
 #include <asm/cachectl.h>
+#include <linux/config.h>
 
 /* Cache flushing:
  *
@@ -25,36 +27,29 @@
  *  - flush_cache_range(mm, start, end) flushes a range of pages
  *  - flush_page_to_ram(page) write back kernel page to ram
  */
-extern void (*flush_cache_all)(void);
-extern void (*flush_cache_mm)(struct mm_struct *mm);
-extern void (*flush_cache_range)(struct mm_struct *mm, unsigned long start,
+extern void (*_flush_cache_all)(void);
+extern void (*_flush_cache_mm)(struct mm_struct *mm);
+extern void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
 				 unsigned long end);
-extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
-extern void (*flush_cache_sigtramp)(unsigned long addr);
-extern void (*flush_page_to_ram)(unsigned long page);
-#define flush_icache_range(start, end) flush_cache_all()
+extern void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
+extern void (*_flush_cache_sigtramp)(unsigned long addr);
+extern void (*_flush_page_to_ram)(struct page * page);
+
+#define flush_cache_all()		_flush_cache_all()
+#define flush_cache_mm(mm)		_flush_cache_mm(mm)
+#define flush_cache_range(mm,start,end)	_flush_cache_range(mm,start,end)
+#define flush_cache_page(vma,page)	_flush_cache_page(vma, page)
+#define flush_cache_sigtramp(addr)	_flush_cache_sigtramp(addr)
+#define flush_page_to_ram(page)		_flush_page_to_ram(page)
 
-/* TLB flushing:
- *
- *  - flush_tlb_all() flushes all processes TLB entries
- *  - flush_tlb_mm(mm) flushes the specified mm context TLB entries
- *  - flush_tlb_page(mm, vmaddr) flushes a single page
- *  - flush_tlb_range(mm, start, end) flushes a range of pages
- */
-extern void (*flush_tlb_all)(void);
-extern void (*flush_tlb_mm)(struct mm_struct *mm);
-extern void (*flush_tlb_range)(struct mm_struct *mm, unsigned long start,
-			       unsigned long end);
-extern void (*flush_tlb_page)(struct vm_area_struct *vma, unsigned long page);
+#define flush_icache_range(start, end)	flush_cache_all()
+#define flush_icache_page(start,page)	do { } while(0)
 
-extern __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end)
-{
-}
 
 /*
  * - add_wired_entry() add a fixed TLB entry, and move wired register
  */
-extern void (*add_wired_entry)(unsigned long entrylo0, unsigned long entrylo1,
+extern void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
 			       unsigned long entryhi, unsigned long pagemask);
 
 
@@ -114,6 +109,20 @@
 #define _PAGE_WRITE                 (1<<2)  /* implemented in software */
 #define _PAGE_ACCESSED              (1<<3)  /* implemented in software */
 #define _PAGE_MODIFIED              (1<<4)  /* implemented in software */
+
+#if defined(CONFIG_CPU_R3000)
+
+#define _PAGE_GLOBAL                (1<<8)
+#define _PAGE_VALID                 (1<<9)
+#define _PAGE_SILENT_READ           (1<<9)  /* synonym                 */
+#define _PAGE_DIRTY                 (1<<10) /* The MIPS dirty bit      */
+#define _PAGE_SILENT_WRITE          (1<<10)
+#define _CACHE_UNCACHED             (1<<11) /* R4[0246]00              */
+#define _CACHE_MASK                 (1<<11)
+#define _CACHE_CACHABLE_NONCOHERENT 0
+
+#else
+ 
 #define _PAGE_R4KBUG                (1<<5)  /* workaround for r4k bug  */
 #define _PAGE_GLOBAL                (1<<6)
 #define _PAGE_VALID                 (1<<7)
@@ -130,6 +139,8 @@
 #define _CACHE_CACHABLE_ACCELERATED (7<<9)  /* R10000 only             */
 #define _CACHE_MASK                 (7<<9)
 
+#endif
+
 #define __READABLE	(_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
 #define __WRITEABLE	(_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
 
@@ -174,6 +185,13 @@
 
 #if !defined (_LANGUAGE_ASSEMBLY)
 
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pmd_ERROR(e) \
+	printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+	printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
+
 /*
  * BAD_PAGETABLE is used when we need a bogus page-table, while
  * BAD_PAGE is used for a bogus page.
@@ -189,8 +207,8 @@
 
 #define BAD_PAGETABLE __bad_pagetable()
 #define BAD_PAGE __bad_page()
-#define ZERO_PAGE(__vaddr) \
-	(empty_zero_page + (((unsigned long)(__vaddr)) & zero_page_mask))
+#define ZERO_PAGE(vaddr) \
+	(mem_map + MAP_NR(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))
 
 /* number of bits that fit into a memory pointer */
 #define BITS_PER_PTR			(8*sizeof(unsigned long))
@@ -207,10 +225,7 @@
 #define PAGE_PTR(address) \
 ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
 
-extern void (*load_pgd)(unsigned long pg_dir);
-
-/* to set the page-dir */
-#define SET_PAGE_DIR(tsk,pgdir) (tsk)->tss.pg_dir = ((unsigned long) (pgdir))
+extern void load_pgd(unsigned long pg_dir);
 
 extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)];
 
@@ -285,6 +300,14 @@
 extern inline void pgd_clear(pgd_t *pgdp)	{ }
 
 /*
+ * Permanent address of a page.  On MIPS64 we never have highmem, so this
+ * is simple.
+ */
+#define page_address(page)	((page)->virtual)
+#define pte_pagenr(x)		((unsigned long)((pte_val(x) >> PAGE_SHIFT)))
+#define pte_page(x)		(mem_map+pte_pagenr(x))
+
+/*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
@@ -353,14 +376,19 @@
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
-extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
-{
-	return __pte(((page & PAGE_MASK) - PAGE_OFFSET) | pgprot_val(pgprot));
-}
+#define mk_pte(page, pgprot)						\
+({									\
+	pte_t   __pte;							\
+									\
+	pte_val(__pte) = ((unsigned long)(page - mem_map) << PAGE_SHIFT) | \
+	                 pgprot_val(pgprot);				\
+									\
+	__pte;								\
+})
 
 extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
 {
-	return __pte(physpage | pgprot_val(pgprot));
+	return __pte(((physpage & PAGE_MASK) - PAGE_OFFSET) | pgprot_val(pgprot));
 }
 
 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
@@ -368,6 +396,8 @@
 	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
 }
 
+#define page_pte(page) page_pte_prot(page, __pgprot(0))
+
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
@@ -395,97 +425,7 @@
 /*
  * Initialize new page directory with pointers to invalid ptes
  */
-extern void (*pgd_init)(unsigned long page);
-
-/*
- * Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any.
- */
-
-#define pgd_quicklist (current_cpu_data.pgd_quick)
-#define pmd_quicklist ((unsigned long *)0)
-#define pte_quicklist (current_cpu_data.pte_quick)
-#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
-
-extern __inline__ pgd_t *get_pgd_slow(void)
-{
-	pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL), *init;
-
-	if (ret) {
-		init = pgd_offset(&init_mm, 0);
-		pgd_init((unsigned long)ret);
-		memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
-			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
-	}
-	return ret;
-}
-
-extern __inline__ pgd_t *get_pgd_fast(void)
-{
-	unsigned long *ret;
-
-	if((ret = pgd_quicklist) != NULL) {
-		pgd_quicklist = (unsigned long *)(*ret);
-		ret[0] = ret[1];
-		pgtable_cache_size--;
-	} else
-		ret = (unsigned long *)get_pgd_slow();
-	return (pgd_t *)ret;
-}
-
-extern __inline__ void free_pgd_fast(pgd_t *pgd)
-{
-	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
-	pgd_quicklist = (unsigned long *) pgd;
-	pgtable_cache_size++;
-}
-
-extern __inline__ void free_pgd_slow(pgd_t *pgd)
-{
-	free_page((unsigned long)pgd);
-}
-
-extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
-extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long address_preadjusted);
-
-extern __inline__ pte_t *get_pte_fast(void)
-{
-	unsigned long *ret;
-
-	if((ret = (unsigned long *)pte_quicklist) != NULL) {
-		pte_quicklist = (unsigned long *)(*ret);
-		ret[0] = ret[1];
-		pgtable_cache_size--;
-	}
-	return (pte_t *)ret;
-}
-
-extern __inline__ void free_pte_fast(pte_t *pte)
-{
-	*(unsigned long *)pte = (unsigned long) pte_quicklist;
-	pte_quicklist = (unsigned long *) pte;
-	pgtable_cache_size++;
-}
-
-extern __inline__ void free_pte_slow(pte_t *pte)
-{
-	free_page((unsigned long)pte);
-}
-
-/* We don't use pmd cache, so these are dummy routines */
-extern __inline__ pmd_t *get_pmd_fast(void)
-{
-	return (pmd_t *)0;
-}
-
-extern __inline__ void free_pmd_fast(pmd_t *pmd)
-{
-}
-
-extern __inline__ void free_pmd_slow(pmd_t *pmd)
-{
-}
+extern void pgd_init(unsigned long page);
 
 extern void __bad_pte(pmd_t *pmd);
 extern void __bad_pte_kernel(pmd_t *pmd);
@@ -495,100 +435,19 @@
 #define pgd_free(pgd)           free_pgd_fast(pgd)
 #define pgd_alloc()             get_pgd_fast()
 
-extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
-{
-	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
-
-	if (pmd_none(*pmd)) {
-		pte_t *page = get_pte_fast();
-		if (page) {
-			pmd_val(*pmd) = (unsigned long)page;
-			return page + address;
-		}
-		return get_pte_kernel_slow(pmd, address);
-	}
-	if (pmd_bad(*pmd)) {
-		__bad_pte_kernel(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + address;
-}
-
-extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
-{
-	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
-
-	if (pmd_none(*pmd)) {
-		pte_t *page = get_pte_fast();
-		if (page) {
-			pmd_val(*pmd) = (unsigned long)page;
-			return page + address;
-		}
-		return get_pte_slow(pmd, address);
-	}
-	if (pmd_bad(*pmd)) {
-		__bad_pte(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + address;
-}
-
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-extern inline void pmd_free(pmd_t * pmd)
-{
-}
-
-extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
-{
-	return (pmd_t *) pgd;
-}
-
-#define pmd_free_kernel		pmd_free
-#define pmd_alloc_kernel	pmd_alloc
-
 extern int do_check_pgt_cache(int, int);
 
-extern inline void set_pgdir(unsigned long address, pgd_t entry)
-{
-	struct task_struct * p;
-	pgd_t *pgd;
-#ifdef __SMP__
-	int i;
-#endif	
-        
-	read_lock(&tasklist_lock);
-	for_each_task(p) {
-		if (!p->mm)
-			continue;
-		*pgd_offset(p->mm,address) = entry;
-	}
-	read_unlock(&tasklist_lock);
-#ifndef __SMP__
-	for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
-		pgd[address >> PGDIR_SHIFT] = entry;
-#else
-	/* To pgd_alloc/pgd_free, one holds master kernel lock and so does our
-	   callee, so we can modify pgd caches of other CPUs as well. -jj */
-	for (i = 0; i < NR_CPUS; i++)
-		for (pgd = (pgd_t *)cpu_data[i].pgd_quick; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
-			pgd[address >> PGDIR_SHIFT] = entry;
-#endif
-}
-
 extern pgd_t swapper_pg_dir[1024];
 
-extern void (*update_mmu_cache)(struct vm_area_struct *vma,
+extern void update_mmu_cache(struct vm_area_struct *vma,
 				unsigned long address, pte_t pte);
 
-/*
- * Kernel with 32 bit address space
- */
-#define SWP_TYPE(entry) (((entry) >> 1) & 0x3f)
-#define SWP_OFFSET(entry) ((entry) >> 8)
-#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
+#define SWP_TYPE(x)		(((x).val >> 1) & 0x3f)
+#define SWP_OFFSET(x)		((x).val >> 8)
+#define SWP_ENTRY(type,offset)	((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
+#define pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
+#define swp_entry_to_pte(x)	((pte_t) { (x).val })
+
 
 #define module_map      vmalloc
 #define module_unmap    vfree
@@ -601,33 +460,37 @@
 extern inline void tlb_probe(void)
 {
 	__asm__ __volatile__(
-		".set noreorder\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"tlbp\n\t"
-		".set reorder");
+		".set pop");
 }
 
 extern inline void tlb_read(void)
 {
 	__asm__ __volatile__(
-		".set noreorder\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"tlbr\n\t"
-		".set reorder");
+		".set pop");
 }
 
 extern inline void tlb_write_indexed(void)
 {
 	__asm__ __volatile__(
-		".set noreorder\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"tlbwi\n\t"
-		".set reorder");
+		".set pop");
 }
 
 extern inline void tlb_write_random(void)
 {
 	__asm__ __volatile__(
-		".set noreorder\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"tlbwr\n\t"
-		".set reorder");
+		".set pop");
 }
 
 /* Dealing with various CP0 mmu/cache related registers. */
@@ -638,11 +501,10 @@
 	unsigned long val;
 
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mfc0 %0, $5\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: "=r" (val));
 	return val;
 }
@@ -650,11 +512,10 @@
 extern inline void set_pagemask(unsigned long val)
 {
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mtc0 %0, $5\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: : "r" (val));
 }
 
@@ -664,11 +525,10 @@
 	unsigned long val;
 
 	__asm__ __volatile__(	
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mfc0 %0, $2\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: "=r" (val));
 	return val;
 }
@@ -676,11 +536,10 @@
 extern inline void set_entrylo0(unsigned long val)
 {
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mtc0 %0, $2\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: : "r" (val));
 }
 
@@ -689,11 +548,10 @@
 	unsigned long val;
 
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mfc0 %0, $3\n\t"
-		".set mips0\n\t"
-		".set reorder" : "=r" (val));
+		".set pop" : "=r" (val));
 
 	return val;
 }
@@ -701,11 +559,10 @@
 extern inline void set_entrylo1(unsigned long val)
 {
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mtc0 %0, $3\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: : "r" (val));
 }
 
@@ -715,11 +572,10 @@
 	unsigned long val;
 
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mfc0 %0, $10\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: "=r" (val));
 
 	return val;
@@ -728,11 +584,10 @@
 extern inline void set_entryhi(unsigned long val)
 {
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mtc0 %0, $10\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: : "r" (val));
 }
 
@@ -742,11 +597,10 @@
 	unsigned long val;
 
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mfc0 %0, $0\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: "=r" (val));
 	return val;
 }
@@ -754,11 +608,10 @@
 extern inline void set_index(unsigned long val)
 {
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
-		"mtc0 %0, $0\n\t"
-		".set mips0\n\t"
+		".set push\n\t"
 		".set reorder\n\t"
+		"mtc0 %0, $0\n\t"
+		".set pop"
 		: : "r" (val));
 }
 
@@ -768,11 +621,10 @@
 	unsigned long val;
 
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
-		"mfc0 %0, $6\n\t"
-		".set mips0\n\t"
+		".set push\n\t"
 		".set reorder\n\t"
+		"mfc0 %0, $6\n\t"
+		".set pop"
 		: "=r" (val));
 	return val;
 }
@@ -780,11 +632,10 @@
 extern inline void set_wired(unsigned long val)
 {
 	__asm__ __volatile__(
-		"\n\t.set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mtc0 %0, $6\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: : "r" (val));
 }
 
@@ -794,11 +645,10 @@
 	unsigned long val;
 
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mfc0 %0, $28\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: "=r" (val));
 	return val;
 }
@@ -806,11 +656,10 @@
 extern inline void set_taglo(unsigned long val)
 {
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mtc0 %0, $28\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: : "r" (val));
 }
 
@@ -819,11 +668,10 @@
 	unsigned long val;
 
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mfc0 %0, $29\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: "=r" (val));
 	return val;
 }
@@ -831,11 +679,10 @@
 extern inline void set_taghi(unsigned long val)
 {
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mtc0 %0, $29\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: : "r" (val));
 }
 
@@ -845,11 +692,10 @@
 	unsigned long val;
 
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mfc0 %0, $4\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: "=r" (val));
 
 	return val;
@@ -858,14 +704,15 @@
 extern inline void set_context(unsigned long val)
 {
 	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
+		".set push\n\t"
+		".set reorder\n\t"
 		"mtc0 %0, $4\n\t"
-		".set mips0\n\t"
-		".set reorder"
+		".set pop"
 		: : "r" (val));
 }
 
 #endif /* !defined (_LANGUAGE_ASSEMBLY) */
 
-#endif /* __ASM_MIPS_PGTABLE_H */
+#define io_remap_page_range remap_page_range
+
+#endif /* _ASM_PGTABLE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/posix_types.h linux/include/asm-mips/posix_types.h
--- v2.3.47/linux/include/asm-mips/posix_types.h	Tue Oct 20 13:52:53 1998
+++ linux/include/asm-mips/posix_types.h	Thu Feb 24 22:52:30 2000
@@ -1,17 +1,13 @@
-/* $Id: posix_types.h,v 1.5 1998/08/17 13:59:34 ralf Exp $
+/* $Id: posix_types.h,v 1.7 2000/02/16 01:07:48 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998, 2000 by Ralf Baechle
  */
-#ifndef __ARCH_MIPS_POSIX_TYPES_H
-#define __ARCH_MIPS_POSIX_TYPES_H
-
-#define __need_size_t
-#define __need_ptrdiff_t
-#include <stddef.h>
+#ifndef _ASM_POSIX_TYPES_H
+#define _ASM_POSIX_TYPES_H
 
 /*
  * This file is generally used by user-level software, so you need to
@@ -28,8 +24,8 @@
 typedef long		__kernel_ipc_pid_t;
 typedef long		__kernel_uid_t;
 typedef long		__kernel_gid_t;
-typedef __SIZE_TYPE__	__kernel_size_t;
-typedef __SSIZE_TYPE__	__kernel_ssize_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
 typedef int		__kernel_ptrdiff_t;
 typedef long		__kernel_time_t;
 typedef long		__kernel_suseconds_t;
@@ -37,6 +33,13 @@
 typedef long		__kernel_daddr_t;
 typedef char *		__kernel_caddr_t;
 
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef long		__kernel_uid32_t;
+typedef long		__kernel_gid32_t;
+typedef __kernel_uid_t	__kernel_old_uid_t;
+typedef __kernel_gid_t	__kernel_old_gid_t;
+
 #ifdef __GNUC__
 typedef long long      __kernel_loff_t;
 #endif
@@ -117,4 +120,4 @@
 
 #endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
 
-#endif /* __ARCH_MIPS_POSIX_TYPES_H */
+#endif /* _ASM_POSIX_TYPES_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/prctl.h linux/include/asm-mips/prctl.h
--- v2.3.47/linux/include/asm-mips/prctl.h	Tue Oct 20 13:52:53 1998
+++ linux/include/asm-mips/prctl.h	Thu Feb 24 22:52:30 2000
@@ -3,7 +3,7 @@
  *
  * The IRIX kernel maps a page at PRDA_ADDRESS with the
  * contents of prda and fills it the bits on prda_sys.
- * $Id: prctl.h,v 1.1 1997/12/02 02:28:28 ralf Exp $
+ * $Id: prctl.h,v 1.1 1997/09/21 22:27:19 miguel Exp $
  */
 
 #ifndef __PRCTL_H__
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/processor.h linux/include/asm-mips/processor.h
--- v2.3.47/linux/include/asm-mips/processor.h	Fri Jan  7 19:13:22 2000
+++ linux/include/asm-mips/processor.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: processor.h,v 1.18 1998/10/14 20:31:12 ralf Exp $
+/* $Id: processor.h,v 1.25 2000/02/05 06:47:37 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -6,10 +6,13 @@
  *
  * Copyright (C) 1994 Waldorf GMBH
  * Copyright (C) 1995, 1996, 1997, 1998 Ralf Baechle
- * Modified further for R[236]000 compatibility by Paul M. Antoine
+ * Copyright (C) 1996 Paul M. Antoine
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_PROCESSOR_H
-#define __ASM_MIPS_PROCESSOR_H
+#ifndef _ASM_PROCESSOR_H
+#define _ASM_PROCESSOR_H
+
+#include <asm/isadep.h>
 
 /*
  * Default implementation of macro that returns current
@@ -18,6 +21,7 @@
 #define current_text_addr() ({ __label__ _l; _l: &&_l;})
 
 #if !defined (_LANGUAGE_ASSEMBLY)
+#include <linux/threads.h>
 #include <asm/cachectl.h>
 #include <asm/mipsregs.h>
 #include <asm/reg.h>
@@ -90,9 +94,9 @@
 #define NUM_FPU_REGS	32
 
 struct mips_fpu_hard_struct {
-	double fp_regs[NUM_FPU_REGS];
+	unsigned int fp_regs[NUM_FPU_REGS];
 	unsigned int control;
-};
+} __attribute__((aligned(8)));
 
 /*
  * FIXME: no fpu emulator yet (but who cares anyway?)
@@ -134,7 +138,6 @@
 	unsigned long cp0_baduaddr;	/* Last kernel fault accessing USEG */
 	unsigned long error_code;
 	unsigned long trap_no;
-	unsigned long pg_dir;                   /* used in tlb refill    */
 #define MF_FIXADE 1			/* Fix address errors in software */
 #define MF_LOGADE 2			/* Log address errors to syslog */
 	unsigned long mflags;
@@ -148,7 +151,7 @@
 #define INIT_MMAP { &init_mm, KSEG0, KSEG1, NULL, PAGE_SHARED, \
                     VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
 
-#define INIT_TSS  { \
+#define INIT_THREAD  { \
         /* \
          * saved main processor registers \
          */ \
@@ -165,7 +168,7 @@
 	/* \
 	 * Other stuff associated with the process \
 	 */ \
-	0, 0, 0, 0, (unsigned long) swapper_pg_dir, \
+	0, 0, 0, 0, \
 	/* \
 	 * For now the default is to fix address errors \
 	 */ \
@@ -179,45 +182,51 @@
 #if !defined (_LANGUAGE_ASSEMBLY)
 
 /* Free all resources held by a thread. */
-extern void release_thread(struct task_struct *);
+#define release_thread(thread) do { } while(0)
+
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 /* Copy and release all segment info associated with a VM */
-#define copy_segments(nr, p, mm) do { } while(0)
+#define copy_segments(p, mm) do { } while(0)
 #define release_segments(mm) do { } while(0)
-#define forget_segments()		do { } while (0)
 
 /*
  * Return saved PC of a blocked thread.
  */
 extern inline unsigned long thread_saved_pc(struct thread_struct *t)
 {
-	extern void ret_from_sys_call(void);
+	extern void ret_from_fork(void);
 
 	/* New born processes are a special case */
-	if (t->reg31 == (unsigned long) ret_from_sys_call)
+	if (t->reg31 == (unsigned long) ret_from_fork)
 		return t->reg31;
 
-	return ((unsigned long*)t->reg29)[17];
+	return ((unsigned long *)t->reg29)[10];
 }
 
 /*
  * Do necessary setup to start up a newly executed thread.
  */
-extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp);
+#define start_thread(regs, new_pc, new_sp) do {				\
+	/* New thread looses kernel privileges. */			\
+	regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU)) | KU_USER;\
+	regs->cp0_epc = new_pc;						\
+	regs->regs[29] = new_sp;					\
+	current->thread.current_ds = USER_DS;				\
+} while (0)
 
 unsigned long get_wchan(struct task_struct *p);
 
-#define PT_REG(reg)		((long)&((struct pt_regs *)0)->reg \
-				 - sizeof(struct pt_regs))
-#define KSTK_TOS(tsk) ((unsigned long)(tsk) + KERNEL_STACK_SIZE - 32)
-#define KSTK_EIP(tsk)	(*(unsigned long *)(KSTK_TOS(tsk) + PT_REG(cp0_epc)))
-#define KSTK_ESP(tsk)	(*(unsigned long *)(KSTK_TOS(tsk) + PT_REG(regs[29])))
+#define __PT_REG(reg) ((long)&((struct pt_regs *)0)->reg - sizeof(struct pt_regs))
+#define __KSTK_TOS(tsk) ((unsigned long)(tsk) + KERNEL_STACK_SIZE - 32)
+#define KSTK_EIP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(cp0_epc)))
+#define KSTK_ESP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(regs[29])))
 
 /* Allocation and freeing of basic task resources. */
 /*
  * NOTE! The task struct and the stack go together
  */
+#define THREAD_SIZE (2*PAGE_SIZE)
 #define alloc_task_struct() \
 	((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
 #define free_task_struct(p)	free_pages((unsigned long)(p),1)
@@ -253,4 +262,4 @@
 #define return_address() NULL
 #endif
 
-#endif /* __ASM_MIPS_PROCESSOR_H */
+#endif /* _ASM_PROCESSOR_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/ptrace.h linux/include/asm-mips/ptrace.h
--- v2.3.47/linux/include/asm-mips/ptrace.h	Mon Jul  5 19:44:57 1999
+++ linux/include/asm-mips/ptrace.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: ptrace.h,v 1.3 1998/07/09 21:45:21 ralf Exp $
+/* $Id: ptrace.h,v 1.8 1999/10/12 17:33:50 harald Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -12,6 +12,7 @@
 #ifndef __ASM_MIPS_PTRACE_H
 #define __ASM_MIPS_PTRACE_H
 
+#include <asm/isadep.h>
 #include <linux/types.h>
 
 /* 0 - 31 are integer registers, 32 - 63 are fp registers.  */
@@ -59,11 +60,11 @@
 /*
  * Does the process account for user or for system time?
  */
-extern int (*user_mode)(struct pt_regs *);
+#define user_mode(regs) (((regs)->cp0_status & KU_MASK) == KU_USER)
 
 #define instruction_pointer(regs) ((regs)->cp0_epc)
 
-extern void (*show_regs)(struct pt_regs *);
+extern void show_regs(struct pt_regs *);
 #endif /* !(__ASSEMBLY__) */
 
 #endif
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/r4kcache.h linux/include/asm-mips/r4kcache.h
--- v2.3.47/linux/include/asm-mips/r4kcache.h	Tue Oct 20 13:52:54 1998
+++ linux/include/asm-mips/r4kcache.h	Thu Feb 24 22:52:30 2000
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: r4kcache.h,v 1.7 1997/12/18 13:00:45 ralf Exp $
+ * $Id: r4kcache.h,v 1.5 1998/03/04 05:36:23 ralf Exp $
  *
  * FIXME: Handle split L2 caches.
  */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/reboot.h linux/include/asm-mips/reboot.h
--- v2.3.47/linux/include/asm-mips/reboot.h	Thu Jun 26 12:33:40 1997
+++ linux/include/asm-mips/reboot.h	Thu Feb 24 22:52:30 2000
@@ -3,15 +3,15 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997 by Ralf Baechle
+ * Copyright (C) 1997, 1999 by Ralf Baechle
  *
  * Declare variables for rebooting.
  */
-#ifndef __ASM_MIPS_REBOOT_H
-#define __ASM_MIPS_REBOOT_H
+#ifndef _ASM_REBOOT_H
+#define _ASM_REBOOT_H
 
 void (*_machine_restart)(char *command);
 void (*_machine_halt)(void);
 void (*_machine_power_off)(void);
 
-#endif /* __ASM_MIPS_REBOOT_H */
+#endif /* _ASM_REBOOT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/reg.h linux/include/asm-mips/reg.h
--- v2.3.47/linux/include/asm-mips/reg.h	Thu Jun 26 12:33:40 1997
+++ linux/include/asm-mips/reg.h	Thu Feb 24 22:52:30 2000
@@ -6,7 +6,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995 by Ralf Baechle
+ * Copyright (C) 1995, 1999 by Ralf Baechle
  */
 #ifndef __ASM_MIPS_REG_H
 #define __ASM_MIPS_REG_H
@@ -55,14 +55,12 @@
  */
 #define EF_LO			38
 #define EF_HI			39
-#define EF_ORIG_REG2		40
-#define EF_ORIG_REG7		41
 
-#define EF_CP0_EPC		42
-#define EF_CP0_BADVADDR		43
-#define EF_CP0_STATUS		44
-#define EF_CP0_CAUSE		45
+#define EF_CP0_EPC		40
+#define EF_CP0_BADVADDR		41
+#define EF_CP0_STATUS		42
+#define EF_CP0_CAUSE		44
 
-#define EF_SIZE			180
+#define EF_SIZE			180	/* size in bytes */
 
 #endif /* __ASM_MIPS_REG_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/resource.h linux/include/asm-mips/resource.h
--- v2.3.47/linux/include/asm-mips/resource.h	Tue Dec 14 01:27:24 1999
+++ linux/include/asm-mips/resource.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: resource.h,v 1.2 1999/01/04 16:09:25 ralf Exp $
+/* $Id: resource.h,v 1.5 2000/02/04 07:40:53 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -6,8 +6,8 @@
  *
  * Copyright (C) 1995, 1996, 1998 by Ralf Baechle
  */
-#ifndef __ASM_MIPS_RESOURCE_H
-#define __ASM_MIPS_RESOURCE_H
+#ifndef _ASM_RESOURCE_H
+#define _ASM_RESOURCE_H
 
 /*
  * Resource limits
@@ -29,24 +29,24 @@
  * SuS says limits have to be unsigned.
  * Which makes a ton more sense anyway.
  */
-#define RLIM_INFINITY	(~0UL)
+#define RLIM_INFINITY	0x7fffffffUL
 
 #ifdef __KERNEL__
 
 #define INIT_RLIMITS					\
 {							\
-	{ LONG_MAX, LONG_MAX },				\
-	{ LONG_MAX, LONG_MAX },				\
-	{ LONG_MAX, LONG_MAX },				\
-	{ _STK_LIM, LONG_MAX },				\
-	{        0, LONG_MAX },				\
-	{ INR_OPEN, INR_OPEN },				\
-	{ LONG_MAX, LONG_MAX },				\
-	{ LONG_MAX, LONG_MAX },				\
-	{ MAX_TASKS_PER_USER, MAX_TASKS_PER_USER },	\
-	{ LONG_MAX, LONG_MAX },				\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ _STK_LIM,      RLIM_INFINITY },		\
+	{        0,      RLIM_INFINITY },		\
+	{ INR_OPEN,      INR_OPEN      },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ 0,             0             },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
 }
 
 #endif /* __KERNEL__ */
 
-#endif /* __ASM_MIPS_RESOURCE_H */
+#endif /* _ASM_RESOURCE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/segment.h linux/include/asm-mips/segment.h
--- v2.3.47/linux/include/asm-mips/segment.h	Thu Jun 26 12:33:40 1997
+++ linux/include/asm-mips/segment.h	Thu Feb 24 22:52:30 2000
@@ -1,6 +1,6 @@
-#ifndef __ALPHA_SEGMENT_H
-#define __ALPHA_SEGMENT_H
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
 
 /* Only here because we have some old header files that expect it.. */
 
-#endif
+#endif /* _ASM_SEGMENT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/semaphore-helper.h linux/include/asm-mips/semaphore-helper.h
--- v2.3.47/linux/include/asm-mips/semaphore-helper.h	Mon Jul 19 13:12:47 1999
+++ linux/include/asm-mips/semaphore-helper.h	Thu Feb 24 22:52:30 2000
@@ -1,13 +1,16 @@
-/* $Id: semaphore-helper.h,v 1.3 1999/06/11 14:30:15 ralf Exp $
+/* $Id: semaphore-helper.h,v 1.7 1999/10/21 00:23:05 ralf Exp $
  *
  * SMP- and interrupt-safe semaphores helper functions.
  *
  * (C) Copyright 1996 Linus Torvalds
  * (C) Copyright 1999 Andrea Arcangeli
  * (C) Copyright 1999 Ralf Baechle
+ * (C) Copyright 1999 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_SEMAPHORE_HELPER_H
-#define __ASM_MIPS_SEMAPHORE_HELPER_H
+#ifndef _ASM_SEMAPHORE_HELPER_H
+#define _ASM_SEMAPHORE_HELPER_H
+
+#include <linux/config.h>
 
 /*
  * These two _must_ execute atomically wrt each other.
@@ -17,17 +20,77 @@
 	atomic_inc(&sem->waking);
 }
 
+#if !defined(CONFIG_CPU_HAS_LLSC)
+
+/*
+ * It doesn't make sense, IMHO, to endlessly turn interrupts off and on again.
+ * Do it once and that's it. ll/sc *has* it's advantages. HK
+ */
+#define read(a) ((a)->counter)
+#define inc(a) (((a)->counter)++)
+#define dec(a) (((a)->counter)--)
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	save_and_cli(flags);
+	if (read(&sem->waking) > 0) {
+		dec(&sem->waking);
+		ret = 1;
+	}
+	restore_flags(flags);
+	return ret;
+}
+
+static inline int waking_non_zero_interruptible(struct semaphore *sem,
+						struct task_struct *tsk)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	save_and_cli(flags);
+	if (read(&sem->waking) > 0) {
+		dec(&sem->waking);
+		ret = 1;
+	} else if (signal_pending(tsk)) {
+		inc(&sem->count);
+		ret = -EINTR;
+	}
+	restore_flags(flags);
+	return ret;
+}
+
+static inline int waking_non_zero_trylock(struct semaphore *sem)
+{
+        int ret = 1;
+	unsigned long flags;
+
+	save_and_cli(flags);
+	if (read(&sem->waking) <= 0)
+		inc(&sem->count);
+	else {
+		dec(&sem->waking);
+		ret = 0;
+	}
+	restore_flags(flags);
+	return ret;
+}
+
+#else /* CONFIG_CPU_HAS_LLSC */
+
 static inline int
 waking_non_zero(struct semaphore *sem)
 {
 	int ret, tmp;
 
 	__asm__ __volatile__(
-	"1:\tll\t%1,%2\n\t"
-	"blez\t%1,2f\n\t"
-	"subu\t%0,%1,1\n\t"
-	"sc\t%0,%2\n\t"
-	"beqz\t%0,1b\n\t"
+	"1:\tll\t%1, %2\n\t"
+	"blez\t%1, 2f\n\t"
+	"subu\t%0, %1, 1\n\t"
+	"sc\t%0, %2\n\t"
+	"beqz\t%0, 1b\n\t"
 	"2:"
 	".text"
 	: "=r"(ret), "=r"(tmp), "=m"(__atomic_fool_gcc(&sem->waking))
@@ -48,78 +111,113 @@
  *
  * This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words.
  *
- * This is crazy.  Normally it stricly forbidden to use 64-bit operation
+ * This is crazy.  Normally it stricly forbidden to use 64-bit operations
  * in the 32-bit MIPS kernel.  In this case it's however ok because if an
  * interrupt has destroyed the upper half of registers sc will fail.
+ * Note also that this will not work for MIPS32 CPUS!
+ *
+ * Pseudocode:
+ *
+ * If(sem->waking > 0) {
+ *	Decrement(sem->waking)
+ *	Return(SUCCESS)
+ * } else If(segnal_pending(tsk)) {
+ *	Increment(sem->count)
+ *	Return(-EINTR)
+ * } else {
+ *	Return(SLEEP)
+ * }
  */
+
 static inline int
 waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk)
 {
 	long ret, tmp;
 
 #ifdef __MIPSEB__
+
         __asm__ __volatile__("
-	.set	mips3
 	.set	push
+	.set	mips3
 	.set	noat
-0:	lld	%1,%2
-	li	%0,0
+0:	lld	%1, %2
+	li	%0, 0
+	sll	$1, %1, 0
+	blez	$1, 1f
+	daddiu	%1, %1, -1
+	li	%0, 1
+	b 	2f
+1:
+	beqz	%3, 2f
+	li	%0, %4
+	dli	$1, 0x0000000100000000
+	daddu	%1, %1, $1
+2:
+	scd	%1, %2
+	beqz	%1, 0b
+
+	.set	pop"
+	: "=&r"(ret), "=&r"(tmp), "=m"(*sem)
+	: "r"(signal_pending(tsk)), "i"(-EINTR));
+
+#elif defined(__MIPSEL__)
 
-	bltz	%1, 1f
-	dli	$1, 0xffffffff00000000
-	daddu	%1, $1
+	__asm__ __volatile__("
+	.set	mips3
+	.set	push
+	.set	noat
+0:
+	lld	%1, %2
+	li	%0, 0
+	blez	%1, 1f
+	dli	$1, 0x0000000100000000
+	dsubu	%1, %1, $1
 	li	%0, 1
 	b	2f
 1:
-
-	beqz	%3, 1f
-	addiu	$1, %1, 1
+	beqz	%3, 2f
+	li	%0, %4
+	/* 
+	 * It would be nice to assume that sem->count
+	 * is != -1, but we will guard against that case
+	 */
+	daddiu	$1, %1, 1
 	dsll32	$1, $1, 0
 	dsrl32	$1, $1, 0
 	dsrl32	%1, %1, 0
 	dsll32	%1, %1, 0
-	or	%1, $1
-	li	%0, %4
-	b	2f
-1:
-	scd	%1, %2
+	or	%1, %1, $1
 2:
-	beqz	%1,0b
+	scd	%1, %2
+	beqz	%1, 0b
+
 	.set	pop
 	.set	mips0"
 	: "=&r"(ret), "=&r"(tmp), "=m"(*sem)
 	: "r"(signal_pending(tsk)), "i"(-EINTR));
-#endif
 
-#ifdef __MIPSEL__
-#error "FIXME: waking_non_zero_interruptible doesn't support little endian machines yet."
+#else
+#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
 #endif
 
 	return ret;
 }
 
 /*
- * waking_non_zero_trylock:
- *	1	failed to lock
- *	0	got the lock
- *
- * XXX SMP ALERT
+ * waking_non_zero_trylock is unused.  we do everything in 
+ * down_trylock and let non-ll/sc hosts bounce around.
  */
-#ifdef __SMP__
-#error FIXME, waking_non_zero_trylock is broken for SMP.
-#endif
-static inline int waking_non_zero_trylock(struct semaphore *sem)
-{
-        int ret = 1;
 
-	if (atomic_read(&sem->waking) <= 0)
-		atomic_inc(&sem->count);
-	else {
-		atomic_dec(&sem->waking);
-		ret = 0;
-	}
+static inline int
+waking_non_zero_trylock(struct semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
 
-	return ret;
+	return 0;
 }
 
-#endif /* __ASM_MIPS_SEMAPHORE_HELPER_H */
+#endif /* CONFIG_CPU_HAS_LLSC */
+
+#endif /* _ASM_SEMAPHORE_HELPER_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/semaphore.h linux/include/asm-mips/semaphore.h
--- v2.3.47/linux/include/asm-mips/semaphore.h	Fri Sep 10 23:57:36 1999
+++ linux/include/asm-mips/semaphore.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: semaphore.h,v 1.6 1999/06/17 13:30:38 ralf Exp $
+/* $Id: semaphore.h,v 1.13 2000/02/18 00:24:48 ralf Exp $
  *
  * SMP- and interrupt-safe semaphores..
  *
@@ -7,19 +7,26 @@
  * for more details.
  *
  * (C) Copyright 1996  Linus Torvalds
- * (C) Copyright 1998, 1999  Ralf Baechle
+ * (C) Copyright 1998, 1999, 2000  Ralf Baechle
+ * (C) Copyright 1999, 2000  Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_SEMAPHORE_H
-#define __ASM_MIPS_SEMAPHORE_H
+#ifndef _ASM_SEMAPHORE_H
+#define _ASM_SEMAPHORE_H
 
 #include <asm/system.h>
 #include <asm/atomic.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
+#include <linux/config.h>
 
 struct semaphore {
+#ifdef __MIPSEB__
 	atomic_t count;
 	atomic_t waking;
+#else
+	atomic_t waking;
+	atomic_t count;
+#endif
 	wait_queue_head_t wait;
 #if WAITQUEUE_DEBUG
 	long __magic;
@@ -33,9 +40,15 @@
 # define __SEM_DEBUG_INIT(name)
 #endif
 
+#ifdef __MIPSEB__
 #define __SEMAPHORE_INITIALIZER(name,count) \
 { ATOMIC_INIT(count), ATOMIC_INIT(0), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
 	__SEM_DEBUG_INIT(name) }
+#else
+#define __SEMAPHORE_INITIALIZER(name,count) \
+{ ATOMIC_INIT(0), ATOMIC_INIT(count), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+	__SEM_DEBUG_INIT(name) }
+#endif
 
 #define __MUTEX_INITIALIZER(name) \
 	__SEMAPHORE_INITIALIZER(name,1)
@@ -92,11 +105,39 @@
 	return ret;
 }
 
+#if !defined(CONFIG_CPU_HAS_LLSC)
+
+extern inline int down_trylock(struct semaphore * sem)
+{
+	int ret = 0;
+	if (atomic_dec_return(&sem->count) < 0)
+		ret = __down_trylock(sem);
+	return ret;
+}
+
+#else
+
 /*
  * down_trylock returns 0 on success, 1 if we failed to get the lock.
  *
  * We must manipulate count and waking simultaneously and atomically.
- * Do this by using ll/sc on the pair of 32-bit words.
+ * Here, we this by using ll/sc on the pair of 32-bit words.  This
+ * won't work on MIPS32 platforms, however, and must be rewritten.
+ *
+ * Pseudocode:
+ *
+ *   Decrement(sem->count)
+ *   If(sem->count >=0) {
+ *	Return(SUCCESS)			// resource is free
+ *   } else {
+ *	If(sem->waking <= 0) {		// if no wakeup pending
+ *	   Increment(sem->count)	// undo decrement
+ *	   Return(FAILURE)
+ *      } else {
+ *	   Decrement(sem->waking)	// otherwise "steal" wakeup
+ *	   Return(SUCCESS)
+ *	}
+ *   }
  */
 extern inline int down_trylock(struct semaphore * sem)
 {
@@ -105,40 +146,36 @@
 #if WAITQUEUE_DEBUG
 	CHECK_MAGIC(sem->__magic);
 #endif
-#ifdef __MIPSEB__
+
 	__asm__ __volatile__("
 			.set	mips3
+
 		0:	lld	%1, %4
 			dli	%3, 0x0000000100000000
-			sltu	%0, %1, $0
-
-			bltz	%1, 1f
-			move	%3, $0
+			dsubu	%1, %3
+			li	%0, 0
+			bgez	%1, 2f
+			sll	%2, %1, 0
+			blez	%2, 1f
+			daddiu	%1, %1, -1
+			b	2f
 		1:
-
-			sltu	%2, %1, $0
-			and	%0, %0, %2
-			bnez	%0, 2f
-
-			subu	%0, %3
+			daddu	%1, %1, %3
+			li	%0, 1
+		2:
 			scd	%1, %4
-
 			beqz	%1, 0b
-		2:
 
 			.set	mips0"
 		: "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub)
 		: "m"(*sem)
 		: "memory");
-#endif
-
-#ifdef __MIPSEL__
-#error "FIXME: down_trylock doesn't support little endian machines yet."
-#endif
 
 	return ret;
 }
 
+#endif
+
 /*
  * Note! This is subtle. We jump to wake people up only if
  * the semaphore was negative (== somebody was waiting on it).
@@ -152,4 +189,174 @@
 		__up(sem);
 }
 
-#endif /* __ASM_MIPS_SEMAPHORE_H */
+/*
+ * rw mutexes (should that be mutices? =) -- throw rw spinlocks and
+ * semaphores together, and this is what we end up with...
+ *
+ * The lock is initialized to BIAS.  This way, a writer subtracts BIAS ands
+ * gets 0 for the case of an uncontended lock.  Readers decrement by 1 and
+ * see a positive value when uncontended, negative if there are writers
+ * waiting (in which case it goes to sleep).
+ *
+ * The value 0x01000000 supports up to 128 processors and lots of processes.
+ * BIAS must be chosen such that subtracting BIAS once per CPU will result
+ * in the int remaining negative.  In terms of fairness, this should result
+ * in the lock flopping back and forth between readers and writers under
+ * heavy use.
+ *
+ * Once we start supporting machines with more than 128 CPUs, we should go
+ * for using a 64bit atomic type instead of 32bit as counter. We shall
+ * probably go for bias 0x80000000 then, so that single sethi can set it.
+ * */
+
+#define RW_LOCK_BIAS		0x01000000
+
+struct rw_semaphore {
+	atomic_t		count;
+	/* bit 0 means read bias granted;
+	   bit 1 means write bias granted.  */
+	unsigned		granted;
+	wait_queue_head_t	wait;
+	wait_queue_head_t	write_bias_wait;
+#if WAITQUEUE_DEBUG
+	long			__magic;
+	atomic_t		readers;
+	atomic_t		writers;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+#define __RWSEM_DEBUG_INIT	, ATOMIC_INIT(0), ATOMIC_INIT(0)
+#else
+#define __RWSEM_DEBUG_INIT	/* */
+#endif
+
+#define __RWSEM_INITIALIZER(name,count)					\
+	{ ATOMIC_INIT(count), 0,					\
+	  __WAIT_QUEUE_HEAD_INITIALIZER((name).wait),			\
+	  __WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait)		\
+	  __SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT }
+
+#define __DECLARE_RWSEM_GENERIC(name,count) \
+	struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
+
+#define DECLARE_RWSEM(name) \
+	__DECLARE_RWSEM_GENERIC(name, RW_LOCK_BIAS)
+#define DECLARE_RWSEM_READ_LOCKED(name) \
+	__DECLARE_RWSEM_GENERIC(name, RW_LOCK_BIAS-1)
+#define DECLARE_RWSEM_WRITE_LOCKED(name) \
+	__DECLARE_RWSEM_GENERIC(name, 0)
+
+extern inline void init_rwsem(struct rw_semaphore *sem)
+{
+	atomic_set(&sem->count, RW_LOCK_BIAS);
+	sem->granted = 0;
+	init_waitqueue_head(&sem->wait);
+	init_waitqueue_head(&sem->write_bias_wait);
+#if WAITQUEUE_DEBUG
+	sem->__magic = (long)&sem->__magic;
+	atomic_set(&sem->readers, 0);
+	atomic_set(&sem->writers, 0);
+#endif
+}
+
+/* The expensive part is outlined.  */
+extern void __down_read(struct rw_semaphore *sem, int count);
+extern void __down_write(struct rw_semaphore *sem, int count);
+extern void __rwsem_wake(struct rw_semaphore *sem, unsigned long readers);
+
+extern inline void down_read(struct rw_semaphore *sem)
+{
+	int count;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	count = atomic_dec_return(&sem->count);
+	if (count < 0) {
+		__down_read(sem, count);
+	}
+	mb();
+
+#if WAITQUEUE_DEBUG
+	if (sem->granted & 2)
+		BUG();
+	if (atomic_read(&sem->writers))
+		BUG();
+	atomic_inc(&sem->readers);
+#endif
+}
+
+extern inline void down_write(struct rw_semaphore *sem)
+{
+	int count;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	count = atomic_sub_return(RW_LOCK_BIAS, &sem->count);
+	if (count) {
+		__down_write(sem, count);
+	}
+	mb();
+
+#if WAITQUEUE_DEBUG
+	if (atomic_read(&sem->writers))
+		BUG();
+	if (atomic_read(&sem->readers))
+		BUG();
+	if (sem->granted & 3)
+		BUG();
+	atomic_inc(&sem->writers);
+#endif
+}
+
+/* When a reader does a release, the only significant case is when
+   there was a writer waiting, and we've bumped the count to 0: we must
+   wake the writer up.  */
+
+extern inline void up_read(struct rw_semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+	if (sem->granted & 2)
+		BUG();
+	if (atomic_read(&sem->writers))
+		BUG();
+	atomic_dec(&sem->readers);
+#endif
+
+	mb();
+	if (atomic_inc_return(&sem->count) == 0)
+		__rwsem_wake(sem, 0);
+}
+
+/*
+ * Releasing the writer is easy -- just release it and wake up any sleepers.
+ */
+extern inline void up_write(struct rw_semaphore *sem)
+{
+	int count;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+	if (sem->granted & 3)
+		BUG();
+	if (atomic_read(&sem->readers))
+		BUG();
+	if (atomic_read(&sem->writers) != 1)
+		BUG();
+	atomic_dec(&sem->writers);
+#endif
+
+	mb();
+	count = atomic_add_return(RW_LOCK_BIAS, &sem->count);
+	if (count - RW_LOCK_BIAS < 0 && count >= 0) {
+		/* Only do the wake if we're no longer negative.  */
+		__rwsem_wake(sem, count);
+	}
+}
+
+#endif /* _ASM_SEMAPHORE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sembuf.h linux/include/asm-mips/sembuf.h
--- v2.3.47/linux/include/asm-mips/sembuf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/sembuf.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,22 @@
+#ifndef _ASM_SEMBUF_H
+#define _ASM_SEMBUF_H
+
+/* 
+ * The semid64_ds structure for the MIPS architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 2 miscellaneous 64-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+};
+
+#endif /* _ASM_SEMBUF_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/serial.h linux/include/asm-mips/serial.h
--- v2.3.47/linux/include/asm-mips/serial.h	Tue Oct 20 13:52:54 1998
+++ linux/include/asm-mips/serial.h	Thu Feb 24 22:52:30 2000
@@ -1,6 +1,7 @@
-/* $Id: serial.h,v 1.3 1998/08/28 15:55:38 ralf Exp $
+/* $Id: serial.h,v 1.9 2000/02/16 01:45:55 ralf Exp $
  *
- * include/asm-mips/serial.h
+ * Copyright (C) 1999 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/config.h>
 #include <asm/bootinfo.h>
@@ -16,8 +17,8 @@
 #define BASE_BAUD ( 1843200 / 16 )
 
 #ifndef CONFIG_OLIVETTI_M700
-/* Some Jazz machines seem to have an 8MHz crystal clock but I don't know
-   exactly which ones ... XXX */
+   /* Some Jazz machines seem to have an 8MHz crystal clock but I don't know
+      exactly which ones ... XXX */
 #define JAZZ_BASE_BAUD ( 8000000 / 16 ) /* ( 3072000 / 16) */
 #else
 /* but the M700 isn't such a strange beast */
@@ -38,6 +39,9 @@
 #define ACCENT_FLAGS 0
 #define BOCA_FLAGS 0
 #define HUB6_FLAGS 0
+#define RS_TABLE_SIZE	64
+#else
+#define RS_TABLE_SIZE
 #endif
 
 /*
@@ -57,12 +61,13 @@
 #define C_P(card,port) (((card)<<6|(port)<<3) + 1)
 
 #ifdef CONFIG_MIPS_JAZZ
-#define JAZZ_SERIAL_PORT_DEFNS			\
-	/* UART CLK   PORT IRQ     FLAGS        */			\
-	{ 0, JAZZ_BASE_BAUD, JAZZ_SERIAL1_BASE,         /* ttyS0 */	\
-	  JAZZ_SERIAL1_IRQ, STD_COM_FLAGS },				\
-	{ 0, JAZZ_BASE_BAUD, JAZZ_SERIAL2_BASE,         /* ttyS1 */	\
-	  JAZZ_SERIAL2_IRQ, STD_COM_FLAGS },
+#define _JAZZ_SERIAL_INIT(int, base)					\
+	{ baud_base: JAZZ_BASE_BAUD, irq: int, flags: STD_COM_FLAGS,	\
+	  iomem_base: (u8 *) base, iomem_reg_shift: 0,			\
+	  io_type: SERIAL_IO_MEM }
+#define JAZZ_SERIAL_PORT_DEFNS						\
+	_JAZZ_SERIAL_INIT(JAZZ_SERIAL1_IRQ, JAZZ_SERIAL1_BASE),		\
+	_JAZZ_SERIAL_INIT(JAZZ_SERIAL2_IRQ, JAZZ_SERIAL2_BASE),
 #else
 #define JAZZ_SERIAL_PORT_DEFNS
 #endif
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sgi/sgi.h linux/include/asm-mips/sgi/sgi.h
--- v2.3.47/linux/include/asm-mips/sgi/sgi.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/sgi/sgi.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,42 @@
+/* $Id: sgi.h,v 1.1 1999/10/21 00:23:05 ralf Exp $
+ * sgi.h: Definitions specific to SGI machines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@sgi.com)
+ */
+#ifndef _MIPS_SGI_H
+#define _MIPS_SGI_H
+
+/* UP=UniProcessor MP=MultiProcessor(capable) */
+enum sgi_mach {
+	ip4,     /* R2k UP */
+	ip5,     /* R2k MP */
+	ip6,     /* R3k UP */
+	ip7,     /* R3k MP */
+	ip9,     /* R3k UP */
+	ip12,    /* R3kA UP, Indigo */
+	ip15,    /* R3kA MP */
+	ip17,    /* R4K UP */
+	ip19,    /* R4K MP */
+	ip20,    /* R4K UP, Indigo */
+	ip21,    /* TFP MP */
+	ip22,    /* R4x00 UP, Indigo2 */
+	ip25,    /* R10k MP */
+	ip26,    /* TFP UP, Indigo2 */
+	ip28,    /* R10k UP, Indigo2 */
+	ip30,
+	ip32,
+};
+
+extern enum sgi_mach sgimach;
+extern void sgi_sysinit(void);
+
+/* Many I/O space registers are byte sized and are contained within
+ * one byte per word, specifically the MSB, this macro helps out.
+ */
+#ifdef __MIPSEL__
+#define SGI_MSB(regaddr)   (regaddr)
+#else
+#define SGI_MSB(regaddr)   ((regaddr) | 0x3)
+#endif
+
+#endif /* !(_MIPS_SGI_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sgi/sgihpc.h linux/include/asm-mips/sgi/sgihpc.h
--- v2.3.47/linux/include/asm-mips/sgi/sgihpc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/sgi/sgihpc.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,372 @@
+/* $Id: sgihpc.h,v 1.2 1999/12/06 23:13:21 ralf Exp $
+ *
+ * sgihpc.h: Various HPC I/O controller defines.  The HPC is basically
+ *           the approximate functional equivalent of the Sun SYSIO
+ *           on SGI INDY machines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1998 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _MIPS_SGIHPC_H
+#define _MIPS_SGIHPC_H
+
+#include <asm/page.h>
+
+extern int sgi_has_ioc2; /* to know if we have older ioc1 or ioc2. */
+extern int sgi_guiness;  /* GUINESS or FULLHOUSE machine. */
+extern int sgi_boardid;  /* Board revision. */
+
+/* An HPC dma descriptor. */
+struct hpc_dma_desc {
+	unsigned long pbuf;      /* physical address of data buffer */
+	unsigned long cntinfo;   /* counter and info bits */
+#define HPCDMA_EOX    0x80000000 /* last desc in chain for tx */
+#define HPCDMA_EOR    0x80000000 /* last desc in chain for rx */
+#define HPCDMA_EOXP   0x40000000 /* end of packet for tx */
+#define HPCDMA_EORP   0x40000000 /* end of packet for rx */
+#define HPCDMA_XIE    0x20000000 /* irq generated when at end of this desc */
+#define HPCDMA_XIU    0x01000000 /* Tx buffer in use by CPU. */
+#define HPCDMA_EIPC   0x00ff0000 /* SEEQ ethernet special xternal bytecount */
+#define HPCDMA_ETXD   0x00008000 /* set to one by HPC when packet tx'd */
+#define HPCDMA_OWN    0x00004000 /* Denotes ring buffer ownership on rx */
+#define HPCDMA_BCNT   0x00003fff /* size in bytes of this dma buffer */
+
+	unsigned long pnext;     /* paddr of next hpc_dma_desc if any */
+};
+
+typedef volatile unsigned long hpcreg;
+
+/* HPC1 stuff. */
+
+/* HPC3 stuff. */
+
+/* The set of regs for each HPC3 pbus dma channel. */
+struct hpc3_pbus_dmacregs {
+	hpcreg pbdma_bptr; /* pbus dma channel buffer ptr */
+	hpcreg pbdma_dptr; /* pbus dma channel desc ptr */
+	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
+	hpcreg pbdma_ctrl; /* pbus dma channel control reg */
+#define HPC3_PDMACTRL_SEL  0x00000002 /* little endian transfer */
+#define HPC3_PDMACTRL_RCV  0x00000004 /* direction is receive */
+#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */
+#define HPC3_PDMACTRL_ACT  0x00000010 /* start dma transfer */
+#define HPC3_PDMACTRL_LD   0x00000020 /* load enable for ACT */
+#define HPC3_PDMACTRL_RT   0x00000040 /* Use realtime GIO bus servicing */
+#define HPC3_PDMACTRL_HW   0x0000ff00 /* DMA High-water mark */
+#define HPC3_PDMACTRL_FB   0x003f0000 /* Ptr to beginning of fifo */
+#define HPC3_PDMACTRL_FE   0x3f000000 /* Ptr to end of fifo */
+
+	char _unused2[PAGE_SIZE - (sizeof(hpcreg))]; /* padding */
+};
+
+/* The HPC3 scsi registers, this does not include external ones. */
+struct hpc3_scsiregs {
+	hpcreg cbptr;   /* current dma buffer ptr, diagnostic use only */
+	hpcreg ndptr;   /* next dma descriptor ptr */
+	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
+	hpcreg bcd;     /* byte count info */
+#define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */
+#define HPC3_SBCD_XIE     0x00004000 /* Send IRQ when done with cur buf */
+#define HPC3_SBCD_EOX     0x00008000 /* Indicates this is last buf in chain */
+
+	hpcreg ctrl;    /* control register */
+#define HPC3_SCTRL_IRQ    0x01 /* IRQ asserted, either dma done or parity */
+#define HPC3_SCTRL_ENDIAN 0x02 /* DMA endian mode, 0=big 1=little */
+#define HPC3_SCTRL_DIR    0x04 /* DMA direction, 1=dev2mem 0=mem2dev */
+#define HPC3_SCTRL_FLUSH  0x08 /* Tells HPC3 to flush scsi fifos */
+#define HPC3_SCTRL_ACTIVE 0x10 /* SCSI DMA channel is active */
+#define HPC3_SCTRL_AMASK  0x20 /* DMA active inhibits PIO */
+#define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */
+#define HPC3_SCTRL_PERR   0x80 /* Bad parity on HPC3 iface to scsi controller */
+
+	hpcreg gfptr;   /* current GIO fifo ptr */
+	hpcreg dfptr;   /* current device fifo ptr */
+	hpcreg dconfig; /* DMA configuration register */
+#define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */
+#define HPC3_SDCFG_D1   0x00006 /* Cycles to spend in D1 state */
+#define HPC3_SDCFG_D2   0x00038 /* Cycles to spend in D2 state */
+#define HPC3_SDCFG_D3   0x001c0 /* Cycles to spend in D3 state */
+#define HPC3_SDCFG_HWAT 0x00e00 /* DMA high water mark */
+#define HPC3_SDCFG_HW   0x01000 /* Enable 16-bit halfword DMA accesses to scsi */
+#define HPC3_SDCFG_SWAP 0x02000 /* Byte swap all DMA accesses */
+#define HPC3_SDCFG_EPAR 0x04000 /* Enable parity checking for DMA */
+#define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */
+#define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */
+
+	hpcreg pconfig; /* PIO configuration register */
+#define HPC3_SPCFG_P3   0x0003 /* Cycles to spend in P3 state */
+#define HPC3_SPCFG_P2W  0x001c /* Cycles to spend in P2 state for writes */
+#define HPC3_SPCFG_P2R  0x01e0 /* Cycles to spend in P2 state for reads */
+#define HPC3_SPCFG_P1   0x0e00 /* Cycles to spend in P1 state */
+#define HPC3_SPCFG_HW   0x1000 /* Enable 16-bit halfword PIO accesses to scsi */
+#define HPC3_SPCFG_SWAP 0x2000 /* Byte swap all PIO accesses */
+#define HPC3_SPCFG_EPAR 0x4000 /* Enable parity checking for PIO */
+#define HPC3_SPCFG_FUJI 0x8000 /* Fujitsu scsi controller mode for faster dma/pio */
+
+	char _unused2[PAGE_SIZE - (6 * sizeof(hpcreg))]; /* padding */
+};
+
+/* SEEQ ethernet HPC3 registers, only one seeq per HPC3. */
+struct hpc3_ethregs {
+	/* Receiver registers. */
+	hpcreg rx_cbptr;   /* current dma buffer ptr, diagnostic use only */
+	hpcreg rx_ndptr;   /* next dma descriptor ptr */
+	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
+	hpcreg rx_bcd;     /* byte count info */
+#define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */
+#define HPC3_ERXBCD_XIE     0x20000000 /* HPC3 interrupts cpu at end of this buf */
+#define HPC3_ERXBCD_EOX     0x80000000 /* flags this as end of descriptor chain */
+
+	hpcreg rx_ctrl;    /* control register */
+#define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */
+#define HPC3_ERXCTRL_STAT6  0x00000040 /* Rdonly irq status */
+#define HPC3_ERXCTRL_STAT7  0x00000080 /* Rdonlt old/new status bit from Seeq */
+#define HPC3_ERXCTRL_ENDIAN 0x00000100 /* Endian for dma channel, little=1 big=0 */
+#define HPC3_ERXCTRL_ACTIVE 0x00000200 /* Tells if DMA transfer is in progress */
+#define HPC3_ERXCTRL_AMASK  0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */
+#define HPC3_ERXCTRL_RBO    0x00000800 /* Receive buffer overflow if set to 1 */
+
+	hpcreg rx_gfptr;   /* current GIO fifo ptr */
+	hpcreg rx_dfptr;   /* current device fifo ptr */
+	hpcreg _unused2;   /* padding */
+	hpcreg rx_reset;   /* reset register */
+#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */
+#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */
+#define HPC3_ERXRST_LBACK  0x4 /* Enable diagnostic loopback mode of Seeq8003 */
+
+	hpcreg rx_dconfig; /* DMA configuration register */
+#define HPC3_ERXDCFG_D1    0x0000f /* Cycles to spend in D1 state for PIO */
+#define HPC3_ERXDCFG_D2    0x000f0 /* Cycles to spend in D2 state for PIO */
+#define HPC3_ERXDCFG_D3    0x00f00 /* Cycles to spend in D3 state for PIO */
+#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
+#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
+#define HPC3_ERXDCFG_FEOP  0x04000 /* Bad packet marker timeout enable */
+#define HPC3_ERXDCFG_FIRQ  0x08000 /* Another bad packet timeout enable */
+#define HPC3_ERXDCFG_PTO   0x30000 /* Programmed timeout value for above two */
+
+	hpcreg rx_pconfig; /* PIO configuration register */
+#define HPC3_ERXPCFG_P1    0x000f /* Cycles to spend in P1 state for PIO */
+#define HPC3_ERXPCFG_P2    0x00f0 /* Cycles to spend in P2 state for PIO */
+#define HPC3_ERXPCFG_P3    0x0f00 /* Cycles to spend in P3 state for PIO */
+#define HPC3_ERXPCFG_TST   0x1000 /* Diagnistic ram test feature bit */
+
+	char _unused3[PAGE_SIZE - (8 * sizeof(hpcreg))]; /* padding */
+
+	/* Transmitter registers. */
+	hpcreg tx_cbptr;   /* current dma buffer ptr, diagnostic use only */
+	hpcreg tx_ndptr;   /* next dma descriptor ptr */
+	char _unused4[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
+	hpcreg tx_bcd;     /* byte count info */
+#define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */
+#define HPC3_ETXBCD_ESAMP   0x10000000 /* if set, too late to add descriptor */
+#define HPC3_ETXBCD_XIE     0x20000000 /* Interrupt cpu at end of cur desc */
+#define HPC3_ETXBCD_EOP     0x40000000 /* Last byte of cur buf is end of packet */
+#define HPC3_ETXBCD_EOX     0x80000000 /* This buf is the end of desc chain */
+
+	hpcreg tx_ctrl;    /* control register */
+#define HPC3_ETXCTRL_STAT30 0x0000000f /* Rdonly copy of seeq tx stat reg */
+#define HPC3_ETXCTRL_STAT4  0x00000010 /* Indicate late collision occurred */
+#define HPC3_ETXCTRL_STAT75 0x000000e0 /* Rdonly irq status from seeq */
+#define HPC3_ETXCTRL_ENDIAN 0x00000100 /* Dma channel endian mode, 1=little 0=big */
+#define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */
+#define HPC3_ETXCTRL_AMASK  0x00000400 /* Indicates ACTIVE inhibits PIO's */
+
+	hpcreg tx_gfptr;   /* current GIO fifo ptr */
+	hpcreg tx_dfptr;   /* current device fifo ptr */
+	char _unused5[PAGE_SIZE - (4 * sizeof(hpcreg))]; /* padding */
+};
+
+struct hpc3_regs {
+	/* First regs for the PBUS 8 dma channels. */
+	struct hpc3_pbus_dmacregs pbdma[8];
+
+	/* Now the HPC scsi registers, we get two scsi reg sets. */
+	struct hpc3_scsiregs scsi_chan0, scsi_chan1;
+
+	/* The SEEQ hpc3 ethernet dma/control registers. */
+	struct hpc3_ethregs ethregs;
+
+	/* Here are where the hpc3 fifo's can be directly accessed
+	 * via PIO accesses.  Under normal operation we never stick
+	 * our grubby paws in here so it's just padding.
+	 */
+	char _unused1[PAGE_SIZE * 24];
+
+	/* HPC3 irq status regs.  Due to a peculiar bug you need to
+	 * look at two different register addresses to get at all of
+	 * the status bits.  The first reg can only reliably report
+	 * bits 4:0 of the status, and the second reg can only
+	 * reliably report bits 9:5 of the hpc3 irq status.  I told
+	 * you it was a peculiar bug. ;-)
+	 */
+	hpcreg istat0;      /* Irq status, only bits <4:0> reliable. */
+#define HPC3_ISTAT_PBIMASK  0x0ff  /* irq bits for pbus devs 0 --> 7 */
+#define HPC3_ISTAT_SC0MASK  0x100  /* irq bit for scsi channel 0 */
+#define HPC3_ISTAT_SC1MASK  0x200  /* irq bit for scsi channel 1 */
+
+	hpcreg gio64_misc;  /* GIO64 misc control bits. */
+#define HPC3_GIOMISC_ERTIME   0x1    /* Enable external timer real time. */
+#define HPC3_GIOMISC_DENDIAN  0x2    /* dma descriptor endian, 1=lit 0=big */
+
+	hpcreg eeprom_data; /* EEPROM data reg. */
+#define HPC3_EEPROM_EPROT     0x01   /* Protect register enable */
+#define HPC3_EEPROM_CSEL      0x02   /* Chip select */
+#define HPC3_EEPROM_ECLK      0x04   /* EEPROM clock */
+#define HPC3_EEPROM_DATO      0x08   /* Data out */
+#define HPC3_EEPROM_DATI      0x10   /* Data in */
+
+	hpcreg istat1;      /* Irq status, only bits <9:5> reliable. */
+	hpcreg gio64_estat; /* GIO64 error interrupt status reg. */
+#define HPC3_GIOESTAT_BLMASK  0x000ff  /* Bus lane where bad parity occurred */
+#define HPC3_GIOESTAT_CTYPE   0x00100  /* Bus cycle type, 0=PIO 1=DMA */
+#define HPC3_GIOESTAT_PIDMSK  0x3f700  /* DMA channel parity identifier */
+
+	/* Now direct PIO per-HPC3 peripheral access to external regs. */
+	char _unused2[0x13fec]; /* Trust me... */
+	hpcreg scsi0_ext[256];  /* SCSI channel 0 external regs */
+	char _unused3[0x07c00]; /* Trust me... */
+	hpcreg scsi1_ext[256];  /* SCSI channel 1 external regs */
+	char _unused4[0x07c00]; /* It'll only hurt a little... */
+
+	/* Did DaveM forget the ethernet external regs?
+	 * Anyhow, they're not here and we need some padding instead.
+	 */
+	char _unused5[0x04000]; /* It'll hurt a lot if you leave this out */
+
+	/* Per-peripheral device external registers and dma/pio control. */
+	hpcreg pbus_extregs[16][256]; /* 2nd indice indexes controller */
+	hpcreg pbus_dmacfgs[8][128]; /* 2nd indice indexes controller */
+#define HPC3_PIODCFG_D3R    0x00000001 /* Cycles to spend in D3 for reads */
+#define HPC3_PIODCFG_D4R    0x0000001e /* Cycles to spend in D4 for reads */
+#define HPC3_PIODCFG_D5R    0x000001e0 /* Cycles to spend in D5 for reads */
+#define HPC3_PIODCFG_D3W    0x00000200 /* Cycles to spend in D3 for writes */
+#define HPC3_PIODCFG_D4W    0x00003c00 /* Cycles to spend in D4 for writes */
+#define HPC3_PIODCFG_D5W    0x0003c000 /* Cycles to spend in D5 for writes */
+#define HPC3_PIODCFG_HWORD  0x00040000 /* Enable 16-bit dma access mode */
+#define HPC3_PIODCFG_EHI    0x00080000 /* Places halfwords on high 16 bits of bus */
+#define HPC3_PIODCFG_RTIME  0x00200000 /* Make this device real time on GIO bus */
+#define HPC3_PIODCFG_BURST  0x07c00000 /* 5 bit burst count for DMA device */
+#define HPC3_PIODCFG_DRQLV  0x08000000 /* Use live pbus_dreq unsynchronized signal */
+
+	hpcreg pbus_piocfgs[64][10]; /* 2nd indice indexes controller */
+#define HPC3_PIOPCFG_RP2    0x00001  /* Cycles to spend in P2 state for reads */
+#define HPC3_PIOPCFG_RP3    0x0001e  /* Cycles to spend in P3 state for reads */
+#define HPC3_PIOPCFG_RP4    0x001e0  /* Cycles to spend in P4 state for reads */
+#define HPC3_PIOPCFG_WP2    0x00200  /* Cycles to spend in P2 state for writes */
+#define HPC3_PIOPCFG_WP3    0x03c00  /* Cycles to spend in P3 state for writes */
+#define HPC3_PIOPCFG_WP4    0x3c000  /* Cycles to spend in P4 state for writes */
+#define HPC3_PIOPCFG_HW     0x40000  /* Enable 16-bit PIO accesses */
+#define HPC3_PIOPCFG_EHI    0x80000  /* Place even address bits in bits <15:8> */
+
+	/* PBUS PROM control regs. */
+	hpcreg pbus_promwe;     /* PROM write enable register */
+#define HPC3_PROM_WENAB     0x1 /* Enable writes to the PROM */
+
+	char _unused6[0x800 - sizeof(hpcreg)];
+	hpcreg pbus_promswap;   /* Chip select swap reg */
+#define HPC3_PROM_SWAP      0x1 /* invert GIO addr bit to select prom0 or prom1 */
+
+	char _unused7[0x800 - sizeof(hpcreg)];
+	hpcreg pbus_gout;       /* PROM general purpose output reg */
+#define HPC3_PROM_STAT      0x1 /* General purpose status bit in gout */
+
+	char _unused8[0x1000 - sizeof(hpcreg)];
+	hpcreg pbus_promram[16384]; /* 64k of PROM battery backed ram */
+};
+
+/* It is possible to have two HPC3's within the address space on
+ * one machine, though only having one is more likely on an INDY.
+ * Controller 0 lives at physical address 0x1fb80000 and the controller
+ * 1 if present lives at address 0x1fb00000.
+ */
+extern struct hpc3_regs *hpc3c0, *hpc3c1;
+#define HPC3_CHIP0_PBASE   0x1fb80000 /* physical */
+#define HPC3_CHIP1_PBASE   0x1fb00000 /* physical */
+
+/* Control and misc status information, these live in pbus channel 6. */
+struct hpc3_miscregs {
+	hpcreg pdata, pctrl, pstat, pdmactrl, pistat, pimask;
+	hpcreg ptimer1, ptimer2, ptimer3, ptimer4;
+	hpcreg _unused1[2];
+	hpcreg ser1cmd, ser1data;
+	hpcreg ser0cmd, ser0data;
+	hpcreg kbdmouse0, kbdmouse1;
+	hpcreg gcsel, genctrl, panel;
+	hpcreg _unused2;
+	hpcreg sysid;
+	hpcreg _unused3;
+	hpcreg read, _unused4;
+	hpcreg dselect;
+#define HPC3_DSELECT_SCLK10MHZ   0x00 /* use 10MHZ serial clock */
+#define HPC3_DSELECT_ISDNB       0x01 /* enable isdn B */
+#define HPC3_DSELECT_ISDNA       0x02 /* enable isdn A */
+#define HPC3_DSELECT_LPR         0x04 /* use parallel DMA */
+#define HPC3_DSELECT_SCLK667MHZ  0x10 /* use 6.67MHZ serial clock */
+#define HPC3_DSELECT_SCLKEXT     0x20 /* use external serial clock */
+
+	hpcreg _unused5;
+	hpcreg write1;
+#define HPC3_WRITE1_PRESET    0x01  /* 0=LPR_RESET, 1=NORMAL */
+#define HPC3_WRITE1_KMRESET   0x02  /* 0=KBDMOUSE_RESET, 1=NORMAL */
+#define HPC3_WRITE1_ERESET    0x04  /* 0=EISA_RESET, 1=NORMAL */
+#define HPC3_WRITE1_GRESET    0x08  /* 0=MAGIC_GIO_RESET, 1=NORMAL */
+#define HPC3_WRITE1_LC0OFF    0x10  /* turn led off (guiness=red, else green) */
+#define HPC3_WRITE1_LC1OFF    0x20  /* turn led off (guiness=green, else amber) */
+
+	hpcreg _unused6;
+	hpcreg write2;
+#define HPC3_WRITE2_NTHRESH  0x01 /* use 4.5db threshhold */
+#define HPC3_WRITE2_TPSPEED  0x02 /* use 100ohm TP speed */
+#define HPC3_WRITE2_EPSEL    0x04 /* force cable mode: 1=AUI 0=TP */
+#define HPC3_WRITE2_EASEL    0x08 /* 1=autoselect 0=manual cable selection */
+#define HPC3_WRITE2_U1AMODE  0x10 /* 1=PC 0=MAC UART mode */
+#define HPC3_WRITE2_U0AMODE  0x20 /* 1=PC 0=MAC UART mode */
+#define HPC3_WRITE2_MLO      0x40 /* 1=4.75V 0=+5V */
+#define HPC3_WRITE2_MHI      0x80 /* 1=5.25V 0=+5V */
+};
+extern struct hpc3_miscregs *hpc3mregs;
+#define HPC3_MREGS_PBASE   0x1fbd9800 /* physical */
+
+/* We need software copies of these because they are write only. */
+extern unsigned int sgi_hpc_write1, sgi_hpc_write2;
+
+struct hpc_keyb {
+#ifdef __MIPSEB__
+	unsigned char _unused0[3];
+	volatile unsigned char data;
+	unsigned char _unused1[3];
+	volatile unsigned char command;
+#else
+	volatile unsigned char data;
+	unsigned char _unused0[3];
+	volatile unsigned char command;
+	unsigned char _unused1[3];
+#endif
+};
+
+/* Indy RTC  */
+
+/* The layout of registers for the INDY Dallas 1286 clock chipset. */
+struct indy_clock {
+	volatile unsigned int hsec;
+	volatile unsigned int sec;
+	volatile unsigned int min;
+	volatile unsigned int malarm;
+	volatile unsigned int hr;
+	volatile unsigned int halarm;
+	volatile unsigned int day;
+	volatile unsigned int dalarm;
+	volatile unsigned int date;
+	volatile unsigned int month;
+	volatile unsigned int year;
+	volatile unsigned int cmd;
+	volatile unsigned int whsec;
+	volatile unsigned int wsec;
+	volatile unsigned int _unused0[50];
+};
+
+#define INDY_CLOCK_REGS (KSEG1ADDR(0x1fbe0000))
+
+extern void sgihpc_init(void);
+
+#endif /* !(_MIPS_SGIHPC_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sgi/sgimc.h linux/include/asm-mips/sgi/sgimc.h
--- v2.3.47/linux/include/asm-mips/sgi/sgimc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/sgi/sgimc.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,223 @@
+/* $Id: sgimc.h,v 1.2 1999/12/06 23:13:21 ralf Exp $
+ * sgimc.h: Definitions for memory controller hardware found on
+ *          SGI IP20, IP22, IP26, and IP28 machines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+
+#ifndef _MIPS_SGIMC_H
+#define _MIPS_SGIMC_H
+
+struct sgimc_misc_ctrl {
+	unsigned long _unused1;
+	volatile unsigned long cpuctrl0;     /* CPU control register 0, readwrite */
+#define SGIMC_CCTRL0_REFS         0x0000000f /* REFS mask */
+#define SGIMC_CCTRL0_EREFRESH     0x00000010 /* Memory refresh enable */
+#define SGIMC_CCTRL0_EPERRGIO     0x00000020 /* GIO parity error enable */
+#define SGIMC_CCTRL0_EPERRMEM     0x00000040 /* Main mem parity error enable */
+#define SGIMC_CCTRL0_EPERRCPU     0x00000080 /* CPU bus parity error enable */
+#define SGIMC_CCTRL0_WDOG         0x00000100 /* Watchdog timer enable */
+#define SGIMC_CCTRL0_SYSINIT      0x00000200 /* System init bit */
+#define SGIMC_CCTRL0_GFXRESET     0x00000400 /* Graphics interface reset */
+#define SGIMC_CCTRL0_EISALOCK     0x00000800 /* Lock CPU from memory for EISA */
+#define SGIMC_CCTRL0_EPERRSCMD    0x00001000 /* SysCMD bus parity error enable */
+#define SGIMC_CCTRL0_IENAB        0x00002000 /* Allow interrupts from MC */
+#define SGIMC_CCTRL0_ESNOOP       0x00004000 /* Snooping I/O enable */
+#define SGIMC_CCTRL0_EPROMWR      0x00008000 /* Prom writes from cpu enable */
+#define SGIMC_CCTRL0_WRESETPMEM   0x00010000 /* Perform warm reset, preserves mem */
+#define SGIMC_CCTRL0_LENDIAN      0x00020000 /* Put MC in little-endian mode */
+#define SGIMC_CCTRL0_WRESETDMEM   0x00040000 /* Warm reset, destroys mem contents */
+#define SGIMC_CCTRL0_CMEMBADPAR   0x02000000 /* Generate bad perr from cpu to mem */
+#define SGIMC_CCTRL0_R4KNOCHKPARR 0x04000000 /* Don't chk parity on mem data reads */
+#define SGIMC_CCTRL0_GIOBTOB      0x08000000 /* Allow GIO back to back writes */
+
+	unsigned long _unused2;
+	volatile unsigned long cpuctrl1;     /* CPU control register 1, readwrite */
+#define SGIMC_CCTRL1_EGIOTIMEO    0x00000010 /* GIO bus timeout enable */
+#define SGIMC_CCTRL1_FIXEDEHPC    0x00001000 /* Fixed HPC endianness */
+#define SGIMC_CCTRL1_LITTLEHPC    0x00002000 /* Little endian HPC */
+#define SGIMC_CCTRL1_FIXEDEEXP0   0x00004000 /* Fixed EXP0 endianness */
+#define SGIMC_CCTRL1_LITTLEEXP0   0x00008000 /* Little endian EXP0 */
+#define SGIMC_CCTRL1_FIXEDEEXP1   0x00010000 /* Fixed EXP1 endianness */
+#define SGIMC_CCTRL1_LITTLEEXP1   0x00020000 /* Little endian EXP1 */
+
+	unsigned long _unused3;
+	volatile unsigned long watchdogt;    /* Watchdog reg rdonly, write clears */
+
+	unsigned long _unused4;
+	volatile unsigned long systemid;     /* MC system ID register, readonly */
+#define SGIMC_SYSID_MASKREV       0x0000000f /* Revision of MC controller */
+#define SGIMC_SYSID_EPRESENT      0x00000010 /* Indicates presence of EISA bus */
+
+	unsigned long _unused5[3];
+	volatile unsigned long divider;      /* Divider reg for RPSS */
+
+	unsigned long _unused6;
+	volatile unsigned char eeprom;       /* EEPROM byte reg for r4k */
+#define SGIMC_EEPROM_PRE          0x00000001 /* eeprom chip PRE pin assertion */
+#define SGIMC_EEPROM_CSEL         0x00000002 /* Active high, eeprom chip select */
+#define SGIMC_EEPROM_SECLOCK      0x00000004 /* EEPROM serial clock */
+#define SGIMC_EEPROM_SDATAO       0x00000008 /* Serial EEPROM data-out */
+#define SGIMC_EEPROM_SDATAI       0x00000010 /* Serial EEPROM data-in */
+
+	unsigned char _unused7[3];
+	unsigned long _unused8[3];
+	volatile unsigned short rcntpre;     /* Preload refresh counter */
+
+	unsigned short _unused9;
+	unsigned long _unused9a;
+	volatile unsigned short rcounter;    /* Readonly refresh counter */
+
+	unsigned short _unused10;
+	unsigned long _unused11[13];
+	volatile unsigned long gioparm;      /* Parameter word for GIO64 */
+#define SGIMC_GIOPARM_HPC64       0x00000001 /* HPC talks to GIO using 64-bits */
+#define SGIMC_GIOPARM_GFX64       0x00000002 /* GFX talks to GIO using 64-bits */
+#define SGIMC_GIOPARM_EXP064      0x00000004 /* EXP(slot0) talks using 64-bits */
+#define SGIMC_GIOPARM_EXP164      0x00000008 /* EXP(slot1) talks using 64-bits */
+#define SGIMC_GIOPARM_EISA64      0x00000010 /* EISA bus talks 64-bits to GIO */
+#define SGIMC_GIOPARM_HPC264      0x00000020 /* 2nd HPX talks 64-bits to GIO */
+#define SGIMC_GIOPARM_RTIMEGFX    0x00000040 /* GFX device has realtime attr */
+#define SGIMC_GIOPARM_RTIMEEXP0   0x00000080 /* EXP(slot0) has realtime attr */
+#define SGIMC_GIOPARM_RTIMEEXP1   0x00000100 /* EXP(slot1) has realtime attr */
+#define SGIMC_GIOPARM_MASTEREISA  0x00000200 /* EISA bus can act as bus master */
+#define SGIMC_GIOPARM_ONEBUS      0x00000400 /* Exists one GIO64 pipelined bus */
+#define SGIMC_GIOPARM_MASTERGFX   0x00000800 /* GFX can act as a bus master */
+#define SGIMC_GIOPARM_MASTEREXP0  0x00001000 /* EXP(slot0) can bus master */
+#define SGIMC_GIOPARM_MASTEREXP1  0x00002000 /* EXP(slot1) can bus master */
+#define SGIMC_GIOPARM_PLINEEXP0   0x00004000 /* EXP(slot0) has pipeline attr */
+#define SGIMC_GIOPARM_PLINEEXP1   0x00008000 /* EXP(slot1) has pipeline attr */
+
+	unsigned long _unused13;
+	volatile unsigned short cputp;       /* CPU bus arb time period */
+
+	unsigned short _unused14;
+	unsigned long _unused15[3];
+	volatile unsigned short lbursttp;    /* Time period for long bursts */
+
+	unsigned short _unused16;
+	unsigned long _unused17[9];
+	volatile unsigned long mconfig0;     /* Memory config register zero */
+	unsigned long _unused18;
+	volatile unsigned long mconfig1;     /* Memory config register one */
+
+        /* These defines apply to both mconfig registers above. */
+#define SGIMC_MCONFIG_FOURMB     0x00000000  /* Physical ram = 4megs */
+#define SGIMC_MCONFIG_EIGHTMB    0x00000100  /* Physical ram = 8megs */
+#define SGIMC_MCONFIG_SXTEENMB   0x00000300  /* Physical ram = 16megs */
+#define SGIMC_MCONFIG_TTWOMB     0x00000700  /* Physical ram = 32megs */
+#define SGIMC_MCONFIG_SFOURMB    0x00000f00  /* Physical ram = 64megs */
+#define SGIMC_MCONFIG_OTEIGHTMB  0x00001f00  /* Physical ram = 128megs */
+#define SGIMC_MCONFIG_RMASK      0x00001f00  /* Ram config bitmask */
+
+	unsigned long _unused19;
+	volatile unsigned long cmacc;        /* Mem access config for CPU */
+	unsigned long _unused20;
+	volatile unsigned long gmacc;        /* Mem access config for GIO */
+
+	/* This define applies to both cmacc and gmacc registers above. */
+#define SGIMC_MACC_ALIASBIG       0x20000000 /* 512MB home for alias */
+
+	/* Error address/status regs from GIO and CPU perspectives. */
+	unsigned long _unused21;
+	volatile unsigned long cerr;         /* Error address reg for CPU */
+	unsigned long _unused22;
+	volatile unsigned long cstat;        /* Status reg for CPU */
+	unsigned long _unused23;
+	volatile unsigned long gerr;         /* Error address reg for GIO */
+	unsigned long _unused24;
+	volatile unsigned long gstat;        /* Status reg for GIO */
+
+	/* Special hard bus locking registers. */
+	unsigned long _unused25;
+	volatile unsigned char syssembit;    /* Uni-bit system semaphore */
+	unsigned char _unused26[3];
+	unsigned long _unused27;
+	volatile unsigned char mlock;        /* Global GIO memory access lock */
+	unsigned char _unused28[3];
+	unsigned long _unused29;
+	volatile unsigned char elock;        /* Locks EISA from GIO accesses */
+
+	/* GIO dma control registers. */
+	unsigned char _unused30[3];
+	unsigned long _unused31[14];
+	volatile unsigned long gio_dma_trans;/* DMA mask to translation GIO addrs */
+	unsigned long _unused32;
+	volatile unsigned long gio_dma_sbits;/* DMA GIO addr substitution bits */
+	unsigned long _unused33;
+	volatile unsigned long dma_intr_cause; /* DMA IRQ cause indicator bits */
+	unsigned long _unused34;
+	volatile unsigned long dma_ctrl;     /* Main DMA control reg */
+
+	/* DMA TLB entry 0 */
+	unsigned long _unused35;
+	volatile unsigned long dtlb_hi0;
+	unsigned long _unused36;
+	volatile unsigned long dtlb_lo0;
+
+	/* DMA TLB entry 1 */
+	unsigned long _unused37;
+	volatile unsigned long dtlb_hi1;
+	unsigned long _unused38;
+	volatile unsigned long dtlb_lo1;
+
+	/* DMA TLB entry 2 */
+	unsigned long _unused39;
+	volatile unsigned long dtlb_hi2;
+	unsigned long _unused40;
+	volatile unsigned long dtlb_lo2;
+
+	/* DMA TLB entry 3 */
+	unsigned long _unused41;
+	volatile unsigned long dtlb_hi3;
+	unsigned long _unused42;
+	volatile unsigned long dtlb_lo3;
+};
+
+/* MC misc control registers live at physical 0x1fa00000. */
+extern struct sgimc_misc_ctrl *mcmisc_regs;
+extern u32 *rpsscounter;          	/* Chirps at 100ns */
+
+struct sgimc_dma_ctrl {
+	unsigned long _unused1;
+	volatile unsigned long maddronly;   /* Address DMA goes at */
+	unsigned long _unused2;
+	volatile unsigned long maddrpdeflts; /* Same as above, plus set defaults */
+	unsigned long _unused3;
+	volatile unsigned long dmasz;       /* DMA count */
+	unsigned long _unused4;
+	volatile unsigned long ssize;       /* DMA stride size */
+	unsigned long _unused5;
+	volatile unsigned long gmaddronly;  /* Set GIO DMA but do not start trans */
+	unsigned long _unused6;
+	volatile unsigned long dmaddnpgo;   /* Set GIO DMA addr + start transfer */
+	unsigned long _unused7;
+	volatile unsigned long dmamode;     /* DMA mode config bit settings */
+	unsigned long _unused8;
+	volatile unsigned long dmacount;    /* Zoom and byte count for DMA */
+	unsigned long _unused9;
+	volatile unsigned long dmastart;    /* Pedal to the metal. */
+	unsigned long _unused10;
+	volatile unsigned long dmarunning;  /* DMA op is in progress */
+	unsigned long _unused11;
+
+	/* Set dma addr, defaults, and kick it */
+	volatile unsigned long maddr_defl_go; /* go go go! -lm */
+};
+
+/* MC controller dma regs live at physical 0x1fa02000. */
+extern struct sgimc_dma_ctrl *dmactrlregs;
+
+/* Base location of the two ram banks found in IP2[0268] machines. */
+#define SGIMC_SEG0_BADDR     0x08000000
+#define SGIMC_SEG1_BADDR     0x20000000
+
+/* Maximum size of the above banks are per machine. */
+extern unsigned long sgimc_seg0_size, sgimc_seg1_size;
+#define SGIMC_SEG0_SIZE_ALL         0x10000000 /* 256MB */
+#define SGIMC_SEG1_SIZE_IP20_IP22   0x08000000 /* 128MB */
+#define SGIMC_SEG1_SIZE_IP26_IP28   0x20000000 /* 512MB */
+
+extern void sgimc_init(void);
+
+#endif /* !(_MIPS_SGIMC_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sgi/sgint23.h linux/include/asm-mips/sgi/sgint23.h
--- v2.3.47/linux/include/asm-mips/sgi/sgint23.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/sgi/sgint23.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,214 @@
+/* $Id: sgint23.h,v 1.1 1999/10/21 00:23:05 ralf Exp $
+ *
+ * sgint23.h: Defines for the SGI INT2 and INT3 chipsets.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - INT2 corrections
+ */
+#ifndef _ASM_SGINT23_H
+#define _ASM_SGINT23_H
+
+/* These are the virtual IRQ numbers, we divide all IRQ's into
+ * 'spaces', the 'space' determines where and how to enable/disable
+ * that particular IRQ on an SGI machine.  Add new 'spaces' as new
+ * IRQ hardware is supported.
+ */
+#define SGINT_LOCAL0   0   /* INDY has 8 local0 irq levels */
+#define SGINT_LOCAL1   8   /* INDY has 8 local1 irq levels */
+#define SGINT_LOCAL2   16  /* INDY has 8 local2 vectored irq levels */
+#define SGINT_LOCAL3   24  /* INDY has 8 local3 vectored irq levels */
+#define SGINT_GIO      32  /* INDY has 9 GIO irq levels */
+#define SGINT_HPCDMA   41  /* INDY has 11 HPCDMA irq _sources_ */
+#define SGINT_END      52  /* End of 'spaces' */
+
+/* Individual interrupt definitions for the INDY and Indigo2
+ */
+
+#define SGI_WD93_0_IRQ	SGINT_LOCAL0 + 1	/* 1st onboard WD93 */
+#define SGI_WD93_1_IRQ	SGINT_LOCAL0 + 2	/* 2nd onboard WD93 */
+#define SGI_ENET_IRQ	SGINT_LOCAL0 + 3	/* onboard ethernet */
+
+#define SGI_PANEL_IRQ	SGINT_LOCAL1 + 1	/* front panel */
+
+#define SGI_EISA_IRQ	SGINT_LOCAL2 + 3	/* EISA interrupts */
+#define SGI_KEYBOARD_IRQ	SGINT_LOCAL2 + 4	/* keyboard */
+#define SGI_SERIAL_IRQ	SGINT_LOCAL2 + 5	/* onboard serial */
+
+/* Individual interrupt definitions for the INDY and Indigo2
+ */
+
+#define SGI_WD93_0_IRQ	SGINT_LOCAL0 + 1	/* 1st onboard WD93 */
+#define SGI_WD93_1_IRQ	SGINT_LOCAL0 + 2	/* 2nd onboard WD93 */
+#define SGI_ENET_IRQ	SGINT_LOCAL0 + 3	/* onboard ethernet */
+
+#define SGI_PANEL_IRQ	SGINT_LOCAL1 + 1	/* front panel */
+
+#define SGI_EISA_IRQ	SGINT_LOCAL2 + 3	/* EISA interrupts */
+#define SGI_KEYBOARD_IRQ	SGINT_LOCAL2 + 4	/* keyboard */
+#define SGI_SERIAL_IRQ	SGINT_LOCAL2 + 5	/* onboard serial */
+
+/* INT2 occupies HPC PBUS slot 4, INT3 uses slot 6. */
+#define SGI_INT2_BASE 0x1fbd9000 /* physical */
+#define SGI_INT3_BASE 0x1fbd9880 /* physical */
+
+struct sgi_ioc_ints {
+#ifdef __MIPSEB__
+	unsigned char _unused0[3];
+	volatile unsigned char istat0;    /* Interrupt status zero */
+#else
+	volatile unsigned char istat0;    /* Interrupt status zero */
+	unsigned char _unused0[3];
+#endif
+#define ISTAT0_FFULL           0x01
+#define ISTAT0_SCSI0           0x02
+#define ISTAT0_SCSI1           0x04
+#define ISTAT0_ENET            0x08
+#define ISTAT0_GFXDMA          0x10
+#define ISTAT0_LPR             0x20
+#define ISTAT0_HPC2            0x40
+#define ISTAT0_LIO2            0x80
+
+#ifdef __MIPSEB__
+	unsigned char _unused1[3];
+	volatile unsigned char imask0;    /* Interrupt mask zero */
+	unsigned char _unused2[3];
+	volatile unsigned char istat1;    /* Interrupt status one */
+#else
+	volatile unsigned char imask0;    /* Interrupt mask zero */
+	unsigned char _unused1[3];
+	volatile unsigned char istat1;    /* Interrupt status one */
+	unsigned char _unused2[3];
+#endif
+#define ISTAT1_ISDNI           0x01
+#define ISTAT1_PWR             0x02
+#define ISTAT1_ISDNH           0x04
+#define ISTAT1_LIO3            0x08
+#define ISTAT1_HPC3            0x10
+#define ISTAT1_AFAIL           0x20
+#define ISTAT1_VIDEO           0x40
+#define ISTAT1_GIO2            0x80
+
+#ifdef __MIPSEB__
+	unsigned char _unused3[3];
+	volatile unsigned char imask1;    /* Interrupt mask one */
+	unsigned char _unused4[3];
+	volatile unsigned char vmeistat;  /* VME interrupt status */
+	unsigned char _unused5[3];
+	volatile unsigned char cmeimask0; /* VME interrupt mask zero */
+	unsigned char _unused6[3];
+	volatile unsigned char cmeimask1; /* VME interrupt mask one */
+	unsigned char _unused7[3];
+	volatile unsigned char cmepol;    /* VME polarity */
+#else
+	volatile unsigned char imask1;    /* Interrupt mask one */
+	unsigned char _unused3[3];
+	volatile unsigned char vmeistat;  /* VME interrupt status */
+	unsigned char _unused4[3];
+	volatile unsigned char cmeimask0; /* VME interrupt mask zero */
+	unsigned char _unused5[3];
+	volatile unsigned char cmeimask1; /* VME interrupt mask one */
+	unsigned char _unused6[3];
+	volatile unsigned char cmepol;    /* VME polarity */
+	unsigned char _unused7[3];
+#endif
+};
+
+struct sgi_ioc_timers {
+#ifdef __MIPSEB__
+	unsigned char _unused0[3];
+	volatile unsigned char tcnt0;  /* counter 0 */
+	unsigned char _unused1[3];
+	volatile unsigned char tcnt1;  /* counter 1 */
+	unsigned char _unused2[3];
+	volatile unsigned char tcnt2;  /* counter 2 */
+	unsigned char _unused3[3];
+	volatile unsigned char tcword; /* control word */
+#else
+	volatile unsigned char tcnt0;  /* counter 0 */
+	unsigned char _unused0[3];
+	volatile unsigned char tcnt1;  /* counter 1 */
+	unsigned char _unused1[3];
+	volatile unsigned char tcnt2;  /* counter 2 */
+	unsigned char _unused2[3];
+	volatile unsigned char tcword; /* control word */
+	unsigned char _unused3[3];
+#endif
+};
+
+/* Timer control word bits. */
+#define SGINT_TCWORD_BCD    0x01 /* Use BCD mode for counters */
+#define SGINT_TCWORD_MMASK  0x0e /* Mode bitmask. */
+#define SGINT_TCWORD_MITC   0x00 /* IRQ on terminal count (doesn't work) */
+#define SGINT_TCWORD_MOS    0x02 /* One-shot IRQ mode. */
+#define SGINT_TCWORD_MRGEN  0x04 /* Normal rate generation */
+#define SGINT_TCWORD_MSWGEN 0x06 /* Square wave generator mode */
+#define SGINT_TCWORD_MSWST  0x08 /* Software strobe */
+#define SGINT_TCWORD_MHWST  0x0a /* Hardware strobe */
+#define SGINT_TCWORD_CMASK  0x30 /* Command mask */
+#define SGINT_TCWORD_CLAT   0x00 /* Latch command */
+#define SGINT_TCWORD_CLSB   0x10 /* LSB read/write */
+#define SGINT_TCWORD_CMSB   0x20 /* MSB read/write */
+#define SGINT_TCWORD_CALL   0x30 /* Full counter read/write */
+#define SGINT_TCWORD_CNT0   0x00 /* Select counter zero */
+#define SGINT_TCWORD_CNT1   0x40 /* Select counter one */
+#define SGINT_TCWORD_CNT2   0x80 /* Select counter two */
+#define SGINT_TCWORD_CRBCK  0xc0 /* Readback command */
+
+#define SGINT_TCSAMP_COUNTER  10255
+
+/* FIXME: What does this really look like?  It was written to have
+ * 17 registers, but there are only 16 in my Indigo2.
+ * I guessed at which one to remove...  	- andrewb
+ */
+struct sgi_int2_regs {
+	struct sgi_ioc_ints ints;
+
+	volatile unsigned long ledbits;   /* LED control bits */
+#define INT2_LED_TXCLK         0x01       /* GPI to TXCLK enable */
+#define INT2_LED_SERSLCT0      0x02       /* serial port0: 0=apple 1=pc */
+#define INT2_LED_SERSLCT1      0x04       /* serial port1: 0=apple 1=pc */
+#define INT2_LED_CHEAPER       0x08       /* 0=cheapernet 1=ethernet */
+#define INT2_LED_POWEROFF      0x10       /* Power-off request, active high */
+
+#ifdef __MIPSEB__
+	unsigned char _unused0[3];
+	volatile unsigned char tclear;    /* Timer clear strobe address */
+#else
+	volatile unsigned char tclear;    /* Timer clear strobe address */
+	unsigned char _unused0[3];
+#endif
+#define INT2_TCLEAR_T0CLR      0x1        /* Clear timer0 IRQ */
+#define INT2_TCLEAR_T1CLR      0x2        /* Clear timer1 IRQ */
+/* I am guesing there are only two unused registers here 
+ * but I could be wrong...			- andrewb
+ */
+/*	unsigned long _unused[3]; */
+	unsigned long _unused[2];
+	struct sgi_ioc_timers timers;
+};
+
+struct sgi_int3_regs {
+	struct sgi_ioc_ints ints;
+
+#ifdef __MIPSEB__
+	unsigned char _unused0[3];
+	volatile unsigned char tclear;    /* Timer clear strobe address */
+#else
+	volatile unsigned char tclear;    /* Timer clear strobe address */
+	unsigned char _unused0[3];
+#endif
+	volatile unsigned long estatus;   /* Error status reg */
+	unsigned long _unused1[2];
+	struct sgi_ioc_timers timers;
+};
+
+extern struct sgi_int2_regs *sgi_i2regs;
+extern struct sgi_int3_regs *sgi_i3regs;
+extern struct sgi_ioc_ints *ioc_icontrol;
+extern struct sgi_ioc_timers *ioc_timers;
+extern volatile unsigned char *ioc_tclear;
+
+extern void sgint_init(void);
+extern void indy_timer_init(void);
+
+#endif /* !(_ASM_SGINT23_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sgi.h linux/include/asm-mips/sgi.h
--- v2.3.47/linux/include/asm-mips/sgi.h	Tue Oct 20 13:52:54 1998
+++ linux/include/asm-mips/sgi.h	Wed Dec 31 16:00:00 1969
@@ -1,42 +0,0 @@
-/* $Id: sgi.h,v 1.1.1.1 1997/06/01 03:17:12 ralf Exp $
- * sgi.h: Definitions specific to SGI machines.
- *
- * Copyright (C) 1996 David S. Miller (dm@sgi.com)
- */
-#ifndef _MIPS_SGI_H
-#define _MIPS_SGI_H
-
-/* UP=UniProcessor MP=MultiProcessor(capable) */
-enum sgi_mach {
-	ip4,     /* R2k UP */
-	ip5,     /* R2k MP */
-	ip6,     /* R3k UP */
-	ip7,     /* R3k MP */
-	ip9,     /* R3k UP */
-	ip12,    /* R3kA UP, Indigo */
-	ip15,    /* R3kA MP */
-	ip17,    /* R4K UP */
-	ip19,    /* R4K MP */
-	ip20,    /* R4K UP, Indigo */
-	ip21,    /* TFP MP */
-	ip22,    /* R4x00 UP, Indigo2 */
-	ip25,    /* R10k MP */
-	ip26,    /* TFP UP, Indigo2 */
-	ip28,    /* R10k UP, Indigo2 */
-	ip30,
-	ip32,
-};
-
-extern enum sgi_mach sgimach;
-extern void sgi_sysinit(void);
-
-/* Many I/O space registers are byte sized and are contained within
- * one byte per word, specifically the MSB, this macro helps out.
- */
-#ifdef __MIPSEL__
-#define SGI_MSB(regaddr)   (regaddr)
-#else
-#define SGI_MSB(regaddr)   ((regaddr) | 0x3)
-#endif
-
-#endif /* !(_MIPS_SGI_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sgialib.h linux/include/asm-mips/sgialib.h
--- v2.3.47/linux/include/asm-mips/sgialib.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/sgialib.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: sgialib.h,v 1.2 1998/07/08 16:01:13 ralf Exp $
+/* $Id: sgialib.h,v 1.4 1999/02/25 20:55:07 tsbogend Exp $
  * sgialib.h: SGI ARCS firmware interface library for the Linux kernel.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sgiarcs.h linux/include/asm-mips/sgiarcs.h
--- v2.3.47/linux/include/asm-mips/sgiarcs.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/sgiarcs.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: sgiarcs.h,v 1.2 1998/07/08 16:01:57 ralf Exp $
+/* $Id: sgiarcs.h,v 1.3 1999/02/25 20:55:08 tsbogend Exp $
  *
  * SGI ARCS firmware interface defines.
  *
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sgihpc.h linux/include/asm-mips/sgihpc.h
--- v2.3.47/linux/include/asm-mips/sgihpc.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/sgihpc.h	Wed Dec 31 16:00:00 1969
@@ -1,374 +0,0 @@
-/* $Id: sgihpc.h,v 1.4 1998/09/16 22:52:42 ralf Exp $
- *
- * sgihpc.h: Various HPC I/O controller defines.  The HPC is basically
- *           the approximate functional equivalent of the Sun SYSIO
- *           on SGI INDY machines.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1998 Ralf Baechle (ralf@gnu.org)
- */
-#ifndef _MIPS_SGIHPC_H
-#define _MIPS_SGIHPC_H
-
-#include <asm/page.h>
-
-extern int sgi_has_ioc2; /* to know if we have older ioc1 or ioc2. */
-extern int sgi_guiness;  /* GUINESS or FULLHOUSE machine. */
-extern int sgi_boardid;  /* Board revision. */
-
-/* An HPC dma descriptor. */
-struct hpc_dma_desc {
-	unsigned long pbuf;      /* physical address of data buffer */
-	unsigned long cntinfo;   /* counter and info bits */
-#define HPCDMA_EOX    0x80000000 /* last desc in chain for tx */
-#define HPCDMA_EOR    0x80000000 /* last desc in chain for rx */
-#define HPCDMA_EOXP   0x40000000 /* end of packet for tx */
-#define HPCDMA_EORP   0x40000000 /* end of packet for rx */
-#define HPCDMA_XIE    0x20000000 /* irq generated when at end of this desc */
-#define HPCDMA_XIU    0x01000000 /* Tx buffer in use by CPU. */
-#define HPCDMA_EIPC   0x00ff0000 /* SEEQ ethernet special xternal bytecount */
-#define HPCDMA_ETXD   0x00008000 /* set to one by HPC when packet tx'd */
-#define HPCDMA_OWN    0x00004000 /* Denotes ring buffer ownership on rx */
-#define HPCDMA_BCNT   0x00003fff /* size in bytes of this dma buffer */
-
-	unsigned long pnext;     /* paddr of next hpc_dma_desc if any */
-};
-
-typedef volatile unsigned long hpcreg;
-
-/* HPC1 stuff. */
-
-/* HPC3 stuff. */
-
-/* The set of regs for each HPC3 pbus dma channel. */
-struct hpc3_pbus_dmacregs {
-	hpcreg pbdma_bptr; /* pbus dma channel buffer ptr */
-	hpcreg pbdma_dptr; /* pbus dma channel desc ptr */
-	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
-	hpcreg pbdma_ctrl; /* pbus dma channel control reg */
-#define HPC3_PDMACTRL_SEL  0x00000002 /* little endian transfer */
-#define HPC3_PDMACTRL_RCV  0x00000004 /* direction is receive */
-#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */
-#define HPC3_PDMACTRL_ACT  0x00000010 /* start dma transfer */
-#define HPC3_PDMACTRL_LD   0x00000020 /* load enable for ACT */
-#define HPC3_PDMACTRL_RT   0x00000040 /* Use realtime GIO bus servicing */
-#define HPC3_PDMACTRL_HW   0x0000ff00 /* DMA High-water mark */
-#define HPC3_PDMACTRL_FB   0x003f0000 /* Ptr to beginning of fifo */
-#define HPC3_PDMACTRL_FE   0x3f000000 /* Ptr to end of fifo */
-
-	char _unused2[PAGE_SIZE - (sizeof(hpcreg))]; /* padding */
-};
-
-/* The HPC3 scsi registers, this does not include external ones. */
-struct hpc3_scsiregs {
-	hpcreg cbptr;   /* current dma buffer ptr, diagnostic use only */
-	hpcreg ndptr;   /* next dma descriptor ptr */
-	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
-	hpcreg bcd;     /* byte count info */
-#define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */
-#define HPC3_SBCD_XIE     0x00004000 /* Send IRQ when done with cur buf */
-#define HPC3_SBCD_EOX     0x00008000 /* Indicates this is last buf in chain */
-
-	hpcreg ctrl;    /* control register */
-#define HPC3_SCTRL_IRQ    0x01 /* IRQ asserted, either dma done or parity */
-#define HPC3_SCTRL_ENDIAN 0x02 /* DMA endian mode, 0=big 1=little */
-#define HPC3_SCTRL_DIR    0x04 /* DMA direction, 1=dev2mem 0=mem2dev */
-#define HPC3_SCTRL_FLUSH  0x08 /* Tells HPC3 to flush scsi fifos */
-#define HPC3_SCTRL_ACTIVE 0x10 /* SCSI DMA channel is active */
-#define HPC3_SCTRL_AMASK  0x20 /* DMA active inhibits PIO */
-#define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */
-#define HPC3_SCTRL_PERR   0x80 /* Bad parity on HPC3 iface to scsi controller */
-
-	hpcreg gfptr;   /* current GIO fifo ptr */
-	hpcreg dfptr;   /* current device fifo ptr */
-	hpcreg dconfig; /* DMA configuration register */
-#define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */
-#define HPC3_SDCFG_D1   0x00006 /* Cycles to spend in D1 state */
-#define HPC3_SDCFG_D2   0x00038 /* Cycles to spend in D2 state */
-#define HPC3_SDCFG_D3   0x001c0 /* Cycles to spend in D3 state */
-#define HPC3_SDCFG_HWAT 0x00e00 /* DMA high water mark */
-#define HPC3_SDCFG_HW   0x01000 /* Enable 16-bit halfword DMA accesses to scsi */
-#define HPC3_SDCFG_SWAP 0x02000 /* Byte swap all DMA accesses */
-#define HPC3_SDCFG_EPAR 0x04000 /* Enable parity checking for DMA */
-#define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */
-#define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */
-
-	hpcreg pconfig; /* PIO configuration register */
-#define HPC3_SPCFG_P3   0x0003 /* Cycles to spend in P3 state */
-#define HPC3_SPCFG_P2W  0x001c /* Cycles to spend in P2 state for writes */
-#define HPC3_SPCFG_P2R  0x01e0 /* Cycles to spend in P2 state for reads */
-#define HPC3_SPCFG_P1   0x0e00 /* Cycles to spend in P1 state */
-#define HPC3_SPCFG_HW   0x1000 /* Enable 16-bit halfword PIO accesses to scsi */
-#define HPC3_SPCFG_SWAP 0x2000 /* Byte swap all PIO accesses */
-#define HPC3_SPCFG_EPAR 0x4000 /* Enable parity checking for PIO */
-#define HPC3_SPCFG_FUJI 0x8000 /* Fujitsu scsi controller mode for faster dma/pio */
-
-	char _unused2[PAGE_SIZE - (6 * sizeof(hpcreg))]; /* padding */
-};
-
-/* SEEQ ethernet HPC3 registers, only one seeq per HPC3. */
-struct hpc3_ethregs {
-	/* Receiver registers. */
-	hpcreg rx_cbptr;   /* current dma buffer ptr, diagnostic use only */
-	hpcreg rx_ndptr;   /* next dma descriptor ptr */
-	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
-	hpcreg rx_bcd;     /* byte count info */
-#define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */
-#define HPC3_ERXBCD_XIE     0x20000000 /* HPC3 interrupts cpu at end of this buf */
-#define HPC3_ERXBCD_EOX     0x80000000 /* flags this as end of descriptor chain */
-
-	hpcreg rx_ctrl;    /* control register */
-#define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */
-#define HPC3_ERXCTRL_STAT6  0x00000040 /* Rdonly irq status */
-#define HPC3_ERXCTRL_STAT7  0x00000080 /* Rdonlt old/new status bit from Seeq */
-#define HPC3_ERXCTRL_ENDIAN 0x00000100 /* Endian for dma channel, little=1 big=0 */
-#define HPC3_ERXCTRL_ACTIVE 0x00000200 /* Tells if DMA transfer is in progress */
-#define HPC3_ERXCTRL_AMASK  0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */
-#define HPC3_ERXCTRL_RBO    0x00000800 /* Receive buffer overflow if set to 1 */
-
-	hpcreg rx_gfptr;   /* current GIO fifo ptr */
-	hpcreg rx_dfptr;   /* current device fifo ptr */
-	hpcreg _unused2;   /* padding */
-	hpcreg rx_reset;   /* reset register */
-#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */
-#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */
-#define HPC3_ERXRST_LBACK  0x4 /* Enable diagnostic loopback mode of Seeq8003 */
-
-	hpcreg rx_dconfig; /* DMA configuration register */
-#define HPC3_ERXDCFG_D1    0x0000f /* Cycles to spend in D1 state for PIO */
-#define HPC3_ERXDCFG_D2    0x000f0 /* Cycles to spend in D2 state for PIO */
-#define HPC3_ERXDCFG_D3    0x00f00 /* Cycles to spend in D3 state for PIO */
-#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
-#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
-#define HPC3_ERXDCFG_FEOP  0x04000 /* Bad packet marker timeout enable */
-#define HPC3_ERXDCFG_FIRQ  0x08000 /* Another bad packet timeout enable */
-#define HPC3_ERXDCFG_PTO   0x30000 /* Programmed timeout value for above two */
-
-	hpcreg rx_pconfig; /* PIO configuration register */
-#define HPC3_ERXPCFG_P1    0x000f /* Cycles to spend in P1 state for PIO */
-#define HPC3_ERXPCFG_P2    0x00f0 /* Cycles to spend in P2 state for PIO */
-#define HPC3_ERXPCFG_P3    0x0f00 /* Cycles to spend in P3 state for PIO */
-#define HPC3_ERXPCFG_TST   0x1000 /* Diagnistic ram test feature bit */
-
-	char _unused3[PAGE_SIZE - (8 * sizeof(hpcreg))]; /* padding */
-
-	/* Transmitter registers. */
-	hpcreg tx_cbptr;   /* current dma buffer ptr, diagnostic use only */
-	hpcreg tx_ndptr;   /* next dma descriptor ptr */
-	char _unused4[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
-	hpcreg tx_bcd;     /* byte count info */
-#define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */
-#define HPC3_ETXBCD_ESAMP   0x10000000 /* if set, too late to add descriptor */
-#define HPC3_ETXBCD_XIE     0x20000000 /* Interrupt cpu at end of cur desc */
-#define HPC3_ETXBCD_EOP     0x40000000 /* Last byte of cur buf is end of packet */
-#define HPC3_ETXBCD_EOX     0x80000000 /* This buf is the end of desc chain */
-
-	hpcreg tx_ctrl;    /* control register */
-#define HPC3_ETXCTRL_STAT30 0x0000000f /* Rdonly copy of seeq tx stat reg */
-#define HPC3_ETXCTRL_STAT4  0x00000010 /* Indicate late collision occurred */
-#define HPC3_ETXCTRL_STAT75 0x000000e0 /* Rdonly irq status from seeq */
-#define HPC3_ETXCTRL_ENDIAN 0x00000100 /* Dma channel endian mode, 1=little 0=big */
-#define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */
-#define HPC3_ETXCTRL_AMASK  0x00000400 /* Indicates ACTIVE inhibits PIO's */
-
-	hpcreg tx_gfptr;   /* current GIO fifo ptr */
-	hpcreg tx_dfptr;   /* current device fifo ptr */
-	char _unused5[PAGE_SIZE - (4 * sizeof(hpcreg))]; /* padding */
-};
-
-struct hpc3_regs {
-	/* First regs for the PBUS 8 dma channels. */
-	struct hpc3_pbus_dmacregs pbdma[8];
-
-	/* Now the HPC scsi registers, we get two scsi reg sets. */
-	struct hpc3_scsiregs scsi_chan0, scsi_chan1;
-
-	/* The SEEQ hpc3 ethernet dma/control registers. */
-	struct hpc3_ethregs ethregs;
-
-	/* Here are where the hpc3 fifo's can be directly accessed
-	 * via PIO accesses.  Under normal operation we never stick
-	 * our grubby paws in here so it's just padding.
-	 */
-	char _unused1[PAGE_SIZE * 24];
-
-	/* HPC3 irq status regs.  Due to a peculiar bug you need to
-	 * look at two different register addresses to get at all of
-	 * the status bits.  The first reg can only reliably report
-	 * bits 4:0 of the status, and the second reg can only
-	 * reliably report bits 9:5 of the hpc3 irq status.  I told
-	 * you it was a peculiar bug. ;-)
-	 */
-	hpcreg istat0;      /* Irq status, only bits <4:0> reliable. */
-#define HPC3_ISTAT_PBIMASK  0x0ff  /* irq bits for pbus devs 0 --> 7 */
-#define HPC3_ISTAT_SC0MASK  0x100  /* irq bit for scsi channel 0 */
-#define HPC3_ISTAT_SC1MASK  0x200  /* irq bit for scsi channel 1 */
-
-	hpcreg gio64_misc;  /* GIO64 misc control bits. */
-#define HPC3_GIOMISC_ERTIME   0x1    /* Enable external timer real time. */
-#define HPC3_GIOMISC_DENDIAN  0x2    /* dma descriptor endian, 1=lit 0=big */
-
-	hpcreg eeprom_data; /* EEPROM data reg. */
-#define HPC3_EEPROM_EPROT     0x01   /* Protect register enable */
-#define HPC3_EEPROM_CSEL      0x02   /* Chip select */
-#define HPC3_EEPROM_ECLK      0x04   /* EEPROM clock */
-#define HPC3_EEPROM_DATO      0x08   /* Data out */
-#define HPC3_EEPROM_DATI      0x10   /* Data in */
-
-	hpcreg istat1;      /* Irq status, only bits <9:5> reliable. */
-	hpcreg gio64_estat; /* GIO64 error interrupt status reg. */
-#define HPC3_GIOESTAT_BLMASK  0x000ff  /* Bus lane where bad parity occurred */
-#define HPC3_GIOESTAT_CTYPE   0x00100  /* Bus cycle type, 0=PIO 1=DMA */
-#define HPC3_GIOESTAT_PIDMSK  0x3f700  /* DMA channel parity identifier */
-
-	/* Now direct PIO per-HPC3 peripheral access to external regs. */
-	char _unused2[0x13fec]; /* Trust me... */
-	hpcreg scsi0_ext[256];  /* SCSI channel 0 external regs */
-	char _unused3[0x07c00]; /* Trust me... */
-	hpcreg scsi1_ext[256];  /* SCSI channel 1 external regs */
-	char _unused4[0x07c00]; /* It'll only hurt a little... */
-
-	/* Did DaveM forget the ethernet external regs?
-	 * Anyhow, they're not here and we need some padding instead.
-	 */
-	char _unused5[0x04000]; /* It'll hurt a lot if you leave this out */
-
-	/* Per-peripheral device external registers and dma/pio control. */
-	hpcreg pbus_extregs[16][256]; /* 2nd indice indexes controller */
-	hpcreg pbus_dmacfgs[8][128]; /* 2nd indice indexes controller */
-#define HPC3_PIODCFG_D3R    0x00000001 /* Cycles to spend in D3 for reads */
-#define HPC3_PIODCFG_D4R    0x0000001e /* Cycles to spend in D4 for reads */
-#define HPC3_PIODCFG_D5R    0x000001e0 /* Cycles to spend in D5 for reads */
-#define HPC3_PIODCFG_D3W    0x00000200 /* Cycles to spend in D3 for writes */
-#define HPC3_PIODCFG_D4W    0x00003c00 /* Cycles to spend in D4 for writes */
-#define HPC3_PIODCFG_D5W    0x0003c000 /* Cycles to spend in D5 for writes */
-#define HPC3_PIODCFG_HWORD  0x00040000 /* Enable 16-bit dma access mode */
-#define HPC3_PIODCFG_EHI    0x00080000 /* Places halfwords on high 16 bits of bus */
-#define HPC3_PIODCFG_RTIME  0x00200000 /* Make this device real time on GIO bus */
-#define HPC3_PIODCFG_BURST  0x07c00000 /* 5 bit burst count for DMA device */
-#define HPC3_PIODCFG_DRQLV  0x08000000 /* Use live pbus_dreq unsynchronized signal */
-
-	hpcreg pbus_piocfgs[64][10]; /* 2nd indice indexes controller */
-#define HPC3_PIOPCFG_RP2    0x00001  /* Cycles to spend in P2 state for reads */
-#define HPC3_PIOPCFG_RP3    0x0001e  /* Cycles to spend in P3 state for reads */
-#define HPC3_PIOPCFG_RP4    0x001e0  /* Cycles to spend in P4 state for reads */
-#define HPC3_PIOPCFG_WP2    0x00200  /* Cycles to spend in P2 state for writes */
-#define HPC3_PIOPCFG_WP3    0x03c00  /* Cycles to spend in P3 state for writes */
-#define HPC3_PIOPCFG_WP4    0x3c000  /* Cycles to spend in P4 state for writes */
-#define HPC3_PIOPCFG_HW     0x40000  /* Enable 16-bit PIO accesses */
-#define HPC3_PIOPCFG_EHI    0x80000  /* Place even address bits in bits <15:8> */
-
-	/* PBUS PROM control regs. */
-	hpcreg pbus_promwe;     /* PROM write enable register */
-#define HPC3_PROM_WENAB     0x1 /* Enable writes to the PROM */
-
-	char _unused6[0x800 - sizeof(hpcreg)];
-	hpcreg pbus_promswap;   /* Chip select swap reg */
-#define HPC3_PROM_SWAP      0x1 /* invert GIO addr bit to select prom0 or prom1 */
-
-	char _unused7[0x800 - sizeof(hpcreg)];
-	hpcreg pbus_gout;       /* PROM general purpose output reg */
-#define HPC3_PROM_STAT      0x1 /* General purpose status bit in gout */
-
-	char _unused8[0x1000 - sizeof(hpcreg)];
-	hpcreg pbus_promram[16384]; /* 64k of PROM battery backed ram */
-};
-
-/* It is possible to have two HPC3's within the address space on
- * one machine, though only having one is more likely on an INDY.
- * Controller 0 lives at physical address 0x1fb80000 and the controller
- * 1 if present lives at address 0x1fb00000.
- */
-extern struct hpc3_regs *hpc3c0, *hpc3c1;
-#define HPC3_CHIP0_PBASE   0x1fb80000 /* physical */
-#define HPC3_CHIP1_PBASE   0x1fb00000 /* physical */
-
-/* Control and misc status information, these live in pbus channel 6. */
-struct hpc3_miscregs {
-	hpcreg pdata, pctrl, pstat, pdmactrl, pistat, pimask;
-	hpcreg ptimer1, ptimer2, ptimer3, ptimer4;
-	hpcreg _unused1[2];
-	hpcreg ser1cmd, ser1data;
-	hpcreg ser0cmd, ser0data;
-	hpcreg kbdmouse0, kbdmouse1;
-	hpcreg gcsel, genctrl, panel;
-	hpcreg _unused2;
-	hpcreg sysid;
-	hpcreg _unused3;
-	hpcreg read, _unused4;
-	hpcreg dselect;
-#define HPC3_DSELECT_SCLK10MHZ   0x00 /* use 10MHZ serial clock */
-#define HPC3_DSELECT_ISDNB       0x01 /* enable isdn B */
-#define HPC3_DSELECT_ISDNA       0x02 /* enable isdn A */
-#define HPC3_DSELECT_LPR         0x04 /* use parallel DMA */
-#define HPC3_DSELECT_SCLK667MHZ  0x10 /* use 6.67MHZ serial clock */
-#define HPC3_DSELECT_SCLKEXT     0x20 /* use external serial clock */
-
-	hpcreg _unused5;
-	hpcreg write1;
-#define HPC3_WRITE1_PRESET    0x01  /* 0=LPR_RESET, 1=NORMAL */
-#define HPC3_WRITE1_KMRESET   0x02  /* 0=KBDMOUSE_RESET, 1=NORMAL */
-#define HPC3_WRITE1_ERESET    0x04  /* 0=EISA_RESET, 1=NORMAL */
-#define HPC3_WRITE1_GRESET    0x08  /* 0=MAGIC_GIO_RESET, 1=NORMAL */
-#define HPC3_WRITE1_LC0OFF    0x10  /* turn led off (guiness=red, else green) */
-#define HPC3_WRITE1_LC1OFF    0x20  /* turn led off (guiness=green, else amber) */
-
-	hpcreg _unused6;
-	hpcreg write2;
-#define HPC3_WRITE2_NTHRESH  0x01 /* use 4.5db threshhold */
-#define HPC3_WRITE2_TPSPEED  0x02 /* use 100ohm TP speed */
-#define HPC3_WRITE2_EPSEL    0x04 /* force cable mode: 1=AUI 0=TP */
-#define HPC3_WRITE2_EASEL    0x08 /* 1=autoselect 0=manual cable selection */
-#define HPC3_WRITE2_U1AMODE  0x10 /* 1=PC 0=MAC UART mode */
-#define HPC3_WRITE2_U0AMODE  0x20 /* 1=PC 0=MAC UART mode */
-#define HPC3_WRITE2_MLO      0x40 /* 1=4.75V 0=+5V */
-#define HPC3_WRITE2_MHI      0x80 /* 1=5.25V 0=+5V */
-};
-extern struct hpc3_miscregs *hpc3mregs;
-#define HPC3_MREGS_PBASE   0x1fbd9800 /* physical */
-
-/* We need software copies of these because they are write only. */
-extern unsigned long sgi_hpc_write1, sgi_hpc_write2;
-
-#define SGI_KEYBOARD_IRQ 20
-
-struct hpc_keyb {
-#ifdef __MIPSEB__
-	unsigned char _unused0[3];
-	volatile unsigned char data;
-	unsigned char _unused1[3];
-	volatile unsigned char command;
-#else
-	volatile unsigned char data;
-	unsigned char _unused0[3];
-	volatile unsigned char command;
-	unsigned char _unused1[3];
-#endif
-};
-
-/* Indy RTC  */
-
-/* The layout of registers for the INDY Dallas 1286 clock chipset. */
-struct indy_clock {
-	volatile unsigned int hsec;
-	volatile unsigned int sec;
-	volatile unsigned int min;
-	volatile unsigned int malarm;
-	volatile unsigned int hr;
-	volatile unsigned int halarm;
-	volatile unsigned int day;
-	volatile unsigned int dalarm;
-	volatile unsigned int date;
-	volatile unsigned int month;
-	volatile unsigned int year;
-	volatile unsigned int cmd;
-	volatile unsigned int whsec;
-	volatile unsigned int wsec;
-	volatile unsigned int _unused0[50];
-};
-
-#define INDY_CLOCK_REGS (KSEG1ADDR(0x1fbe0000))
-
-extern void sgihpc_init(void);
-
-#endif /* !(_MIPS_SGIHPC_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sgimc.h linux/include/asm-mips/sgimc.h
--- v2.3.47/linux/include/asm-mips/sgimc.h	Tue Oct 20 13:52:54 1998
+++ linux/include/asm-mips/sgimc.h	Wed Dec 31 16:00:00 1969
@@ -1,223 +0,0 @@
-/* $Id: sgimc.h,v 1.1.1.1 1997/06/01 03:17:13 ralf Exp $
- * sgimc.h: Definitions for memory controller hardware found on
- *          SGI IP20, IP22, IP26, and IP28 machines.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-
-#ifndef _MIPS_SGIMC_H
-#define _MIPS_SGIMC_H
-
-struct sgimc_misc_ctrl {
-	unsigned long _unused1;
-	volatile unsigned long cpuctrl0;     /* CPU control register 0, readwrite */
-#define SGIMC_CCTRL0_REFS         0x0000000f /* REFS mask */
-#define SGIMC_CCTRL0_EREFRESH     0x00000010 /* Memory refresh enable */
-#define SGIMC_CCTRL0_EPERRGIO     0x00000020 /* GIO parity error enable */
-#define SGIMC_CCTRL0_EPERRMEM     0x00000040 /* Main mem parity error enable */
-#define SGIMC_CCTRL0_EPERRCPU     0x00000080 /* CPU bus parity error enable */
-#define SGIMC_CCTRL0_WDOG         0x00000100 /* Watchdog timer enable */
-#define SGIMC_CCTRL0_SYSINIT      0x00000200 /* System init bit */
-#define SGIMC_CCTRL0_GFXRESET     0x00000400 /* Graphics interface reset */
-#define SGIMC_CCTRL0_EISALOCK     0x00000800 /* Lock CPU from memory for EISA */
-#define SGIMC_CCTRL0_EPERRSCMD    0x00001000 /* SysCMD bus parity error enable */
-#define SGIMC_CCTRL0_IENAB        0x00002000 /* Allow interrupts from MC */
-#define SGIMC_CCTRL0_ESNOOP       0x00004000 /* Snooping I/O enable */
-#define SGIMC_CCTRL0_EPROMWR      0x00008000 /* Prom writes from cpu enable */
-#define SGIMC_CCTRL0_WRESETPMEM   0x00010000 /* Perform warm reset, preserves mem */
-#define SGIMC_CCTRL0_LENDIAN      0x00020000 /* Put MC in little-endian mode */
-#define SGIMC_CCTRL0_WRESETDMEM   0x00040000 /* Warm reset, destroys mem contents */
-#define SGIMC_CCTRL0_CMEMBADPAR   0x02000000 /* Generate bad perr from cpu to mem */
-#define SGIMC_CCTRL0_R4KNOCHKPARR 0x04000000 /* Don't chk parity on mem data reads */
-#define SGIMC_CCTRL0_GIOBTOB      0x08000000 /* Allow GIO back to back writes */
-
-	unsigned long _unused2;
-	volatile unsigned long cpuctrl1;     /* CPU control register 1, readwrite */
-#define SGIMC_CCTRL1_EGIOTIMEO    0x00000010 /* GIO bus timeout enable */
-#define SGIMC_CCTRL1_FIXEDEHPC    0x00001000 /* Fixed HPC endianness */
-#define SGIMC_CCTRL1_LITTLEHPC    0x00002000 /* Little endian HPC */
-#define SGIMC_CCTRL1_FIXEDEEXP0   0x00004000 /* Fixed EXP0 endianness */
-#define SGIMC_CCTRL1_LITTLEEXP0   0x00008000 /* Little endian EXP0 */
-#define SGIMC_CCTRL1_FIXEDEEXP1   0x00010000 /* Fixed EXP1 endianness */
-#define SGIMC_CCTRL1_LITTLEEXP1   0x00020000 /* Little endian EXP1 */
-
-	unsigned long _unused3;
-	volatile unsigned long watchdogt;    /* Watchdog reg rdonly, write clears */
-
-	unsigned long _unused4;
-	volatile unsigned long systemid;     /* MC system ID register, readonly */
-#define SGIMC_SYSID_MASKREV       0x0000000f /* Revision of MC controller */
-#define SGIMC_SYSID_EPRESENT      0x00000010 /* Indicates presence of EISA bus */
-
-	unsigned long _unused5[3];
-	volatile unsigned long divider;      /* Divider reg for RPSS */
-
-	unsigned long _unused6;
-	volatile unsigned char eeprom;       /* EEPROM byte reg for r4k */
-#define SGIMC_EEPROM_PRE          0x00000001 /* eeprom chip PRE pin assertion */
-#define SGIMC_EEPROM_CSEL         0x00000002 /* Active high, eeprom chip select */
-#define SGIMC_EEPROM_SECLOCK      0x00000004 /* EEPROM serial clock */
-#define SGIMC_EEPROM_SDATAO       0x00000008 /* Serial EEPROM data-out */
-#define SGIMC_EEPROM_SDATAI       0x00000010 /* Serial EEPROM data-in */
-
-	unsigned char _unused7[3];
-	unsigned long _unused8[3];
-	volatile unsigned short rcntpre;     /* Preload refresh counter */
-
-	unsigned short _unused9;
-	unsigned long _unused9a;
-	volatile unsigned short rcounter;    /* Readonly refresh counter */
-
-	unsigned short _unused10;
-	unsigned long _unused11[13];
-	volatile unsigned long gioparm;      /* Parameter word for GIO64 */
-#define SGIMC_GIOPARM_HPC64       0x00000001 /* HPC talks to GIO using 64-bits */
-#define SGIMC_GIOPARM_GFX64       0x00000002 /* GFX talks to GIO using 64-bits */
-#define SGIMC_GIOPARM_EXP064      0x00000004 /* EXP(slot0) talks using 64-bits */
-#define SGIMC_GIOPARM_EXP164      0x00000008 /* EXP(slot1) talks using 64-bits */
-#define SGIMC_GIOPARM_EISA64      0x00000010 /* EISA bus talks 64-bits to GIO */
-#define SGIMC_GIOPARM_HPC264      0x00000020 /* 2nd HPX talks 64-bits to GIO */
-#define SGIMC_GIOPARM_RTIMEGFX    0x00000040 /* GFX device has realtime attr */
-#define SGIMC_GIOPARM_RTIMEEXP0   0x00000080 /* EXP(slot0) has realtime attr */
-#define SGIMC_GIOPARM_RTIMEEXP1   0x00000100 /* EXP(slot1) has realtime attr */
-#define SGIMC_GIOPARM_MASTEREISA  0x00000200 /* EISA bus can act as bus master */
-#define SGIMC_GIOPARM_ONEBUS      0x00000400 /* Exists one GIO64 pipelined bus */
-#define SGIMC_GIOPARM_MASTERGFX   0x00000800 /* GFX can act as a bus master */
-#define SGIMC_GIOPARM_MASTEREXP0  0x00001000 /* EXP(slot0) can bus master */
-#define SGIMC_GIOPARM_MASTEREXP1  0x00002000 /* EXP(slot1) can bus master */
-#define SGIMC_GIOPARM_PLINEEXP0   0x00004000 /* EXP(slot0) has pipeline attr */
-#define SGIMC_GIOPARM_PLINEEXP1   0x00008000 /* EXP(slot1) has pipeline attr */
-
-	unsigned long _unused13;
-	volatile unsigned short cputp;       /* CPU bus arb time period */
-
-	unsigned short _unused14;
-	unsigned long _unused15[3];
-	volatile unsigned short lbursttp;    /* Time period for long bursts */
-
-	unsigned short _unused16;
-	unsigned long _unused17[9];
-	volatile unsigned long mconfig0;     /* Memory config register zero */
-	unsigned long _unused18;
-	volatile unsigned long mconfig1;     /* Memory config register one */
-
-        /* These defines apply to both mconfig registers above. */
-#define SGIMC_MCONFIG_FOURMB     0x00000000  /* Physical ram = 4megs */
-#define SGIMC_MCONFIG_EIGHTMB    0x00000100  /* Physical ram = 8megs */
-#define SGIMC_MCONFIG_SXTEENMB   0x00000300  /* Physical ram = 16megs */
-#define SGIMC_MCONFIG_TTWOMB     0x00000700  /* Physical ram = 32megs */
-#define SGIMC_MCONFIG_SFOURMB    0x00000f00  /* Physical ram = 64megs */
-#define SGIMC_MCONFIG_OTEIGHTMB  0x00001f00  /* Physical ram = 128megs */
-#define SGIMC_MCONFIG_RMASK      0x00001f00  /* Ram config bitmask */
-
-	unsigned long _unused19;
-	volatile unsigned long cmacc;        /* Mem access config for CPU */
-	unsigned long _unused20;
-	volatile unsigned long gmacc;        /* Mem access config for GIO */
-
-	/* This define applies to both cmacc and gmacc registers above. */
-#define SGIMC_MACC_ALIASBIG       0x20000000 /* 512MB home for alias */
-
-	/* Error address/status regs from GIO and CPU perspectives. */
-	unsigned long _unused21;
-	volatile unsigned long cerr;         /* Error address reg for CPU */
-	unsigned long _unused22;
-	volatile unsigned long cstat;        /* Status reg for CPU */
-	unsigned long _unused23;
-	volatile unsigned long gerr;         /* Error address reg for GIO */
-	unsigned long _unused24;
-	volatile unsigned long gstat;        /* Status reg for GIO */
-
-	/* Special hard bus locking registers. */
-	unsigned long _unused25;
-	volatile unsigned char syssembit;    /* Uni-bit system semaphore */
-	unsigned char _unused26[3];
-	unsigned long _unused27;
-	volatile unsigned char mlock;        /* Global GIO memory access lock */
-	unsigned char _unused28[3];
-	unsigned long _unused29;
-	volatile unsigned char elock;        /* Locks EISA from GIO accesses */
-
-	/* GIO dma control registers. */
-	unsigned char _unused30[3];
-	unsigned long _unused31[14];
-	volatile unsigned long gio_dma_trans;/* DMA mask to translation GIO addrs */
-	unsigned long _unused32;
-	volatile unsigned long gio_dma_sbits;/* DMA GIO addr substitution bits */
-	unsigned long _unused33;
-	volatile unsigned long dma_intr_cause; /* DMA IRQ cause indicator bits */
-	unsigned long _unused34;
-	volatile unsigned long dma_ctrl;     /* Main DMA control reg */
-
-	/* DMA TLB entry 0 */
-	unsigned long _unused35;
-	volatile unsigned long dtlb_hi0;
-	unsigned long _unused36;
-	volatile unsigned long dtlb_lo0;
-
-	/* DMA TLB entry 1 */
-	unsigned long _unused37;
-	volatile unsigned long dtlb_hi1;
-	unsigned long _unused38;
-	volatile unsigned long dtlb_lo1;
-
-	/* DMA TLB entry 2 */
-	unsigned long _unused39;
-	volatile unsigned long dtlb_hi2;
-	unsigned long _unused40;
-	volatile unsigned long dtlb_lo2;
-
-	/* DMA TLB entry 3 */
-	unsigned long _unused41;
-	volatile unsigned long dtlb_hi3;
-	unsigned long _unused42;
-	volatile unsigned long dtlb_lo3;
-};
-
-/* MC misc control registers live at physical 0x1fa00000. */
-extern struct sgimc_misc_ctrl *mcmisc_regs;
-extern unsigned long *rpsscounter;          /* Chirps at 100ns */
-
-struct sgimc_dma_ctrl {
-	unsigned long _unused1;
-	volatile unsigned long maddronly;   /* Address DMA goes at */
-	unsigned long _unused2;
-	volatile unsigned long maddrpdeflts; /* Same as above, plus set defaults */
-	unsigned long _unused3;
-	volatile unsigned long dmasz;       /* DMA count */
-	unsigned long _unused4;
-	volatile unsigned long ssize;       /* DMA stride size */
-	unsigned long _unused5;
-	volatile unsigned long gmaddronly;  /* Set GIO DMA but do not start trans */
-	unsigned long _unused6;
-	volatile unsigned long dmaddnpgo;   /* Set GIO DMA addr + start transfer */
-	unsigned long _unused7;
-	volatile unsigned long dmamode;     /* DMA mode config bit settings */
-	unsigned long _unused8;
-	volatile unsigned long dmacount;    /* Zoom and byte count for DMA */
-	unsigned long _unused9;
-	volatile unsigned long dmastart;    /* Pedal to the metal. */
-	unsigned long _unused10;
-	volatile unsigned long dmarunning;  /* DMA op is in progress */
-	unsigned long _unused11;
-
-	/* Set dma addr, defaults, and kick it */
-	volatile unsigned long maddr_defl_go; /* go go go! -lm */
-};
-
-/* MC controller dma regs live at physical 0x1fa02000. */
-extern struct sgimc_dma_ctrl *dmactrlregs;
-
-/* Base location of the two ram banks found in IP2[0268] machines. */
-#define SGIMC_SEG0_BADDR     0x08000000
-#define SGIMC_SEG1_BADDR     0x20000000
-
-/* Maximum size of the above banks are per machine. */
-extern unsigned long sgimc_seg0_size, sgimc_seg1_size;
-#define SGIMC_SEG0_SIZE_ALL         0x10000000 /* 256MB */
-#define SGIMC_SEG1_SIZE_IP20_IP22   0x08000000 /* 128MB */
-#define SGIMC_SEG1_SIZE_IP26_IP28   0x20000000 /* 512MB */
-
-extern void sgimc_init(void);
-
-#endif /* !(_MIPS_SGIMC_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sgint23.h linux/include/asm-mips/sgint23.h
--- v2.3.47/linux/include/asm-mips/sgint23.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/sgint23.h	Wed Dec 31 16:00:00 1969
@@ -1,187 +0,0 @@
-/* $Id: sgint23.h,v 1.3 1999/05/07 22:35:37 ulfc Exp $
- * sgint23.h: Defines for the SGI INT2 and INT3 chipsets.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - INT2 corrections
- */
-#ifndef _MIPS_SGINT23_H
-#define _MIPS_SGINT23_H
-
-/* These are the virtual IRQ numbers, we divide all IRQ's into
- * 'spaces', the 'space' determines where and how to enable/disable
- * that particular IRQ on an SGI machine.  Add new 'spaces' as new
- * IRQ hardware is supported.
- */
-#define SGINT_LOCAL0   0   /* INDY has 8 local0 irq levels */
-#define SGINT_LOCAL1   8   /* INDY has 8 local1 irq levels */
-#define SGINT_LOCAL2   16  /* INDY has 8 local2 vectored irq levels */
-#define SGINT_LOCAL3   24  /* INDY has 8 local3 vectored irq levels */
-#define SGINT_GIO      32  /* INDY has 9 GIO irq levels */
-#define SGINT_HPCDMA   41  /* INDY has 11 HPCDMA irq _sources_ */
-#define SGINT_END      52  /* End of 'spaces' */
-
-/* INT2 occupies HPC PBUS slot 4, INT3 uses slot 6. */
-#define SGI_INT2_BASE 0x1fbd9000 /* physical */
-#define SGI_INT3_BASE 0x1fbd9880 /* physical */
-
-struct sgi_ioc_ints {
-#ifdef __MIPSEB__
-	unsigned char _unused0[3];
-	volatile unsigned char istat0;    /* Interrupt status zero */
-#else
-	volatile unsigned char istat0;    /* Interrupt status zero */
-	unsigned char _unused0[3];
-#endif
-#define ISTAT0_FFULL           0x01
-#define ISTAT0_SCSI0           0x02
-#define ISTAT0_SCSI1           0x04
-#define ISTAT0_ENET            0x08
-#define ISTAT0_GFXDMA          0x10
-#define ISTAT0_LPR             0x20
-#define ISTAT0_HPC2            0x40
-#define ISTAT0_LIO2            0x80
-
-#ifdef __MIPSEB__
-	unsigned char _unused1[3];
-	volatile unsigned char imask0;    /* Interrupt mask zero */
-	unsigned char _unused2[3];
-	volatile unsigned char istat1;    /* Interrupt status one */
-#else
-	volatile unsigned char imask0;    /* Interrupt mask zero */
-	unsigned char _unused1[3];
-	volatile unsigned char istat1;    /* Interrupt status one */
-	unsigned char _unused2[3];
-#endif
-#define ISTAT1_ISDNI           0x01
-#define ISTAT1_PWR             0x02
-#define ISTAT1_ISDNH           0x04
-#define ISTAT1_LIO3            0x08
-#define ISTAT1_HPC3            0x10
-#define ISTAT1_AFAIL           0x20
-#define ISTAT1_VIDEO           0x40
-#define ISTAT1_GIO2            0x80
-
-#ifdef __MIPSEB__
-	unsigned char _unused3[3];
-	volatile unsigned char imask1;    /* Interrupt mask one */
-	unsigned char _unused4[3];
-	volatile unsigned char vmeistat;  /* VME interrupt status */
-	unsigned char _unused5[3];
-	volatile unsigned char cmeimask0; /* VME interrupt mask zero */
-	unsigned char _unused6[3];
-	volatile unsigned char cmeimask1; /* VME interrupt mask one */
-	unsigned char _unused7[3];
-	volatile unsigned char cmepol;    /* VME polarity */
-#else
-	volatile unsigned char imask1;    /* Interrupt mask one */
-	unsigned char _unused3[3];
-	volatile unsigned char vmeistat;  /* VME interrupt status */
-	unsigned char _unused4[3];
-	volatile unsigned char cmeimask0; /* VME interrupt mask zero */
-	unsigned char _unused5[3];
-	volatile unsigned char cmeimask1; /* VME interrupt mask one */
-	unsigned char _unused6[3];
-	volatile unsigned char cmepol;    /* VME polarity */
-	unsigned char _unused7[3];
-#endif
-};
-
-struct sgi_ioc_timers {
-#ifdef __MIPSEB__
-	unsigned char _unused0[3];
-	volatile unsigned char tcnt0;  /* counter 0 */
-	unsigned char _unused1[3];
-	volatile unsigned char tcnt1;  /* counter 1 */
-	unsigned char _unused2[3];
-	volatile unsigned char tcnt2;  /* counter 2 */
-	unsigned char _unused3[3];
-	volatile unsigned char tcword; /* control word */
-#else
-	volatile unsigned char tcnt0;  /* counter 0 */
-	unsigned char _unused0[3];
-	volatile unsigned char tcnt1;  /* counter 1 */
-	unsigned char _unused1[3];
-	volatile unsigned char tcnt2;  /* counter 2 */
-	unsigned char _unused2[3];
-	volatile unsigned char tcword; /* control word */
-	unsigned char _unused3[3];
-#endif
-};
-
-/* Timer control word bits. */
-#define SGINT_TCWORD_BCD    0x01 /* Use BCD mode for counters */
-#define SGINT_TCWORD_MMASK  0x0e /* Mode bitmask. */
-#define SGINT_TCWORD_MITC   0x00 /* IRQ on terminal count (doesn't work) */
-#define SGINT_TCWORD_MOS    0x02 /* One-shot IRQ mode. */
-#define SGINT_TCWORD_MRGEN  0x04 /* Normal rate generation */
-#define SGINT_TCWORD_MSWGEN 0x06 /* Square wave generator mode */
-#define SGINT_TCWORD_MSWST  0x08 /* Software strobe */
-#define SGINT_TCWORD_MHWST  0x0a /* Hardware strobe */
-#define SGINT_TCWORD_CMASK  0x30 /* Command mask */
-#define SGINT_TCWORD_CLAT   0x00 /* Latch command */
-#define SGINT_TCWORD_CLSB   0x10 /* LSB read/write */
-#define SGINT_TCWORD_CMSB   0x20 /* MSB read/write */
-#define SGINT_TCWORD_CALL   0x30 /* Full counter read/write */
-#define SGINT_TCWORD_CNT0   0x00 /* Select counter zero */
-#define SGINT_TCWORD_CNT1   0x40 /* Select counter one */
-#define SGINT_TCWORD_CNT2   0x80 /* Select counter two */
-#define SGINT_TCWORD_CRBCK  0xc0 /* Readback command */
-
-#define SGINT_TCSAMP_COUNTER  10255
-
-/* FIXME: What does this really look like?  It was written to have
- * 17 registers, but there are only 16 in my Indigo2.
- * I guessed at which one to remove...  	- andrewb
- */
-struct sgi_int2_regs {
-	struct sgi_ioc_ints ints;
-
-	volatile unsigned long ledbits;   /* LED control bits */
-#define INT2_LED_TXCLK         0x01       /* GPI to TXCLK enable */
-#define INT2_LED_SERSLCT0      0x02       /* serial port0: 0=apple 1=pc */
-#define INT2_LED_SERSLCT1      0x04       /* serial port1: 0=apple 1=pc */
-#define INT2_LED_CHEAPER       0x08       /* 0=cheapernet 1=ethernet */
-#define INT2_LED_POWEROFF      0x10       /* Power-off request, active high */
-
-#ifdef __MIPSEB__
-	unsigned char _unused0[3];
-	volatile unsigned char tclear;    /* Timer clear strobe address */
-#else
-	volatile unsigned char tclear;    /* Timer clear strobe address */
-	unsigned char _unused0[3];
-#endif
-#define INT2_TCLEAR_T0CLR      0x1        /* Clear timer0 IRQ */
-#define INT2_TCLEAR_T1CLR      0x2        /* Clear timer1 IRQ */
-/* I am guesing there are only two unused registers here 
- * but I could be wrong...			- andrewb
- */
-/*	unsigned long _unused[3]; */
-	unsigned long _unused[2];
-	struct sgi_ioc_timers timers;
-};
-
-struct sgi_int3_regs {
-	struct sgi_ioc_ints ints;
-
-#ifdef __MIPSEB__
-	unsigned char _unused0[3];
-	volatile unsigned char tclear;    /* Timer clear strobe address */
-#else
-	volatile unsigned char tclear;    /* Timer clear strobe address */
-	unsigned char _unused0[3];
-#endif
-	volatile unsigned long estatus;   /* Error status reg */
-	unsigned long _unused1[2];
-	struct sgi_ioc_timers timers;
-};
-
-extern struct sgi_int2_regs *sgi_i2regs;
-extern struct sgi_int3_regs *sgi_i3regs;
-extern struct sgi_ioc_ints *ioc_icontrol;
-extern struct sgi_ioc_timers *ioc_timers;
-extern volatile unsigned char *ioc_tclear;
-
-extern void sgint_init(void);
-extern void indy_timer_init(void);
-
-#endif /* !(_MIPS_SGINT23_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/shmbuf.h linux/include/asm-mips/shmbuf.h
--- v2.3.47/linux/include/asm-mips/shmbuf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/shmbuf.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,38 @@
+#ifndef _ASM_SHMBUF_H
+#define _ASM_SHMBUF_H
+
+/* 
+ * The shmid64_ds structure for the MIPS architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 2 miscellaneous 64-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	__kernel_time_t		shm_ctime;	/* last change time */
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _ASM_SHMBUF_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/shmparam.h linux/include/asm-mips/shmparam.h
--- v2.3.47/linux/include/asm-mips/shmparam.h	Sun Nov  7 16:37:34 1999
+++ linux/include/asm-mips/shmparam.h	Thu Feb 24 22:52:30 2000
@@ -1,9 +1,12 @@
-#ifndef __ASM_MIPS_SHMPARAM_H
-#define __ASM_MIPS_SHMPARAM_H
-
-/*
- * This constant is very large but the ABI in it's wisdom says ...
+/* $Id: shmparam.h,v 1.3 2000/01/29 01:42:28 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  */
+#ifndef _ASM_SHMPARAM_H
+#define _ASM_SHMPARAM_H
+
 #define	SHMLBA 0x40000			/* attach addr a multiple of this */
 
-#endif /* __ASM_MIPS_SHMPARAM_H */
+#endif /* _ASM_SHMPARAM_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sigcontext.h linux/include/asm-mips/sigcontext.h
--- v2.3.47/linux/include/asm-mips/sigcontext.h	Tue Oct 20 13:52:54 1998
+++ linux/include/asm-mips/sigcontext.h	Thu Feb 24 22:52:30 2000
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 1996, 1997 by Ralf Baechle
  *
- * $Id: sigcontext.h,v 1.5 1997/12/14 18:57:19 ralf Exp $
+ * $Id: sigcontext.h,v 1.5 1997/12/16 05:36:43 ralf Exp $
  */
 #ifndef __ASM_MIPS_SIGCONTEXT_H
 #define __ASM_MIPS_SIGCONTEXT_H
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/siginfo.h linux/include/asm-mips/siginfo.h
--- v2.3.47/linux/include/asm-mips/siginfo.h	Fri Jan 28 15:09:09 2000
+++ linux/include/asm-mips/siginfo.h	Thu Feb 24 22:52:30 2000
@@ -1,30 +1,33 @@
-/* $Id: siginfo.h,v 1.4 1998/08/28 16:23:06 ralf Exp $
+/* $Id: siginfo.h,v 1.6 2000/02/18 00:24:48 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1998 by Ralf Baechle
+ * Copyright (C) 1998, 1999 by Ralf Baechle
  */
-#ifndef __ASM_MIPS_SIGINFO_H
-#define __ASM_MIPS_SIGINFO_H
+#ifndef _ASM_SIGINFO_H
+#define _ASM_SIGINFO_H
 
 #include <linux/types.h>
 
-/* This structure matches OSF/1 for binary compatibility. */
+/* This structure matches IRIX 32/n32 ABIs for binary compatibility. */
 
 typedef union sigval {
 	int sival_int;
 	void *sival_ptr;
 } sigval_t;
 
+/* This structure matches IRIX 32/n32 ABIs for binary compatibility but
+   has Linux extensions.  */
+
 #define SI_MAX_SIZE	128
-#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 4)
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
 
 typedef struct siginfo {
 	int si_signo;
-	int si_errno;
 	int si_code;
+	int si_errno;
 
 	union {
 		int _pad[SI_PAD_SIZE];
@@ -35,38 +38,47 @@
 			uid_t _uid;		/* sender's uid */
 		} _kill;
 
-		/* POSIX.1b timers */
-		struct {
-			unsigned int _timer1;
-			unsigned int _timer2;
-		} _timer;
-
-		/* POSIX.1b signals */
-		struct {
-			pid_t _pid;		/* sender's pid */
-			uid_t _uid;		/* sender's uid */
-			sigval_t _sigval;
-		} _rt;
-
 		/* SIGCHLD */
 		struct {
 			pid_t _pid;		/* which child */
 			uid_t _uid;		/* sender's uid */
-			int _status;		/* exit code */
 			clock_t _utime;
+			int _status;		/* exit code */
 			clock_t _stime;
 		} _sigchld;
 
+		/* IRIX SIGCHLD */
+		struct {
+			pid_t _pid;		/* which child */
+			clock_t _utime;
+			int _status;		/* exit code */
+			clock_t _stime;
+		} _irix_sigchld;
+
 		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
 		struct {
 			void *_addr; /* faulting insn/memory ref. */
 		} _sigfault;
 
-		/* SIGPOLL */
+		/* SIGPOLL, SIGXFSZ (To do ...)  */
 		struct {
 			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+			sigval_t _sigval;
+		} _rt;
+
 	} _sifields;
 } siginfo_t;
 
@@ -87,7 +99,7 @@
 
 /*
  * si_code values
- * Digital reserves positive values for kernel-generated signals.
+ * Again these have been choosen to be IRIX compatible.
  */
 #define SI_USER		0	/* sent by kill, sigsend, raise */
 #define SI_KERNEL	0x80	/* sent by the kernel from somewhere */
@@ -165,7 +177,7 @@
 #define POLL_IN		1	/* data input available */
 #define POLL_OUT	2	/* output buffers available */
 #define POLL_MSG	3	/* input message available */
-#define POLL_ERR	4	/* i/o error */
+#define POLL_ERR	4	/* I/O error */
 #define POLL_PRI	5	/* high priority input available */
 #define POLL_HUP	6	/* device disconnected */
 #define NSIGPOLL	6
@@ -178,17 +190,19 @@
  * thread manager then catches and does the appropriate nonsense.
  * However, everything is written out here so as to not get lost.
  */
-#define SIGEV_SIGNAL	0	/* notify via signal */
-#define SIGEV_NONE	1	/* other notification: meaningless */
-#define SIGEV_THREAD	2	/* deliver via thread creation */
+#define SIGEV_NONE	128	/* other notification: meaningless */
+#define SIGEV_SIGNAL	129	/* notify via signal */
+#define SIGEV_CALLBACK	130	/* ??? */
+#define SIGEV_THREAD	131	/* deliver via thread creation */
 
 #define SIGEV_MAX_SIZE	64
 #define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 4)
 
+/* XXX This one isn't yet IRIX / ABI compatible.  */
 typedef struct sigevent {
+	int sigev_notify;
 	sigval_t sigev_value;
 	int sigev_signo;
-	int sigev_notify;
 	union {
 		int _pad[SIGEV_PAD_SIZE];
 
@@ -202,4 +216,4 @@
 #define sigev_notify_function	_sigev_un._sigev_thread._function
 #define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
 
-#endif /* __ASM_MIPS_SIGINFO_H */
+#endif /* _ASM_SIGINFO_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/signal.h linux/include/asm-mips/signal.h
--- v2.3.47/linux/include/asm-mips/signal.h	Tue Oct 20 13:52:54 1998
+++ linux/include/asm-mips/signal.h	Thu Feb 24 22:52:30 2000
@@ -1,13 +1,14 @@
-/* $Id: signal.h,v 1.4 1998/08/18 20:46:42 ralf Exp $
+/* $Id: signal.h,v 1.7 1999/09/28 22:27:17 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_SIGNAL_H
-#define __ASM_MIPS_SIGNAL_H
+#ifndef _ASM_SIGNAL_H
+#define _ASM_SIGNAL_H
 
 #include <linux/types.h>
 
@@ -16,7 +17,7 @@
 #define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
 
 typedef struct {
-	unsigned long sig[_NSIG_WORDS];
+	__u32 sig[_NSIG_WORDS];
 } sigset_t;
 
 typedef unsigned long old_sigset_t;		/* at least 32 bits */
@@ -74,16 +75,19 @@
  * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
  * Unix names RESETHAND and NODEFER respectively.
  */
-#define SA_STACK	0x00000001
-#define SA_RESETHAND	0x00000002
-#define SA_RESTART	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESETHAND	0x80000000
+#define SA_RESTART	0x10000000
 #define SA_SIGINFO	0x00000008
-#define SA_NODEFER	0x00000010
+#define SA_NODEFER	0x40000000
 #define SA_NOCLDWAIT	0x00010000	/* Not supported yet */
-#define SA_NOCLDSTOP	0x00020000
+#define SA_NOCLDSTOP	0x00000001
 
 #define SA_NOMASK	SA_NODEFER
 #define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000	/* dummy -- ignored */
+
+#define SA_RESTORER	0x04000000
 
 /* 
  * sigaltstack controls
@@ -95,18 +99,18 @@
 #define SIGSTKSZ       8192
 
 #ifdef __KERNEL__
+
 /*
  * These values of sa_flags are used only by the kernel as part of the
  * irq handling routines.
  *
- * 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_INTERRUPT is also used by the irq handling routines.
  * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
  */
-#define SA_INTERRUPT		0x01000000	/* interrupt handling */
-#define SA_SHIRQ		0x08000000
 #define SA_PROBE		SA_ONESHOT
 #define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x02000000
+
 #endif /* __KERNEL__ */
 
 #define SIG_BLOCK	1	/* for blocking signals */
@@ -127,13 +131,12 @@
 	unsigned int	sa_flags;
 	__sighandler_t	sa_handler;
 	sigset_t	sa_mask;
-	int		sa_resv[2];	/* reserved */
+	void		(*sa_restorer)(void);
+	int		sa_resv[1];	/* reserved */
 };
 
-/* XXX use sa_rev for storing ka_restorer */
 struct k_sigaction {
 	struct sigaction sa;
-	void (*ka_restorer)(void);
 };
 
 /* IRIX compatible stack_t  */
@@ -145,9 +148,7 @@
 
 #ifdef __KERNEL__
 #include <asm/sigcontext.h>
-#endif
 
-#if defined (__KERNEL__) || defined (__USE_MISC)
 /*
  * The following break codes are or were in use for specific purposes in
  * other MIPS operating systems.  Linux/MIPS doesn't use all of them.  The
@@ -167,6 +168,7 @@
 #define BRK_NORLD	10	/* No rld found - not used by Linux/MIPS */
 #define _BRK_THREADBP	11	/* For threads, user bp (used by debuggers) */
 #define BRK_MULOVF	1023	/* Multiply overflow */
-#endif /* defined (__KERNEL__) || defined (__USE_MISC) */
 
-#endif /* !defined (__ASM_MIPS_SIGNAL_H) */
+#endif /* defined (__KERNEL__) */
+
+#endif /* _ASM_SIGNAL_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/smplock.h linux/include/asm-mips/smplock.h
--- v2.3.47/linux/include/asm-mips/smplock.h	Fri Sep 10 23:57:36 1999
+++ linux/include/asm-mips/smplock.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: smplock.h,v 1.2 1999/10/09 00:01:43 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/sni.h linux/include/asm-mips/sni.h
--- v2.3.47/linux/include/asm-mips/sni.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/sni.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: sni.h,v 1.2 1998/09/16 22:52:43 ralf Exp $
+/* $Id: sni.h,v 1.3 1999/01/04 16:09:26 ralf Exp $
  *
  * SNI specific definitions
  *
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/socket.h linux/include/asm-mips/socket.h
--- v2.3.47/linux/include/asm-mips/socket.h	Tue Oct 20 13:52:54 1998
+++ linux/include/asm-mips/socket.h	Thu Feb 24 22:52:30 2000
@@ -1,5 +1,5 @@
 /*
- * $Id: socket.h,v 1.5 1998/03/15 09:52:54 ralf Exp $
+ * $Id: socket.h,v 1.5 1998/03/17 22:16:17 ralf Exp $
  */
 #ifndef __ASM_MIPS_SOCKET_H
 #define __ASM_MIPS_SOCKET_H
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/softirq.h linux/include/asm-mips/softirq.h
--- v2.3.47/linux/include/asm-mips/softirq.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/softirq.h	Thu Feb 24 22:52:30 2000
@@ -1,98 +1,26 @@
-/* $Id: softirq.h,v 1.6 1999/06/17 13:30:38 ralf Exp $
+/* $Id: softirq.h,v 1.11 2000/02/23 00:41:38 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_SOFTIRQ_H
-#define __ASM_MIPS_SOFTIRQ_H
+#ifndef _ASM_SOFTIRQ_H
+#define _ASM_SOFTIRQ_H
 
-/* The locking mechanism for base handlers, to prevent re-entrancy,
- * is entirely private to an implementation, it should not be
- * referenced at all outside of this file.
- */
-extern atomic_t __mips_bh_counter;
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
 
 extern unsigned int local_bh_count[NR_CPUS];
 
-#define cpu_bh_disable(cpu)    do { local_bh_count[(cpu)]++; barrier(); } while (0)
-#define cpu_bh_enable(cpu)     do { barrier(); local_bh_count[(cpu)]--; } while (0)
-
-#define cpu_bh_trylock(cpu)    (local_bh_count[(cpu)] ? 0 : (local_bh_count[(cpu)] = 1))
-#define cpu_bh_endlock(cpu)    (local_bh_count[(cpu)] = 0)
+#define cpu_bh_disable(cpu)	do { local_bh_count[(cpu)]++; barrier(); } while (0)
+#define cpu_bh_enable(cpu)	do { barrier(); local_bh_count[(cpu)]--; } while (0)
 
-#define local_bh_disable()     cpu_bh_disable(smp_processor_id())
-#define local_bh_enable()      cpu_bh_enable(smp_processor_id())
+#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
+#define local_bh_enable()	cpu_bh_enable(smp_processor_id())
 
-#define get_active_bhs()	(bh_mask & bh_active)
-
-static inline void clear_active_bhs(unsigned long x)
-{
-	unsigned long temp;
-
-	__asm__ __volatile__(
-		"1:\tll\t%0,%1\n\t"
-		"and\t%0,%2\n\t"
-		"sc\t%0,%1\n\t"
-		"beqz\t%0,1b"
-		:"=&r" (temp),
-		 "=m" (bh_active)
-		:"Ir" (~x),
-		 "m" (bh_active));
-}
-
-extern inline void init_bh(int nr, void (*routine)(void))
-{
-	bh_base[nr] = routine;
-	atomic_set(&bh_mask_count[nr], 0);
-	bh_mask |= 1 << nr;
-}
-
-extern inline void remove_bh(int nr)
-{
-	bh_mask &= ~(1 << nr);
-	mb();
-	bh_base[nr] = NULL;
-}
-
-extern inline void mark_bh(int nr)
-{
-	set_bit(nr, &bh_active);
-}
-
-/*
- * These use a mask count to correctly handle
- * nested disable/enable calls
- */
-extern inline void disable_bh(int nr)
-{
-	bh_mask &= ~(1 << nr);
-	atomic_inc(&bh_mask_count[nr]);
-}
-
-extern inline void enable_bh(int nr)
-{
-	if (atomic_dec_and_test(&bh_mask_count[nr]))
-		bh_mask |= 1 << nr;
-}
-
-extern inline void start_bh_atomic(void)
-{
-	local_bh_disable();
-	barrier();
-}
-
-extern inline void end_bh_atomic(void)
-{
-	barrier();
-	local_bh_enable();
-}
-
-/* These are for the irq's testing the lock */
-#define softirq_trylock(cpu)   (cpu_bh_trylock(cpu))
-#define softirq_endlock(cpu)   (cpu_bh_endlock(cpu))
-#define synchronize_bh()	barrier()
+#define in_softirq() (local_bh_count[smp_processor_id()] != 0)
 
-#endif /* __ASM_MIPS_SOFTIRQ_H */
+#endif /* _ASM_SOFTIRQ_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/spinlock.h linux/include/asm-mips/spinlock.h
--- v2.3.47/linux/include/asm-mips/spinlock.h	Fri Sep 10 23:57:36 1999
+++ linux/include/asm-mips/spinlock.h	Thu Feb 24 22:52:30 2000
@@ -1,8 +1,149 @@
-/* $Id: spinlock.h,v 1.5 1999/06/17 13:30:39 ralf Exp $
+/* $Id: spinlock.h,v 1.9 2000/01/25 00:41:46 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_SPINLOCK_H
-#define __ASM_MIPS_SPINLOCK_H
+#ifndef _ASM_SPINLOCK_H
+#define _ASM_SPINLOCK_H
 
-#error "Nix SMP on MIPS"
+/*
+ * Your basic SMP spinlocks, allowing only a single CPU anywhere
+ */
+
+typedef struct {
+	volatile unsigned int lock;
+} spinlock_t;
+
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
+
+#define spin_lock_init(x)	do { (x)->lock = 0; } while(0);
+
+/*
+ * Simple spin lock operations.  There are two variants, one clears IRQ's
+ * on the local processor, one does not.
+ *
+ * We make no fairness assumptions.  They have a cost.
+ */
+
+typedef struct { unsigned long a[100]; } __dummy_lock_t;
+#define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
+
+static inline void spin_lock(spinlock_t *lock)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# spin_lock\n"
+	"1:\tll\t%1, %2\n\t"
+	"bnez\t%1, 1b\n\t"
+	" li\t%1, 1\n\t"
+	"sc\t%1, %0\n\t"
+	"beqz\t%1, 1b\n\t"
+	" sync\n\t"
+	".set\treorder"
+	: "=o" (__dummy_lock(lock)), "=&r" (tmp)
+	: "o" (__dummy_lock(lock))
+	: "memory");
+}
+
+static inline void spin_unlock(spinlock_t *lock)
+{
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# spin_unlock\n\t"
+	"sync\n\t"
+	"sw\t$0, %0\n\t"
+	".set\treorder"	
+	: "=o" (__dummy_lock(lock))
+	: "o" (__dummy_lock(lock))
+	: "memory");
+}
+
+#define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
+
+/*
+ * Read-write spinlocks, allowing multiple readers but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts but no interrupt
+ * writers. For those circumstances we can "mix" irq-safe locks - any writer
+ * needs to get a irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ */
+
+typedef struct {
+	volatile unsigned int lock;
+} rwlock_t;
+
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
+
+static inline void read_lock(rwlock_t *rw)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# read_lock\n"
+	"1:\tll\t%1, %2\n\t"
+	"bltz\t%1, 1b\n\t"
+	" addu\t%1, 1\n\t"
+	"sc\t%1, %0\n\t"
+	"beqz\t%1, 1b\n\t"
+	" sync\n\t"
+	".set\treorder"	
+	: "=o" (__dummy_lock(rw)), "=&r" (tmp)
+	: "o" (__dummy_lock(rw))
+	: "memory");
+}
+
+/* Note the use of sub, not subu which will make the kernel die with an
+   overflow exception if we ever try to unlock an rwlock that is already
+   unlocked or is being held by a writer.  */
+static inline void read_unlock(rwlock_t *rw)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# read_unlock\n"
+	"1:\tll\t%1, %2\n\t"
+	"sub\t%1, 1\n\t"
+	"sc\t%1, %0\n\t"
+	"beqz\t%1, 1b\n\t"
+	".set\treorder"	
+	: "=o" (__dummy_lock(rw)), "=&r" (tmp)
+	: "o" (__dummy_lock(rw))
+	: "memory");
+}
+
+static inline void write_lock(rwlock_t *rw)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# write_lock\n"
+	"1:\tll\t%1, %2\n\t"
+	"bnez\t%1, 1b\n\t"
+	" lui\t%1, 0x8000\n\t"
+	"sc\t%1, %0\n\t"
+	"beqz\t%1, 1b\n\t"
+	" sync\n\t"
+	".set\treorder"	
+	: "=o" (__dummy_lock(rw)), "=&r" (tmp)
+	: "o" (__dummy_lock(rw))
+	: "memory");
+}
+
+static inline void write_unlock(rwlock_t *rw)
+{
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# write_unlock\n\t"
+	"sync\n\t"
+	"sw\t$0, %0\n\t"
+	".set\treorder"	
+	: "=o" (__dummy_lock(rw))
+	: "o" (__dummy_lock(rw))
+	: "memory");
+}
 
-#endif /* __ASM_MIPS_SPINLOCK_H */
+#endif /* _ASM_SPINLOCK_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/stackframe.h linux/include/asm-mips/stackframe.h
--- v2.3.47/linux/include/asm-mips/stackframe.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/stackframe.h	Thu Feb 24 22:52:30 2000
@@ -3,16 +3,20 @@
  *
  *  Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Paul M. Antoine.
  *
- * $Id: stackframe.h,v 1.7 1998/04/28 19:39:15 ralf Exp $
+ * $Id: stackframe.h,v 1.11 1999/12/04 03:59:12 ralf Exp $
  */
 #ifndef __ASM_MIPS_STACKFRAME_H
 #define __ASM_MIPS_STACKFRAME_H
 
 #include <asm/asm.h>
 #include <asm/offset.h>
+#include <linux/config.h>
 
 #define SAVE_AT                                          \
-		sw	$1, PT_R1(sp)
+		.set	push;                            \
+		.set	noat;                            \
+		sw	$1, PT_R1(sp);                   \
+		.set	pop
 
 #define SAVE_TEMP                                        \
 		mfhi	v1;                              \
@@ -100,10 +104,10 @@
 		SAVE_STATIC
 
 #define RESTORE_AT                                       \
+		.set	push;                            \
+		.set	noat;                            \
 		lw	$1,  PT_R1(sp);                  \
-
-#define RESTORE_SP                                       \
-		lw	sp,  PT_R29(sp)
+		.set	pop;
 
 #define RESTORE_TEMP                                     \
 		lw	$24, PT_LO(sp);                  \
@@ -131,6 +135,44 @@
 		lw	$23, PT_R23(sp);                 \
 		lw	$30, PT_R30(sp)
 
+#if defined(CONFIG_CPU_R3000)
+
+#define RESTORE_SOME                                     \
+		.set	push;                            \
+		.set	reorder;                         \
+		mfc0	t0, CP0_STATUS;                  \
+		.set	pop;                             \
+		ori	t0, 0x1f;                        \
+		xori	t0, 0x1f;                        \
+		mtc0	t0, CP0_STATUS;                  \
+		li	v1, 0xff00;                      \
+		and	t0, v1;				 \
+		lw	v0, PT_STATUS(sp);               \
+		nor	v1, $0, v1;			 \
+		and	v0, v1;				 \
+		or	v0, t0;				 \
+		mtc0	v0, CP0_STATUS;                  \
+		lw	$31, PT_R31(sp);                 \
+		lw	$28, PT_R28(sp);                 \
+		lw	$25, PT_R25(sp);                 \
+		lw	$7,  PT_R7(sp);                  \
+		lw	$6,  PT_R6(sp);                  \
+		lw	$5,  PT_R5(sp);                  \
+		lw	$4,  PT_R4(sp);                  \
+		lw	$3,  PT_R3(sp);                  \
+		lw	$2,  PT_R2(sp)
+
+#define RESTORE_SP_AND_RET                               \
+		.set	push;				 \
+		.set	noreorder;			 \
+		lw	k0, PT_EPC(sp);                  \
+		lw	sp,  PT_R29(sp);                 \
+		jr	k0;                              \
+		 rfe;					 \
+		.set	pop
+
+#else
+
 #define RESTORE_SOME                                     \
 		.set	push;                            \
 		.set	reorder;                         \
@@ -158,12 +200,20 @@
 		lw	$3,  PT_R3(sp);                  \
 		lw	$2,  PT_R2(sp)
 
-#define RESTORE_ALL                                      \
+#define RESTORE_SP_AND_RET                               \
+		lw	sp,  PT_R29(sp);                 \
+		.set	mips3;				 \
+		eret;					 \
+		.set	mips0
+
+#endif
+
+#define RESTORE_ALL_AND_RET                              \
 		RESTORE_SOME;                            \
 		RESTORE_AT;                              \
 		RESTORE_TEMP;                            \
 		RESTORE_STATIC;                          \
-		RESTORE_SP
+		RESTORE_SP_AND_RET
 
 /*
  * Move to kernel mode and disable interrupts.
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/stat.h linux/include/asm-mips/stat.h
--- v2.3.47/linux/include/asm-mips/stat.h	Thu Jun 26 12:33:40 1997
+++ linux/include/asm-mips/stat.h	Thu Feb 24 22:52:30 2000
@@ -52,4 +52,41 @@
 	unsigned int	st_gen;
 };
 
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ * XXX We don't ship glibc 2.1 for MIPS yet, so this structure may be
+ * changed without breaking compatibility.  You've been warned.
+ */
+struct stat64 {
+	unsigned long	st_dev;
+	unsigned char	__pad0[8];
+
+	unsigned long	st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned short	st_rdev;
+	unsigned char	__pad3[10];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+
+	unsigned long	st_atime;
+	unsigned long	__pad5;
+
+	unsigned long	st_mtime;
+	unsigned long	__pad6;
+
+	unsigned long	st_ctime;
+	unsigned long	__pad7;		/* will be high 32 bits of ctime someday */
+
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+};
 #endif /* __ASM_MIPS_STAT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/string.h linux/include/asm-mips/string.h
--- v2.3.47/linux/include/asm-mips/string.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/string.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: string.h,v 1.6 1998/07/20 17:52:21 ralf Exp $
+/* $Id: string.h,v 1.13 2000/02/19 14:12:14 harald Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -9,6 +9,8 @@
 #ifndef __ASM_MIPS_STRING_H
 #define __ASM_MIPS_STRING_H
 
+#include <linux/config.h>
+
 #define __HAVE_ARCH_STRCPY
 extern __inline__ char *strcpy(char *__dest, __const__ char *__src)
 {
@@ -74,7 +76,7 @@
 	"addiu\t%1,1\n\t"
 	"bnez\t%2,1b\n\t"
 	"lbu\t%2,(%0)\n\t"
-#if _MIPS_ISA == _MIPS_ISA_MIPS1
+#if defined(CONFIG_CPU_R3000)
 	"nop\n\t"
 #endif
 	"move\t%2,$1\n"
@@ -89,30 +91,37 @@
 }
 
 #define __HAVE_ARCH_STRNCMP
-extern __inline__ int strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count)
+extern __inline__ int
+strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count)
 {
-  int __res;
+	int __res;
 
-  __asm__ __volatile__(
+	__asm__ __volatile__(
 	".set\tnoreorder\n\t"
 	".set\tnoat\n"
-	"1:\tlbu\t%3,(%1)\n\t"
+	"1:\tlbu\t%3,(%0)\n\t"
+#if defined(CONFIG_CPU_R3000)
+	"lbu\t$1,(%1)\n\t"
+	"nop\n\t"
 	"beqz\t%2,2f\n\t"
-	"lbu\t$1,(%0)\n\t"
-	"addiu\t%1,1\n\t"
-	"subu\t%3,$1,%3\n\t"
-	"bnez\t%3,2f\n\t"
+#else
+	"beqz\t%2,2f\n\t"
+	"lbu\t$1,(%1)\n\t"
+#endif
+	"subu\t%2,1\n\t"
+	"bne\t$1,%3,3f\n\t"
 	"addiu\t%0,1\n\t"
-	"bnez\t%1,1b\n"
-	"addiu\t%2,-1\n"
-	"2:\n\t"
+	"bnez\t%3,1b\n\t"
+	"addiu\t%1,1\n"
+	"2:\tmove\t%3,$1\n"
+	"3:\tsubu\t%3,$1\n\t"
 	".set\tat\n\t"
 	".set\treorder"
 	: "=r" (__cs), "=r" (__ct), "=r" (__count), "=r" (__res)
 	: "0" (__cs), "1" (__ct), "2" (__count)
 	: "$1");
 
-  return __res;
+	return __res;
 }
 
 #define __HAVE_ARCH_MEMSET
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/system.h linux/include/asm-mips/system.h
--- v2.3.47/linux/include/asm-mips/system.h	Tue Aug  3 08:01:29 1999
+++ linux/include/asm-mips/system.h	Thu Feb 24 22:52:30 2000
@@ -1,30 +1,33 @@
-/* $Id: system.h,v 1.8 1998/07/20 17:52:21 ralf Exp $
+/* $Id: system.h,v 1.21 1999/12/30 14:21:21 raiko Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Ralf Baechle
- * Modified further for R[236]000 by Paul M. Antoine, 1996
+ * Copyright (C) 1994 - 1999 by Ralf Baechle
+ * Copyright (C) 1996 by Paul M. Antoine
+ * Copyright (C) 1994 - 1999 by Ralf Baechle
  */
-#ifndef __ASM_MIPS_SYSTEM_H
-#define __ASM_MIPS_SYSTEM_H
+#ifndef _ASM_SYSTEM_H
+#define _ASM_SYSTEM_H
 
+#include <linux/config.h>
 #include <asm/sgidefs.h>
+#include <asm/ptrace.h>
 #include <linux/kernel.h>
 
 extern __inline__ void
 __sti(void)
 {
 	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
+		".set\tpush\n\t"
+		".set\treorder\n\t"
 		".set\tnoat\n\t"
 		"mfc0\t$1,$12\n\t"
 		"ori\t$1,0x1f\n\t"
 		"xori\t$1,0x1e\n\t"
 		"mtc0\t$1,$12\n\t"
-		".set\tat\n\t"
-		".set\treorder"
+		".set\tpop\n\t"
 		: /* no outputs */
 		: /* no inputs */
 		: "$1", "memory");
@@ -41,17 +44,18 @@
 __cli(void)
 {
 	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
+		".set\tpush\n\t"
+		".set\treorder\n\t"
 		".set\tnoat\n\t"
 		"mfc0\t$1,$12\n\t"
 		"ori\t$1,1\n\t"
 		"xori\t$1,1\n\t"
+		".set\tnoreorder\n\t"
 		"mtc0\t$1,$12\n\t"
 		"nop\n\t"
 		"nop\n\t"
 		"nop\n\t"
-		".set\tat\n\t"
-		".set\treorder"
+		".set\tpop\n\t"
 		: /* no outputs */
 		: /* no inputs */
 		: "$1", "memory");
@@ -59,26 +63,28 @@
 
 #define __save_flags(x)                  \
 __asm__ __volatile__(                    \
-	".set\tnoreorder\n\t"            \
+	".set\tpush\n\t"		 \
+	".set\treorder\n\t"              \
 	"mfc0\t%0,$12\n\t"               \
-	".set\treorder"                  \
+	".set\tpop\n\t"                      \
 	: "=r" (x)                       \
 	: /* no inputs */                \
 	: "memory")
 
 #define __save_and_cli(x)                \
 __asm__ __volatile__(                    \
-	".set\tnoreorder\n\t"            \
+	".set\tpush\n\t"		 \
+	".set\treorder\n\t"              \
 	".set\tnoat\n\t"                 \
 	"mfc0\t%0,$12\n\t"               \
 	"ori\t$1,%0,1\n\t"               \
 	"xori\t$1,1\n\t"                 \
+	".set\tnoreorder\n\t"		 \
 	"mtc0\t$1,$12\n\t"               \
 	"nop\n\t"                        \
 	"nop\n\t"                        \
 	"nop\n\t"                        \
-	".set\tat\n\t"                   \
-	".set\treorder"                  \
+	".set\tpop\n\t"                  \
 	: "=r" (x)                       \
 	: /* no inputs */                \
 	: "$1", "memory")
@@ -87,19 +93,21 @@
 __restore_flags(int flags)
 {
 	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
+		".set\tpush\n\t"
+		".set\treorder\n\t"
 		"mfc0\t$8,$12\n\t"
 		"li\t$9,0xff00\n\t"
 		"and\t$8,$9\n\t"
 		"nor\t$9,$0,$9\n\t"
 		"and\t%0,$9\n\t"
 		"or\t%0,$8\n\t"
+		".set\tnoreorder\n\t"
 		"mtc0\t%0,$12\n\t"
 		"nop\n\t"
 		"nop\n\t"
 		"nop\n\t"
-		".set\treorder"
-		: /* no output */
+		".set\tpop\n\t"
+		:
 		: "r" (flags)
 		: "$8", "$9", "memory");
 }
@@ -122,6 +130,12 @@
 /*
  * These are probably defined overly paranoid ...
  */
+#ifdef CONFIG_CPU_HAS_WB
+#include <asm/wbflush.h>
+#define rmb()
+#define wmb() wbflush()
+#define mb() wbflush()
+#else
 #define mb()						\
 __asm__ __volatile__(					\
 	"# prevent instructions being moved around\n\t"	\
@@ -134,13 +148,23 @@
 	: "memory")
 #define rmb() mb()
 #define wmb() mb()
+#endif
+
+#define set_mb(var, value) \
+do { var = value; mb(); } while (0)
+
+#define set_rmb(var, value) \
+do { var = value; rmb(); } while (0)
+
+#define set_wmb(var, value) \
+do { var = value; wmb(); } while (0)
 
 #if !defined (_LANGUAGE_ASSEMBLY)
 /*
  * switch_to(n) should switch tasks to task nr n, first
  * checking that n isn't the current task, in which case it does nothing.
  */
-extern asmlinkage void *(*resume)(void *last, void *next);
+extern asmlinkage void *resume(void *last, void *next);
 #endif /* !defined (_LANGUAGE_ASSEMBLY) */
 
 #define prepare_to_switch()	do { } while(0)
@@ -155,8 +179,7 @@
  */
 extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
 {
-#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \
-    (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
+#if defined(CONFIG_CPU_HAS_LLSC)
 	unsigned long dummy;
 
 	__asm__ __volatile__(
@@ -172,6 +195,8 @@
 		: "=r" (val), "=r" (m), "=r" (dummy)
 		: "1" (m), "2" (val)
 		: "memory");
+
+	return val;
 #else
 	unsigned long flags, retval;
 
@@ -180,9 +205,9 @@
 	retval = *m;
 	*m = val;
 	restore_flags(flags);
+	return retval;
 
 #endif /* Processor-dependent optimization */
-	return val;
 }
 
 /*
@@ -199,7 +224,7 @@
 		"1:\tmove\t$1,%2\n\t"
 		"scd\t$1,(%1)\n\t"
 		"beqzl\t$1,1b\n\t"
-		"ll\t%0,(%1)\n\t"
+		"lld\t%0,(%1)\n\t"
 		".set\tat\n\t"
 		".set\treorder"
 		: "=r" (val), "=r" (m), "=r" (dummy)
@@ -238,4 +263,14 @@
 
 extern void set_except_vector(int n, void *addr);
 
-#endif /* __ASM_MIPS_SYSTEM_H */
+extern void __die(const char *, struct pt_regs *, const char *where,
+	unsigned long line) __attribute__((noreturn));
+extern void __die_if_kernel(const char *, struct pt_regs *, const char *where,
+	unsigned long line);
+
+#define die(msg, regs)							\
+	__die(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__)
+#define die_if_kernel(msg, regs)					\
+	__die_if_kernel(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__)
+
+#endif /* _ASM_SYSTEM_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/termios.h linux/include/asm-mips/termios.h
--- v2.3.47/linux/include/asm-mips/termios.h	Fri Jan 28 15:09:09 2000
+++ linux/include/asm-mips/termios.h	Thu Feb 24 22:52:30 2000
@@ -1,5 +1,4 @@
-/*
- * ioctls for Linux/MIPS.
+/* $Id: termios.h,v 1.9 2000/02/18 00:24:48 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -7,7 +6,8 @@
  *
  * Copyright (C) 1995, 1996 by Ralf Baechle
  */
-#ifndef __ASM_MIPS_TERMIOS_H
+#ifndef _ASM_TERMIOS_H
+#define _ASM_TERMIOS_H
 
 #include <asm/termbits.h>
 #include <asm/ioctls.h>
@@ -100,7 +100,7 @@
 #define N_IRDA		11	/* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14
+#define N_SYNC_PPP	14	/* synchronous PPP */
 
 #ifdef __KERNEL__
 
@@ -142,4 +142,4 @@
 
 #endif /* defined(__KERNEL__) */
 
-#endif /* __ASM_MIPS_TERMIOS_H */
+#endif /* _ASM_TERMIOS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/types.h linux/include/asm-mips/types.h
--- v2.3.47/linux/include/asm-mips/types.h	Fri May  8 00:13:26 1998
+++ linux/include/asm-mips/types.h	Thu Feb 24 22:52:30 2000
@@ -1,14 +1,14 @@
-/*
- * include/asm-mips/types.h
+/* $Id: types.h,v 1.4 2000/02/18 00:24:48 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_TYPES_H
-#define __ASM_MIPS_TYPES_H
+#ifndef _ASM_TYPES_H
+#define _ASM_TYPES_H
 
 typedef unsigned long umode_t;
 
@@ -26,18 +26,18 @@
 typedef __signed__ int __s32;
 typedef unsigned int __u32;
 
-#if ((~0UL) == 0xffffffff)
+#if (_MIPS_SZLONG == 64)
 
+typedef __signed__ long __s64;
+typedef unsigned long __u64;
+
+#else
+ 
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
 typedef __signed__ long long __s64;
 typedef unsigned long long __u64;
 #endif
-  
-#else
-  
-typedef __signed__ long __s64;
-typedef unsigned long __u64;
-
+ 
 #endif
 
 /*
@@ -54,21 +54,24 @@
 typedef __signed int s32;
 typedef unsigned int u32;
 
-#if ((~0UL) == 0xffffffff)
+#if (_MIPS_SZLONG == 64)
+
+typedef __signed__ long s64;
+typedef unsigned long u64;
+
+#else
 
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
 typedef __signed__ long long s64;
 typedef unsigned long long u64;
 #endif
-  
-#else
-  
-typedef __signed__ long s64;
-typedef unsigned long u64;
 
 #endif
+
 #define BITS_PER_LONG _MIPS_SZLONG
 
+typedef unsigned long dma_addr_t;
+
 #endif /* __KERNEL__ */
 
-#endif /* __ASM_MIPS_TYPES_H */
+#endif /* _ASM_TYPES_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/uaccess.h linux/include/asm-mips/uaccess.h
--- v2.3.47/linux/include/asm-mips/uaccess.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/uaccess.h	Thu Feb 24 22:52:30 2000
@@ -1,16 +1,14 @@
-/*
- * include/asm-mips/uaccess.h
+/* $Id: uaccess.h,v 1.12 2000/02/21 18:05:07 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
- *
- * $Id: uaccess.h,v 1.15 1998/05/03 11:13:54 ralf Exp $
+ * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_UACCESS_H
-#define __ASM_MIPS_UACCESS_H
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
 
 #include <linux/errno.h>
 #include <linux/sched.h>
@@ -25,15 +23,15 @@
  *
  * For historical reasons, these macros are grossly misnamed.
  */
-#define KERNEL_DS	((mm_segment_t) { 0UL })
-#define USER_DS		((mm_segment_t) { 1UL })
+#define KERNEL_DS	((mm_segment_t) { (unsigned long) 0L })
+#define USER_DS		((mm_segment_t) { (unsigned long) -1L })
 
 #define VERIFY_READ    0
 #define VERIFY_WRITE   1
 
-#define get_fs()        (current->tss.current_ds)
+#define get_fs()        (current->thread.current_ds)
 #define get_ds()	(KERNEL_DS)
-#define set_fs(x)       (current->tss.current_ds=(x))
+#define set_fs(x)       (current->thread.current_ds=(x))
 
 #define segment_eq(a,b)	((a).seg == (b).seg)
 
@@ -50,7 +48,7 @@
  */
 #define __access_ok(addr,size,mask) \
         (((__signed__ long)((mask)&(addr | size | (addr+size)))) >= 0)
-#define __access_mask (-(long)(get_fs().seg))
+#define __access_mask ((long)(get_fs().seg))
 
 #define access_ok(type,addr,size) \
 __access_ok(((unsigned long)(addr)),(size),__access_mask)
@@ -325,10 +323,12 @@
 		"move\t$4, %1\n\t" \
 		"move\t$5, %2\n\t" \
 		"move\t$6, %3\n\t" \
+		".set\tnoreorder\n\t" \
+		__MODULE_JAL(__copy_user) \
 		".set\tnoat\n\t" \
 		"addu\t$1, %2, %3\n\t" \
 		".set\tat\n\t" \
-		__MODULE_JAL(__copy_user) \
+		".set\treorder\n\t" \
 		"move\t%0, $6" \
 		: "=r" (__cu_len) \
 		: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
@@ -372,10 +372,12 @@
 			"move\t$4, %1\n\t" \
 			"move\t$5, %2\n\t" \
 			"move\t$6, %3\n\t" \
+			".set\tnoreorder\n\t" \
+			__MODULE_JAL(__copy_user) \
 			".set\tnoat\n\t" \
 			"addu\t$1, %2, %3\n\t" \
 			".set\tat\n\t" \
-			__MODULE_JAL(__copy_user) \
+			".set\treorder\n\t" \
 			"move\t%0, $6" \
 			: "=r" (__cu_len) \
 			: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
@@ -449,7 +451,6 @@
 	return res;
 }
 
-
 /* Returns: 0 if bad, string length+1 (memory size) of string if ok */
 extern inline long __strlen_user(const char *s)
 {
@@ -481,6 +482,39 @@
 	return res;
 }
 
+/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
+extern inline long __strnlen_user(const char *s, long n)
+{
+	long res;
+
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		"move\t$5, %2\n\t"
+		__MODULE_JAL(__strnlen_user_nocheck_asm)
+		"move\t%0, $2"
+		: "=r" (res)
+		: "r" (s), "r" (n)
+		: "$2", "$4", "$5", "$8", "$31");
+
+	return res;
+}
+
+extern inline long strnlen_user(const char *s, long n)
+{
+	long res;
+
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		"move\t$5, %2\n\t"
+		__MODULE_JAL(__strnlen_user_asm)
+		"move\t%0, $2"
+		: "=r" (res)
+		: "r" (s), "r" (n)
+		: "$2", "$4", "$5", "$8", "$31");
+
+	return res;
+}
+
 struct exception_table_entry
 {
 	unsigned long insn;
@@ -496,4 +530,4 @@
 	fixup_unit;                                             \
 })
 
-#endif /* __ASM_MIPS_UACCESS_H */
+#endif /* _ASM_UACCESS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/ucontext.h linux/include/asm-mips/ucontext.h
--- v2.3.47/linux/include/asm-mips/ucontext.h	Fri May  8 00:13:26 1998
+++ linux/include/asm-mips/ucontext.h	Thu Feb 24 22:52:30 2000
@@ -1,5 +1,15 @@
-#ifndef __ASM_MIPS_UCONTEXT_H
-#define __ASM_MIPS_UCONTEXT_H
+/* $Id: ucontext.h,v 1.2 1999/09/28 22:27:17 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Low level exception handling
+ *
+ * Copyright (C) 1998, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_UCONTEXT_H
+#define _ASM_UCONTEXT_H
 
 struct ucontext {
 	unsigned long	  uc_flags;
@@ -9,4 +19,4 @@
 	sigset_t	  uc_sigmask;	/* mask last for extensibility */
 };
 
-#endif /* __ASM_MIPS_UCONTEXT_H */
+#endif /* _ASM_UCONTEXT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/unaligned.h linux/include/asm-mips/unaligned.h
--- v2.3.47/linux/include/asm-mips/unaligned.h	Wed Dec 10 10:31:11 1997
+++ linux/include/asm-mips/unaligned.h	Thu Feb 24 22:52:30 2000
@@ -1,16 +1,16 @@
-/*
- * Inline functions to do unaligned accesses.
+/* $Id: unaligned.h,v 1.3 1999/08/19 22:56:34 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996 by Ralf Baechle
+ * Copyright (C) 1996, 1999 by Ralf Baechle
  */
-#ifndef __ASM_MIPS_UNALIGNED_H
-#define __ASM_MIPS_UNALIGNED_H
+#ifndef _ASM_UNALIGNED_H
+#define _ASM_UNALIGNED_H
 
-#include <asm/string.h>
+extern void __get_unaligned_bad_length(void);
+extern void __put_unaligned_bad_length(void);
 
 /*
  * Load quad unaligned.
@@ -94,18 +94,21 @@
 {
 	unsigned long val;
 	switch (size) {
-	      case 1:
+	case 1:
 		val = *(const unsigned char *)ptr;
 		break;
-	      case 2:
+	case 2:
 		val = ldw_u((const unsigned short *)ptr);
 		break;
-	      case 4:
+	case 4:
 		val = ldl_u((const unsigned int *)ptr);
 		break;
-	      case 8:
+	case 8:
 		val = ldq_u((const unsigned long long *)ptr);
 		break;
+	default:
+		__get_unaligned_bad_length();
+		break;
 	}
 	return val;
 }
@@ -113,18 +116,21 @@
 extern inline void __put_unaligned(unsigned long val, void *ptr, size_t size)
 {
 	switch (size) {
-	      case 1:
+	case 1:
 		*(unsigned char *)ptr = (val);
-	        break;
-	      case 2:
+		break;
+	case 2:
 		stw_u(val, (unsigned short *)ptr);
 		break;
-	      case 4:
+	case 4:
 		stl_u(val, (unsigned int *)ptr);
 		break;
-	      case 8:
+	case 8:
 		stq_u(val, (unsigned long long *)ptr);
 		break;
+	default:
+		__put_unaligned_bad_length();
+		break;
 	}
 }
 
@@ -136,4 +142,4 @@
 #define put_unaligned(x,ptr) \
 	__put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr)))
 
-#endif /* __ASM_MIPS_UNALIGNED_H */
+#endif /* _ASM_UNALIGNED_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/unistd.h linux/include/asm-mips/unistd.h
--- v2.3.47/linux/include/asm-mips/unistd.h	Wed Jul 28 10:30:10 1999
+++ linux/include/asm-mips/unistd.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.21 1998/10/19 21:29:15 ralf Exp $
+/* $Id: unistd.h,v 1.20 2000/02/18 00:24:48 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -1015,7 +1015,7 @@
 #define __NR_ptrace			(__NR_Linux +  26)
 #define __NR_alarm			(__NR_Linux +  27)
 #define __NR_oldfstat			(__NR_Linux +  28)
-#define __NR_pause			(__NR_Linux +  29)
+#define __NR_unused29			(__NR_Linux +  29)
 #define __NR_utime			(__NR_Linux +  30)
 #define __NR_stty			(__NR_Linux +  31)
 #define __NR_gtty			(__NR_Linux +  32)
@@ -1196,11 +1196,18 @@
 #define __NR_sendfile			(__NR_Linux + 207)
 #define __NR_getpmsg			(__NR_Linux + 208)
 #define __NR_putpmsg			(__NR_Linux + 209)
+#define __NR_mmap2			(__NR_Linux + 210)
+#define __NR_truncate64			(__NR_Linux + 211)
+#define __NR_ftruncate64		(__NR_Linux + 212)
+#define __NR_stat64			(__NR_Linux + 213)
+#define __NR_lstat64			(__NR_Linux + 214)
+#define __NR_fstat64			(__NR_Linux + 215)
+#define __NR_pivot_root			(__NR_Linux + 216)
 
 /*
  * Offset of the last Linux flavoured syscall
  */
-#define __NR_Linux_syscalls		209
+#define __NR_Linux_syscalls		216
 
 #ifndef _LANGUAGE_ASSEMBLY
 
@@ -1419,8 +1426,6 @@
  * some others too.
  */
 #define __NR__exit __NR_exit
-static inline _syscall0(int,idle)
-static inline _syscall0(int,pause)
 static inline _syscall0(int,sync)
 static inline _syscall0(pid_t,setsid)
 static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/watch.h linux/include/asm-mips/watch.h
--- v2.3.47/linux/include/asm-mips/watch.h	Tue Oct 20 13:52:54 1998
+++ linux/include/asm-mips/watch.h	Thu Feb 24 22:52:30 2000
@@ -1,4 +1,4 @@
-/* $Id: watch.h,v 1.3 1998/08/19 21:58:15 ralf Exp $
+/* $Id: watch.h,v 1.3 1998/08/25 09:22:05 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/wbflush.h linux/include/asm-mips/wbflush.h
--- v2.3.47/linux/include/asm-mips/wbflush.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/wbflush.h	Thu Feb 24 22:52:30 2000
@@ -0,0 +1,36 @@
+/*
+ * Header file for using the wbflush routine
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1998 Harald Koerfgen
+ *
+ * $Id: wbflush.h,v 1.3 1999/10/07 07:27:43 raiko Exp $
+ */
+#ifndef __ASM_MIPS_WBFLUSH_H
+#define __ASM_MIPS_WBFLUSH_H
+
+#include <linux/config.h>
+
+#if defined(CONFIG_CPU_HAS_WB)
+/*
+ * R2000 or R3000
+ */
+extern void (*__wbflush) (void);
+
+#define wbflush() __wbflush()
+
+#else
+/*
+ * we don't need no stinkin' wbflush
+ */
+
+#define wbflush()
+
+#endif
+
+extern void wbflush_setup(void);
+
+#endif /* __ASM_MIPS_WBFLUSH_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/a.out.h linux/include/asm-mips64/a.out.h
--- v2.3.47/linux/include/asm-mips64/a.out.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/a.out.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,34 @@
+/* $Id: a.out.h,v 1.2 2000/01/16 01:40:43 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999 by Ralf Baechle
+ */
+#ifndef _ASM_A_OUT_H
+#define _ASM_A_OUT_H
+
+struct exec
+{
+  unsigned long a_info;		/* Use macros N_MAGIC, etc for access */
+  unsigned a_text;		/* length of text, in bytes */
+  unsigned a_data;		/* length of data, in bytes */
+  unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
+  unsigned a_syms;		/* length of symbol table data in file, in bytes */
+  unsigned a_entry;		/* start address */
+  unsigned a_trsize;		/* length of relocation info for text, in bytes */
+  unsigned a_drsize;		/* length of relocation info for data, in bytes */
+};
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+#ifdef __KERNEL__
+
+#define STACK_TOP (current->thread.mflags & MF_32BIT ? 0x7fff8000 : TASK_SIZE)
+
+#endif
+
+#endif /* _ASM_A_OUT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/addrspace.h linux/include/asm-mips64/addrspace.h
--- v2.3.47/linux/include/asm-mips64/addrspace.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/addrspace.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,107 @@
+/* $Id: addrspace.h,v 1.6 2000/02/10 20:20:15 kanoj Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1990, 1999 by Silicon Graphics, Inc.
+ */
+#ifndef _ASM_ADDRSPACE_H
+#define _ASM_ADDRSPACE_H
+
+#include <linux/config.h>
+
+/*
+ * Memory segments (32bit kernel mode addresses)
+ */
+#define KUSEG                   0x0000000000000000
+#define KSEG0                   0xffffffff80000000
+#define KSEG1                   0xffffffffa0000000
+#define KSEG2                   0xffffffffc0000000
+#define KSEG3                   0xffffffffe0000000
+
+/*
+ * Returns the kernel segment base of a given address
+ */
+#define KSEGX(a)                (((unsigned long)(a)) & 0xe0000000)
+
+/*
+ * Returns the physical address of a KSEG0/KSEG1 address
+ */
+#define CPHYSADDR(a)		(((unsigned long)(a)) & 0x000000001fffffffUL)
+#define PHYSADDR(a)		(((unsigned long)(a)) & 0x000000ffffffffffUL)
+
+/*
+ * Map an address to a certain kernel segment
+ */
+#define KSEG0ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x000000ffffffffffUL) | KSEG0))
+#define KSEG1ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x000000ffffffffffUL) | KSEG1))
+#define KSEG2ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x000000ffffffffffUL) | KSEG2))
+#define KSEG3ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x000000ffffffffffUL) | KSEG3))
+
+/*
+ * Memory segments (64bit kernel mode addresses)
+ */
+#define XKUSEG                  0x0000000000000000
+#define XKSSEG                  0x4000000000000000
+#define XKPHYS                  0x8000000000000000
+#define XKSEG                   0xc000000000000000
+#define CKSEG0                  0xffffffff80000000
+#define CKSEG1                  0xffffffffa0000000
+#define CKSSEG                  0xffffffffc0000000
+#define CKSEG3                  0xffffffffe0000000
+
+#if defined (CONFIG_CPU_R4300)						\
+    || defined (CONFIG_CPU_R4X00)					\
+    || defined (CONFIG_CPU_R5000)					\
+    || defined (CONFIG_CPU_NEVADA)
+#define	KUSIZE		0x0000010000000000		/* 2^^40 */
+#define	KUSIZE_64	0x0000010000000000		/* 2^^40 */
+#define	K0SIZE		0x0000001000000000		/* 2^^36 */
+#define	K1SIZE		0x0000001000000000		/* 2^^36 */
+#define	K2SIZE		0x000000ff80000000
+#define	KSEGSIZE	0x000000ff80000000		/* max syssegsz */
+#define TO_PHYS_MASK	0x0000000fffffffff		/* 2^^36 - 1 */
+#endif
+
+#if defined (CONFIG_CPU_R8000)
+/* We keep KUSIZE consistent with R4000 for now (2^^40) instead of (2^^48) */
+#define	KUSIZE		0x0000010000000000		/* 2^^40 */
+#define	KUSIZE_64	0x0000010000000000		/* 2^^40 */
+#define	K0SIZE		0x0000010000000000		/* 2^^40 */
+#define	K1SIZE		0x0000010000000000		/* 2^^40 */
+#define	K2SIZE		0x0001000000000000
+#define	KSEGSIZE	0x0000010000000000		/* max syssegsz */
+#define TO_PHYS_MASK	0x000000ffffffffff		/* 2^^40 - 1 */
+#endif
+
+#if defined (CONFIG_CPU_R10000)
+#define	KUSIZE		0x0000010000000000		/* 2^^40 */
+#define	KUSIZE_64	0x0000010000000000		/* 2^^40 */
+#define	K0SIZE		0x0000010000000000		/* 2^^40 */
+#define	K1SIZE		0x0000010000000000		/* 2^^40 */
+#define	K2SIZE		0x00000fff80000000
+#define	KSEGSIZE	0x00000fff80000000		/* max syssegsz */
+#define TO_PHYS_MASK	0x000000ffffffffff		/* 2^^40 - 1 */
+#endif
+
+/*
+ * Further names for SGI source compatibility.  These are stolen from
+ * IRIX's <sys/mips_addrspace.h>.
+ */
+#define KUBASE		0
+#define KUSIZE_32	0x0000000080000000	/* KUSIZE for a 32 bit proc */
+#define K0BASE		0xa800000000000000
+#define K0BASE_EXL_WR	K0BASE			/* exclusive on write */
+#define K0BASE_NONCOH	0x9800000000000000	/* noncoherent */
+#define K0BASE_EXL	0xa000000000000000	/* exclusive */
+
+#ifdef CONFIG_SGI_IP27
+#define K1BASE		0x9600000000000000	/* Uncached attr 3, uncac */
+#else
+#define K1BASE		0x9000000000000000
+#endif
+#define K2BASE		0xc000000000000000
+
+#endif /* _ASM_ADDRSPACE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/arc/hinv.h linux/include/asm-mips64/arc/hinv.h
--- v2.3.47/linux/include/asm-mips64/arc/hinv.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/arc/hinv.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,175 @@
+/* $Id: hinv.h,v 1.1 2000/01/17 23:32:47 ralf Exp $
+ *
+ * ARCS hardware/memory inventory/configuration and system ID definitions.
+ */
+#ifndef _ASM_ARC_HINV_H
+#define _ASM_ARC_HINV_H
+
+#include <asm/arc/types.h>
+
+/* configuration query defines */
+typedef enum configclass {
+	SystemClass,
+	ProcessorClass,
+	CacheClass,
+#ifndef	_NT_PROM
+	MemoryClass,
+	AdapterClass,
+	ControllerClass,
+	PeripheralClass
+#else	/* _NT_PROM */
+	AdapterClass,
+	ControllerClass,
+	PeripheralClass,
+	MemoryClass
+#endif	/* _NT_PROM */
+} CONFIGCLASS;
+
+typedef enum configtype {
+	ARC,
+	CPU,
+	FPU,
+	PrimaryICache,
+	PrimaryDCache,
+	SecondaryICache,
+	SecondaryDCache,
+	SecondaryCache,
+#ifndef	_NT_PROM
+	Memory,
+#endif
+	EISAAdapter,
+	TCAdapter,
+	SCSIAdapter,
+	DTIAdapter,
+	MultiFunctionAdapter,
+	DiskController,
+	TapeController,
+	CDROMController,
+	WORMController,
+	SerialController,
+	NetworkController,
+	DisplayController,
+	ParallelController,
+	PointerController,
+	KeyboardController,
+	AudioController,
+	OtherController,
+	DiskPeripheral,
+	FloppyDiskPeripheral,
+	TapePeripheral,
+	ModemPeripheral,
+	MonitorPeripheral,
+	PrinterPeripheral,
+	PointerPeripheral,
+	KeyboardPeripheral,
+	TerminalPeripheral,
+	LinePeripheral,
+	NetworkPeripheral,
+#ifdef	_NT_PROM
+	Memory,
+#endif
+	OtherPeripheral,
+
+	/* new stuff for IP30 */
+	/* added without moving anything */
+	/* except ANONYMOUS. */
+
+	XTalkAdapter,
+	PCIAdapter,
+	GIOAdapter,
+	TPUAdapter,
+
+	Anonymous
+} CONFIGTYPE;
+
+typedef enum {
+	Failed = 1,
+	ReadOnly = 2,
+	Removable = 4,
+	ConsoleIn = 8,
+	ConsoleOut = 16,
+	Input = 32,
+	Output = 64
+} IDENTIFIERFLAG;
+
+#ifndef NULL			/* for GetChild(NULL); */
+#define	NULL	0
+#endif
+
+union key_u {
+	struct {
+#ifdef	_MIPSEB
+		unsigned char  c_bsize;		/* block size in lines */
+		unsigned char  c_lsize;		/* line size in bytes/tag */
+		unsigned short c_size;		/* cache size in 4K pages */
+#else	/* _MIPSEL */
+		unsigned short c_size;		/* cache size in 4K pages */
+		unsigned char  c_lsize;		/* line size in bytes/tag */
+		unsigned char  c_bsize;		/* block size in lines */
+#endif	/* _MIPSEL */
+	} cache;
+	ULONG FullKey;
+};
+
+#if _MIPS_SIM == _ABI64
+#define SGI_ARCS_VERS	64			/* sgi 64-bit version */
+#define SGI_ARCS_REV	0			/* rev .00 */
+#else
+#define SGI_ARCS_VERS	1			/* first version */
+#define SGI_ARCS_REV	10			/* rev .10, 3/04/92 */
+#endif
+
+typedef struct component {
+	CONFIGCLASS	Class;
+	CONFIGTYPE	Type;
+	IDENTIFIERFLAG	Flags;
+	USHORT		Version;
+	USHORT		Revision;
+	ULONG 		Key;
+	ULONG		AffinityMask;
+	ULONG		ConfigurationDataSize;
+	ULONG		IdentifierLength;
+	char		*Identifier;
+} COMPONENT;
+
+/* internal structure that holds pathname parsing data */
+struct cfgdata {
+	char *name;			/* full name */
+	int minlen;			/* minimum length to match */
+	CONFIGTYPE type;		/* type of token */
+};
+
+/* System ID */
+typedef struct systemid {
+	CHAR VendorId[8];
+	CHAR ProductId[8];
+} SYSTEMID;
+
+/* memory query functions */
+typedef enum memorytype {
+	ExceptionBlock,
+	SPBPage,			/* ARCS == SystemParameterBlock */
+#ifndef	_NT_PROM
+	FreeContiguous,
+	FreeMemory,
+	BadMemory,
+	LoadedProgram,
+	FirmwareTemporary,
+	FirmwarePermanent
+#else	/* _NT_PROM */
+	FreeMemory,
+	BadMemory,
+	LoadedProgram,
+	FirmwareTemporary,
+	FirmwarePermanent,
+	FreeContiguous
+#endif	/* _NT_PROM */
+} MEMORYTYPE;
+
+typedef struct memorydescriptor {
+	MEMORYTYPE	Type;
+	LONG		BasePage;
+	LONG		PageCount;
+} MEMORYDESCRIPTOR;
+
+#endif /* _ASM_ARC_HINV_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/arc/types.h linux/include/asm-mips64/arc/types.h
--- v2.3.47/linux/include/asm-mips64/arc/types.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/arc/types.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,72 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_ARC_TYPES_H
+#define _ASM_ARC_TYPES_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_ARC32
+
+typedef char		CHAR;
+typedef short		SHORT;
+typedef long		LARGE_INTEGER __attribute__ ((__mode__ (__DI__)));
+typedef	long		LONG __attribute__ ((__mode__ (__SI__)));
+typedef unsigned char	UCHAR;
+typedef unsigned short	USHORT;
+typedef unsigned long	ULONG __attribute__ ((__mode__ (__SI__)));
+typedef void		VOID;
+
+/* The pointer types.  Note that we're using a 64-bit compiler but all
+   pointer in the ARC structures are only 32-bit, so we need some disgusting
+   workarounds.  Keep your vomit bag handy.  */
+typedef LONG		_PCHAR;
+typedef LONG		_PSHORT;
+typedef LONG		_PLARGE_INTEGER;
+typedef	LONG		_PLONG;
+typedef LONG		_PUCHAR;
+typedef LONG		_PUSHORT;
+typedef LONG		_PULONG;
+typedef LONG		_PVOID;
+
+#endif /* CONFIG_ARC32 */
+
+#ifdef CONFIG_ARC64
+
+typedef char		CHAR;
+typedef short		SHORT;
+typedef long		LARGE_INTEGER __attribute__ ((__mode__ (__DI__)));
+typedef	long		LONG __attribute__ ((__mode__ (__DI__)));
+typedef unsigned char	UCHAR;
+typedef unsigned short	USHORT;
+typedef unsigned long	ULONG __attribute__ ((__mode__ (__DI__)));
+typedef void		VOID;
+
+/* The pointer types.  We're 64-bit and the firmware is also 64-bit, so
+   live is sane ...  */
+typedef CHAR		*_PCHAR;
+typedef SHORT		*_PSHORT;
+typedef LARGE_INTEGER	*_PLARGE_INTEGER;
+typedef	LONG		*_PLONG;
+typedef UCHAR		*_PUCHAR;
+typedef USHORT		*_PUSHORT;
+typedef ULONG		*_PULONG;
+typedef VOID		*_PVOID;
+
+#endif /* CONFIG_ARC64  */
+
+typedef CHAR		*PCHAR;
+typedef SHORT		*PSHORT;
+typedef LARGE_INTEGER	*PLARGE_INTEGER;
+typedef	LONG		*PLONG;
+typedef UCHAR		*PUCHAR;
+typedef USHORT		*PUSHORT;
+typedef ULONG		*PULONG;
+typedef VOID		*PVOID;
+
+#endif /* _ASM_ARC_TYPES_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/asm.h linux/include/asm-mips64/asm.h
--- v2.3.47/linux/include/asm-mips64/asm.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/asm.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,370 @@
+/* $Id: asm.h,v 1.3 2000/01/17 23:32:47 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1999 by Ralf Baechle
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ *
+ * Some useful macros for MIPS assembler code
+ *
+ * Some of the routines below contain useless nops that will be optimized
+ * away by gas in -O mode. These nops are however required to fill delay
+ * slots in noreorder mode.
+ */
+#ifndef	_ASM_ASM_H
+#define	_ASM_ASM_H
+
+#include <asm/sgidefs.h>
+
+/*
+ * PIC specific declarations
+ * Not used for the kernel but here seems to be the right place.
+ */
+#ifdef __PIC__
+#define CPRESTORE(register)                             \
+		.cprestore register
+#define CPADD(register)                                 \
+		.cpadd	register
+#define CPLOAD(register)                                \
+		.cpload	register
+#else
+#define CPRESTORE(register)
+#define CPADD(register)
+#define CPLOAD(register)
+#endif
+
+/*
+ * LEAF - declare leaf routine
+ */
+#define	LEAF(symbol)                                    \
+		.globl	symbol;                         \
+		.align	2;                              \
+		.type	symbol,@function;               \
+		.ent	symbol,0;                       \
+symbol:		.frame	sp,0,ra
+
+/*
+ * NESTED - declare nested routine entry point
+ */
+#define	NESTED(symbol, framesize, rpc)                  \
+		.globl	symbol;                         \
+		.align	2;                              \
+		.type	symbol,@function;               \
+		.ent	symbol,0;                       \
+symbol:		.frame	sp, framesize, rpc
+
+/*
+ * END - mark end of function
+ */
+#define	END(function)                                   \
+		.end	function;		        \
+		.size	function,.-function
+
+/*
+ * EXPORT - export definition of symbol
+ */
+#define	EXPORT(symbol)					\
+		.globl	symbol;                         \
+symbol:
+
+/*
+ * FEXPORT - export definition of a function symbol
+ */
+#define	FEXPORT(symbol)					\
+		.globl	symbol;                         \
+		.type	symbol,@function;		\
+symbol:
+
+/*
+ * ABS - export absolute symbol
+ */
+#define	ABS(symbol,value)                               \
+		.globl	symbol;                         \
+symbol		=	value
+
+#define	PANIC(msg)                                      \
+		.set	push;				\
+		.set	reorder;                        \
+		la	a0,8f;                          \
+		jal	panic;                          \
+9:		b	9b;                             \
+		.set	pop;				\
+		TEXT(msg)
+
+/*
+ * Print formated string
+ */
+#define PRINT(string)                                   \
+		.set	push;				\
+		.set	reorder;                        \
+		la	a0,8f;                          \
+		jal	printk;                         \
+		.set	pop;				\
+		TEXT(string)
+
+/*
+ * Print formated string
+ */
+#define PROM_PRINT(string)                              \
+		.set	push;				\
+		.set	reorder;                        \
+		la	a0,8f;                          \
+		jal	prom_printf;                    \
+		.set	pop;				\
+		TEXT(string)
+
+#define	TEXT(msg)                                       \
+		.data;                                  \
+8:		.asciiz	msg;                            \
+		.previous;
+
+/*
+ * Build text tables
+ */
+#define TTABLE(string)                                  \
+		.text;                                  \
+		.word	1f;                             \
+		.previous;                              \
+		.data;                                  \
+1:		.asciz	string;                         \
+		.previous
+
+/*
+ * MIPS IV pref instruction.
+ * Use with .set noreorder only!
+ *
+ * MIPS IV implementations are free to treat this as a nop.  The R5000
+ * is one of them.  So we should have an option not to use this instruction.
+ */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
+#define PREF(hint,addr)                                 \
+		pref	hint,addr
+#define PREFX(hint,addr)                                \
+		prefx	hint,addr
+#else
+#define PREF
+#define PREFX
+#endif
+
+/*
+ * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
+ */
+#if _MIPS_ISA == _MIPS_ISA_MIPS1
+#define MOVN(rd,rs,rt)                                  \
+		.set	push;				\
+		.set	reorder;			\
+		beqz	rt,9f;                          \
+		move	rd,rs;                          \
+		.set	pop;				\
+9:
+#define MOVZ(rd,rs,rt)                                  \
+		.set	push;				\
+		.set	reorder;			\
+		bnez	rt,9f;                          \
+		move	rd,rt;                          \
+		.set	pop;				\
+9:
+#endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
+#define MOVN(rd,rs,rt)                                  \
+		.set	push;				\
+		.set	noreorder;			\
+		bnezl	rt,9f;                          \
+		move	rd,rs;                          \
+		.set	pop;				\
+9:
+#define MOVZ(rd,rs,rt)                                  \
+		.set	push;				\
+		.set	noreorder;			\
+		beqzl	rt,9f;                          \
+		movz	rd,rs;                          \
+		.set	pop;				\
+9:
+#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
+#define MOVN(rd,rs,rt)                                  \
+		movn	rd,rs,rt
+#define MOVZ(rd,rs,rt)                                  \
+		movz	rd,rs,rt
+#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */
+
+/*
+ * Stack alignment
+ */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+#define ALSZ	7
+#define ALMASK	~7
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+    (_MIPS_ISA == _MIPS_ISA_MIPS5)
+#define ALSZ	15
+#define ALMASK	~15
+#endif
+
+/*
+ * Size of a register
+ */
+#ifdef __mips64
+#define SZREG	8
+#else
+#define SZREG	4
+#endif
+
+/*
+ * Use the following macros in assemblercode to load/store registers,
+ * pointers etc.
+ */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+#define REG_S sw
+#define REG_L lw
+#define PTR_SUBU dsubu
+#define PTR_ADDU daddu
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+    (_MIPS_ISA == _MIPS_ISA_MIPS5)
+#define REG_S sd
+#define REG_L ld
+/* We still live in a 32 bit address space ...  */
+#define PTR_SUBU dsubu
+#define PTR_ADDU daddu
+#endif
+
+/*
+ * How to add/sub/load/store/shift C int variables.
+ */
+#if (_MIPS_SZINT == 32)
+#define INT_ADD	add
+#define INT_ADDI	addi
+#define INT_ADDU	addu
+#define INT_ADDIU	addiu
+#define INT_SUB	add
+#define INT_SUBI	subi
+#define INT_SUBU	subu
+#define INT_SUBIU	subu
+#define INT_L		lw
+#define INT_S		sw
+#endif
+
+#if (_MIPS_SZINT == 64)
+#define INT_ADD	dadd
+#define INT_ADDI	daddi
+#define INT_ADDU	daddu
+#define INT_ADDIU	daddiu
+#define INT_SUB	dadd
+#define INT_SUBI	dsubi
+#define INT_SUBU	dsubu
+#define INT_SUBIU	dsubu
+#define INT_L		ld
+#define INT_S		sd
+#endif
+
+/*
+ * How to add/sub/load/store/shift C long variables.
+ */
+#if (_MIPS_SZLONG == 32)
+#define LONG_ADD	add
+#define LONG_ADDI	addi
+#define LONG_ADDU	addu
+#define LONG_ADDIU	addiu
+#define LONG_SUB	add
+#define LONG_SUBI	subi
+#define LONG_SUBU	subu
+#define LONG_SUBIU	subu
+#define LONG_L		lw
+#define LONG_S		sw
+#define LONG_SLL	sll
+#define LONG_SLLV	sllv
+#define LONG_SRL	srl
+#define LONG_SRLV	srlv
+#define LONG_SRA	sra
+#define LONG_SRAV	srav
+#endif
+
+#if (_MIPS_SZLONG == 64)
+#define LONG_ADD	dadd
+#define LONG_ADDI	daddi
+#define LONG_ADDU	daddu
+#define LONG_ADDIU	daddiu
+#define LONG_SUB	dadd
+#define LONG_SUBI	dsubi
+#define LONG_SUBU	dsubu
+#define LONG_SUBIU	dsubu
+#define LONG_L		ld
+#define LONG_S		sd
+#define LONG_SLL	dsll
+#define LONG_SLLV	dsllv
+#define LONG_SRL	dsrl
+#define LONG_SRLV	dsrlv
+#define LONG_SRA	dsra
+#define LONG_SRAV	dsrav
+#endif
+
+/*
+ * How to add/sub/load/store/shift pointers.
+ */
+#if (_MIPS_SZPTR == 32)
+#define PTR_ADD	add
+#define PTR_ADDI	addi
+#define PTR_ADDU	addu
+#define PTR_ADDIU	addiu
+#define PTR_SUB		add
+#define PTR_SUBI	subi
+#define PTR_SUBU	subu
+#define PTR_SUBIU	subu
+#define PTR_L		lw
+#define PTR_S		sw
+#define PTR_SLL		sll
+#define PTR_SLLV	sllv
+#define PTR_SRL		srl
+#define PTR_SRLV	srlv
+#define PTR_SRA		sra
+#define PTR_SRAV	srav
+
+#define PTR_SCALESHIFT	2
+
+#define PTR		.word
+#define PTRSIZE		4
+#define PTRLOG		2
+#endif
+
+#if (_MIPS_SZPTR == 64)
+#define PTR_ADD	dadd
+#define PTR_ADDI	daddi
+#define PTR_ADDU	daddu
+#define PTR_ADDIU	daddiu
+#define PTR_SUB		dadd
+#define PTR_SUBI	dsubi
+#define PTR_SUBU	dsubu
+#define PTR_SUBIU	dsubu
+#define PTR_L		ld
+#define PTR_S		sd
+#define PTR_SLL		dsll
+#define PTR_SLLV	dsllv
+#define PTR_SRL		dsrl
+#define PTR_SRLV	dsrlv
+#define PTR_SRA		dsra
+#define PTR_SRAV	dsrav
+
+#define PTR_SCALESHIFT	3
+
+#define PTR		.dword
+#define PTRSIZE		8
+#define PTRLOG		3
+#endif
+
+/*
+ * Some cp0 registers were extended to 64bit for MIPS III.
+ */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+#define MFC0	mfc0
+#define MTC0	mtc0
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+    (_MIPS_ISA == _MIPS_ISA_MIPS5)
+#define MFC0	dmfc0
+#define MTC0	dmtc0
+#endif
+
+#endif /* _ASM_ASM_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/asmmacro.h linux/include/asm-mips64/asmmacro.h
--- v2.3.47/linux/include/asm-mips64/asmmacro.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/asmmacro.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,193 @@
+/* $Id: asmmacro.h,v 1.1 1999/12/04 03:59:12 ralf Exp $
+ *
+ * asmmacro.h: Assembler macros to make things easier to read.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_ASMMACRO_H
+#define _ASM_ASMMACRO_H
+
+#include <asm/offset.h>
+
+	.macro	fpu_save_16even thread tmp
+	cfc1	\tmp, fcr31
+	sdc1	$f2,  (THREAD_FPU + 0x010)(\thread)
+	sdc1	$f4,  (THREAD_FPU + 0x020)(\thread)
+	sdc1	$f6,  (THREAD_FPU + 0x030)(\thread)
+	sdc1	$f8,  (THREAD_FPU + 0x040)(\thread)
+	sdc1	$f10, (THREAD_FPU + 0x050)(\thread)
+	sdc1	$f12, (THREAD_FPU + 0x060)(\thread)
+	sdc1	$f14, (THREAD_FPU + 0x070)(\thread)
+	sdc1	$f16, (THREAD_FPU + 0x080)(\thread)
+	sdc1	$f18, (THREAD_FPU + 0x090)(\thread)
+	sdc1	$f20, (THREAD_FPU + 0x0a0)(\thread)
+	sdc1	$f22, (THREAD_FPU + 0x0b0)(\thread)
+	sdc1	$f24, (THREAD_FPU + 0x0c0)(\thread)
+	sdc1	$f26, (THREAD_FPU + 0x0d0)(\thread)
+	sdc1	$f28, (THREAD_FPU + 0x0e0)(\thread)
+	sdc1	$f30, (THREAD_FPU + 0x0f0)(\thread)
+	sw	\tmp, (THREAD_FPU + 0x100)(\thread)
+	.endm
+
+	.macro	fpu_save_16odd thread
+	sdc1	$f1,  (THREAD_FPU + 0x08)(\thread)
+	sdc1	$f3,  (THREAD_FPU + 0x18)(\thread)
+	sdc1	$f5,  (THREAD_FPU + 0x28)(\thread)
+	sdc1	$f7,  (THREAD_FPU + 0x38)(\thread)
+	sdc1	$f9,  (THREAD_FPU + 0x48)(\thread)
+	sdc1	$f11, (THREAD_FPU + 0x58)(\thread)
+	sdc1	$f13, (THREAD_FPU + 0x68)(\thread)
+	sdc1	$f15, (THREAD_FPU + 0x78)(\thread)
+	sdc1	$f17, (THREAD_FPU + 0x88)(\thread)
+	sdc1	$f19, (THREAD_FPU + 0x98)(\thread)
+	sdc1	$f21, (THREAD_FPU + 0xa8)(\thread)
+	sdc1	$f23, (THREAD_FPU + 0xb8)(\thread)
+	sdc1	$f25, (THREAD_FPU + 0xc8)(\thread)
+	sdc1	$f27, (THREAD_FPU + 0xd8)(\thread)
+	sdc1	$f29, (THREAD_FPU + 0xe8)(\thread)
+	sdc1	$f31, (THREAD_FPU + 0xf8)(\thread)
+	.endm
+
+	.macro	fpu_save thread tmp
+	cfc1	\tmp,  fcr31
+	swc1	$f0,  (THREAD_FPU + 0x000)(\thread)
+	swc1	$f1,  (THREAD_FPU + 0x008)(\thread)
+	swc1	$f2,  (THREAD_FPU + 0x010)(\thread)
+	swc1	$f3,  (THREAD_FPU + 0x018)(\thread)
+	swc1	$f4,  (THREAD_FPU + 0x020)(\thread)
+	swc1	$f5,  (THREAD_FPU + 0x028)(\thread)
+	swc1	$f6,  (THREAD_FPU + 0x030)(\thread)
+	swc1	$f7,  (THREAD_FPU + 0x038)(\thread)
+	swc1	$f8,  (THREAD_FPU + 0x040)(\thread)
+	swc1	$f9,  (THREAD_FPU + 0x048)(\thread)
+	swc1	$f10, (THREAD_FPU + 0x050)(\thread)
+	swc1	$f11, (THREAD_FPU + 0x058)(\thread)
+	swc1	$f12, (THREAD_FPU + 0x060)(\thread)
+	swc1	$f13, (THREAD_FPU + 0x068)(\thread)
+	swc1	$f14, (THREAD_FPU + 0x070)(\thread)
+	swc1	$f15, (THREAD_FPU + 0x078)(\thread)
+	swc1	$f16, (THREAD_FPU + 0x080)(\thread)
+	swc1	$f17, (THREAD_FPU + 0x088)(\thread)
+	swc1	$f18, (THREAD_FPU + 0x090)(\thread)
+	swc1	$f19, (THREAD_FPU + 0x098)(\thread)
+	swc1	$f20, (THREAD_FPU + 0x0a0)(\thread)
+	swc1	$f21, (THREAD_FPU + 0x0a8)(\thread)
+	swc1	$f22, (THREAD_FPU + 0x0b0)(\thread)
+	swc1	$f23, (THREAD_FPU + 0x0b8)(\thread)
+	swc1	$f24, (THREAD_FPU + 0x0c0)(\thread)
+	swc1	$f25, (THREAD_FPU + 0x0c8)(\thread)
+	swc1	$f26, (THREAD_FPU + 0x0d0)(\thread)
+	swc1	$f27, (THREAD_FPU + 0x0d8)(\thread)
+	swc1	$f28, (THREAD_FPU + 0x0e0)(\thread)
+	swc1	$f29, (THREAD_FPU + 0x0e8)(\thread)
+	swc1	$f30, (THREAD_FPU + 0x0f0)(\thread)
+	swc1	$f31, (THREAD_FPU + 0x0f8)(\thread)
+	sw	\tmp, (THREAD_FPU + 0x100)(\thread)
+	.endm
+
+	.macro	fpu_restore_16even thread tmp
+	lw	\tmp, (THREAD_FPU + 0x100)(\thread)
+	ldc1	$f2,  (THREAD_FPU + 0x010)(\thread)
+	ldc1	$f4,  (THREAD_FPU + 0x020)(\thread)
+	ldc1	$f6,  (THREAD_FPU + 0x030)(\thread)
+	ldc1	$f8,  (THREAD_FPU + 0x040)(\thread)
+	ldc1	$f10, (THREAD_FPU + 0x050)(\thread)
+	ldc1	$f12, (THREAD_FPU + 0x060)(\thread)
+	ldc1	$f14, (THREAD_FPU + 0x070)(\thread)
+	ldc1	$f16, (THREAD_FPU + 0x080)(\thread)
+	ldc1	$f18, (THREAD_FPU + 0x090)(\thread)
+	ldc1	$f20, (THREAD_FPU + 0x0a0)(\thread)
+	ldc1	$f22, (THREAD_FPU + 0x0b0)(\thread)
+	ldc1	$f24, (THREAD_FPU + 0x0c0)(\thread)
+	ldc1	$f26, (THREAD_FPU + 0x0d0)(\thread)
+	ldc1	$f28, (THREAD_FPU + 0x0e0)(\thread)
+	ldc1	$f30, (THREAD_FPU + 0x0f0)(\thread)
+	ctc1	\tmp,  fcr31
+	.endm
+
+	.macro	fpu_restore_16odd thread
+	ldc1	$f1,  (THREAD_FPU + 0x08)(\thread)
+	ldc1	$f3,  (THREAD_FPU + 0x18)(\thread)
+	ldc1	$f5,  (THREAD_FPU + 0x28)(\thread)
+	ldc1	$f7,  (THREAD_FPU + 0x38)(\thread)
+	ldc1	$f9,  (THREAD_FPU + 0x48)(\thread)
+	ldc1	$f11, (THREAD_FPU + 0x58)(\thread)
+	ldc1	$f13, (THREAD_FPU + 0x68)(\thread)
+	ldc1	$f15, (THREAD_FPU + 0x78)(\thread)
+	ldc1	$f17, (THREAD_FPU + 0x88)(\thread)
+	ldc1	$f19, (THREAD_FPU + 0x98)(\thread)
+	ldc1	$f21, (THREAD_FPU + 0xa8)(\thread)
+	ldc1	$f23, (THREAD_FPU + 0xb8)(\thread)
+	ldc1	$f25, (THREAD_FPU + 0xc8)(\thread)
+	ldc1	$f27, (THREAD_FPU + 0xd8)(\thread)
+	ldc1	$f29, (THREAD_FPU + 0xe8)(\thread)
+	ldc1	$f31, (THREAD_FPU + 0xf8)(\thread)
+	.endm
+
+	.macro	fpu_restore thread tmp
+	lw	\tmp, (THREAD_FPU + 0x100)(\thread)
+	lwc1	$f0,  (THREAD_FPU + 0x000)(\thread)
+	lwc1	$f1,  (THREAD_FPU + 0x008)(\thread)
+	lwc1	$f2,  (THREAD_FPU + 0x010)(\thread)
+	lwc1	$f3,  (THREAD_FPU + 0x018)(\thread)
+	lwc1	$f4,  (THREAD_FPU + 0x020)(\thread)
+	lwc1	$f5,  (THREAD_FPU + 0x028)(\thread)
+	lwc1	$f6,  (THREAD_FPU + 0x030)(\thread)
+	lwc1	$f7,  (THREAD_FPU + 0x038)(\thread)
+	lwc1	$f8,  (THREAD_FPU + 0x040)(\thread)
+	lwc1	$f9,  (THREAD_FPU + 0x048)(\thread)
+	lwc1	$f10, (THREAD_FPU + 0x050)(\thread)
+	lwc1	$f11, (THREAD_FPU + 0x058)(\thread)
+	lwc1	$f12, (THREAD_FPU + 0x060)(\thread)
+	lwc1	$f13, (THREAD_FPU + 0x068)(\thread)
+	lwc1	$f14, (THREAD_FPU + 0x070)(\thread)
+	lwc1	$f15, (THREAD_FPU + 0x078)(\thread)
+	lwc1	$f16, (THREAD_FPU + 0x080)(\thread)
+	lwc1	$f17, (THREAD_FPU + 0x088)(\thread)
+	lwc1	$f18, (THREAD_FPU + 0x090)(\thread)
+	lwc1	$f19, (THREAD_FPU + 0x098)(\thread)
+	lwc1	$f20, (THREAD_FPU + 0x0a0)(\thread)
+	lwc1	$f21, (THREAD_FPU + 0x0a8)(\thread)
+	lwc1	$f22, (THREAD_FPU + 0x0b0)(\thread)
+	lwc1	$f23, (THREAD_FPU + 0x0b8)(\thread)
+	lwc1	$f24, (THREAD_FPU + 0x0c0)(\thread)
+	lwc1	$f25, (THREAD_FPU + 0x0c8)(\thread)
+	lwc1	$f26, (THREAD_FPU + 0x0d0)(\thread)
+	lwc1	$f27, (THREAD_FPU + 0x0d8)(\thread)
+	lwc1	$f28, (THREAD_FPU + 0x0e0)(\thread)
+	lwc1	$f29, (THREAD_FPU + 0x0e8)(\thread)
+	lwc1	$f30, (THREAD_FPU + 0x0f0)(\thread)
+	lwc1	$f31, (THREAD_FPU + 0x0f8)(\thread)
+	ctc1	\tmp,  fcr31
+	.endm
+
+	.macro	cpu_save_nonscratch thread
+	sd	s0, THREAD_REG16(\thread)
+	sd	s1, THREAD_REG17(\thread)
+	sd	s2, THREAD_REG18(\thread)
+	sd	s3, THREAD_REG19(\thread)
+	sd	s4, THREAD_REG20(\thread)
+	sd	s5, THREAD_REG21(\thread)
+	sd	s6, THREAD_REG22(\thread)
+	sd	s7, THREAD_REG23(\thread)
+	sd	sp, THREAD_REG29(\thread)
+	sd	fp, THREAD_REG30(\thread)
+	.endm
+
+	.macro	cpu_restore_nonscratch thread
+	ld	s0, THREAD_REG16(\thread)
+	ld	s1, THREAD_REG17(\thread)
+	ld	s2, THREAD_REG18(\thread)
+	ld	s3, THREAD_REG19(\thread)
+	ld	s4, THREAD_REG20(\thread)
+	ld	s5, THREAD_REG21(\thread)
+	ld	s6, THREAD_REG22(\thread)
+	ld	s7, THREAD_REG23(\thread)
+	ld	sp, THREAD_REG29(\thread)
+	ld	fp, THREAD_REG30(\thread)
+	ld	ra, THREAD_REG31(\thread)
+	.endm
+
+#endif /* !(_ASM_ASMMACRO_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/atomic.h linux/include/asm-mips64/atomic.h
--- v2.3.47/linux/include/asm-mips64/atomic.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/atomic.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,124 @@
+/* $Id: atomic.h,v 1.1 1999/08/18 23:37:50 ralf Exp $
+ *
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ *
+ * But use these as seldom as possible since they are much more slower
+ * than regular operations.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_ATOMIC_H
+#define _ASM_ATOMIC_H
+
+#include <asm/sgidefs.h>
+
+#ifdef __SMP__
+typedef struct { volatile int counter; } atomic_t;
+#else
+typedef struct { int counter; } atomic_t;
+#endif
+
+#ifdef __KERNEL__
+#define ATOMIC_INIT(i)    { (i) }
+
+#define atomic_read(v)	((v)->counter)
+#define atomic_set(v,i)	((v)->counter = (i))
+
+/*
+ * Make sure gcc doesn't try to be clever and move things around
+ * on us. We need to use _exactly_ the address the user gave us,
+ * not some alias that contains the same information.
+ */
+#define __atomic_fool_gcc(x) (*(volatile struct { int a[100]; } *)x)
+
+extern __inline__ void atomic_add(int i, volatile atomic_t * v)
+{
+	unsigned long temp;
+
+	__asm__ __volatile__(
+		"1:\tll\t%0,%1\n\t"
+		"addu\t%0,%2\n\t"
+		"sc\t%0,%1\n\t"
+		"beqz\t%0,1b"
+		:"=&r" (temp),
+		 "=m" (__atomic_fool_gcc(v))
+		:"Ir" (i),
+		 "m" (__atomic_fool_gcc(v)));
+}
+
+extern __inline__ void atomic_sub(int i, volatile atomic_t * v)
+{
+	unsigned long temp;
+
+	__asm__ __volatile__(
+		"1:\tll\t%0,%1\n\t"
+		"subu\t%0,%2\n\t"
+		"sc\t%0,%1\n\t"
+		"beqz\t%0,1b"
+		:"=&r" (temp),
+		 "=m" (__atomic_fool_gcc(v))
+		:"Ir" (i),
+		 "m" (__atomic_fool_gcc(v)));
+}
+
+/*
+ * Same as above, but return the result value
+ */
+extern __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+	unsigned long temp, result;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n"
+		"1:\tll\t%1,%2\n\t"
+		"addu\t%0,%1,%3\n\t"
+		"sc\t%0,%2\n\t"
+		"beqz\t%0,1b\n\t"
+		"addu\t%0,%1,%3\n\t"
+		".set\treorder"
+		:"=&r" (result),
+		 "=&r" (temp),
+		 "=m" (__atomic_fool_gcc(v))
+		:"Ir" (i),
+		 "m" (__atomic_fool_gcc(v)));
+
+	return result;
+}
+
+extern __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+	unsigned long temp, result;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n"
+		"1:\tll\t%1,%2\n\t"
+		"subu\t%0,%1,%3\n\t"
+		"sc\t%0,%2\n\t"
+		"beqz\t%0,1b\n\t"
+		"subu\t%0,%1,%3\n\t"
+		".set\treorder"
+		:"=&r" (result),
+		 "=&r" (temp),
+		 "=m" (__atomic_fool_gcc(v))
+		:"Ir" (i),
+		 "m" (__atomic_fool_gcc(v)));
+
+	return result;
+}
+
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+#define atomic_inc(v) atomic_add(1,(v))
+#define atomic_dec(v) atomic_sub(1,(v))
+#endif /* defined(__KERNEL__) */
+
+#endif /* _ASM_ATOMIC_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/bcache.h linux/include/asm-mips64/bcache.h
--- v2.3.47/linux/include/asm-mips64/bcache.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/bcache.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,62 @@
+/* $Id: bcache.h,v 1.3 2000/01/21 22:34:07 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1997, 1999 by Ralf Baechle
+ * Copyright (c) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_BCACHE_H
+#define _ASM_BCACHE_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_BOARD_SCACHE
+
+/* Some R4000 / R4400 / R4600 / R5000 machines may have chipset implemented
+   caches.  On machines with other CPUs the CPU does the cache thing itself. */
+struct bcache_ops {
+	void (*bc_enable)(void);
+	void (*bc_disable)(void);
+	void (*bc_wback_inv)(unsigned long page, unsigned long size);
+	void (*bc_inv)(unsigned long page, unsigned long size);
+};
+
+extern void indy_sc_init(void);
+extern void sni_pcimt_sc_init(void);
+
+extern struct bcache_ops *bcops;
+
+extern inline void bc_enable(void)
+{
+	bcops->bc_enable();
+}
+
+extern inline void bc_disable(void)
+{
+	bcops->bc_disable();
+}
+
+extern inline void bc_wback_inv(unsigned long page, unsigned long size)
+{
+	bcops->bc_wback_inv(page, size);
+}
+
+extern inline void bc_inv(unsigned long page, unsigned long size)
+{
+	bcops->bc_inv(page, size);
+}
+
+#else /* !defined(CONFIG_BOARD_SCACHE) */
+
+/* Not R4000 / R4400 / R4600 / R5000.  */
+
+#define bc_enable() do { } while (0)
+#define bc_disable() do { } while (0)
+#define bc_wback_inv(page, size) do { } while (0)
+#define bc_inv(page, size) do { } while (0)
+
+#endif /* !defined(CONFIG_BOARD_SCACHE) */
+
+#endif /* _ASM_BCACHE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/bitops.h linux/include/asm-mips64/bitops.h
--- v2.3.47/linux/include/asm-mips64/bitops.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/bitops.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,453 @@
+/* $Id: bitops.h,v 1.4 1999/12/04 03:59:12 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1994 - 1999  Ralf Baechle (ralf@gnu.org)
+ * Copyright (c) 1999  Silicon Graphics, Inc.
+ */
+#ifndef _ASM_BITOPS_H
+#define _ASM_BITOPS_H
+
+#include <linux/types.h>
+#include <linux/byteorder/swab.h>		/* sigh ... */
+
+#ifndef __KERNEL__
+#error "Don't do this, sucker ..."
+#endif
+
+#include <asm/system.h>
+#include <asm/sgidefs.h>
+#include <asm/mipsregs.h>
+
+/*
+ * These functions for MIPS ISA > 1 are interrupt and SMP proof and
+ * interrupt friendly
+ */
+
+extern __inline__ void
+set_bit(unsigned long nr, void *addr)
+{
+	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
+	unsigned long temp;
+
+	__asm__ __volatile__(
+		"1:\tlld\t%0, %1\t\t# set_bit\n\t"
+		"or\t%0, %2\n\t"
+		"scd\t%0, %1\n\t"
+		"beqz\t%0, 1b"
+		:"=&r" (temp), "=m" (*m)
+		:"ir" (1UL << (nr & 0x3f)), "m" (*m));
+}
+
+extern __inline__ void
+clear_bit(unsigned long nr, void *addr)
+{
+	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
+	unsigned long temp;
+
+	__asm__ __volatile__(
+		"1:\tlld\t%0, %1\t\t# clear_bit\n\t"
+		"and\t%0, %2\n\t"
+		"scd\t%0, %1\n\t"
+		"beqz\t%0, 1b\n\t"
+		:"=&r" (temp), "=m" (*m)
+		:"ir" (~(1UL << (nr & 0x3f))), "m" (*m));
+}
+
+extern __inline__ void
+change_bit(unsigned long nr, void *addr)
+{
+	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
+	unsigned long temp;
+
+	__asm__ __volatile__(
+		"1:\tlld\t%0, %1\t\t# change_bit\n\t"
+		"xor\t%0, %2\n\t"
+		"scd\t%0, %1\n\t"
+		"beqz\t%0, 1b"
+		:"=&r" (temp), "=m" (*m)
+		:"ir" (1UL << (nr & 0x3f)), "m" (*m));
+}
+
+extern __inline__ unsigned long
+test_and_set_bit(unsigned long nr, void *addr)
+{
+	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
+	unsigned long temp, res;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\t\t# test_and_set_bit\n"
+		"1:\tlld\t%0, %1\n\t"
+		"or\t%2, %0, %3\n\t"
+		"scd\t%2, %1\n\t"
+		"beqz\t%2, 1b\n\t"
+		" and\t%2, %0, %3\n\t"
+		".set\treorder"
+		:"=&r" (temp), "=m" (*m), "=&r" (res)
+		:"r" (1UL << (nr & 0x3f)), "m" (*m));
+
+	return res != 0;
+}
+
+extern __inline__ unsigned long
+test_and_clear_bit(unsigned long nr, void *addr)
+{
+	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
+	unsigned long temp, res;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\t\t# test_and_clear_bit\n"
+		"1:\tlld\t%0, %1\n\t"
+		"or\t%2, %0, %3\n\t"
+		"xor\t%2, %3\n\t"
+		"scd\t%2, %1\n\t"
+		"beqz\t%2, 1b\n\t"
+		" and\t%2, %0, %3\n\t"
+		".set\treorder"
+		:"=&r" (temp), "=m" (*m), "=&r" (res)
+		:"r" (1UL << (nr & 0x3f)), "m" (*m));
+
+	return res != 0;
+}
+
+extern __inline__ unsigned long
+test_and_change_bit(unsigned long nr, void *addr)
+{
+	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
+	unsigned long temp, res;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\t\t# test_and_change_bit\n"
+		"1:\tlld\t%0, %1\n\t"
+		"xor\t%2, %0, %3\n\t"
+		"scd\t%2, %1\n\t"
+		"beqz\t%2, 1b\n\t"
+		" and\t%2, %0, %3\n\t"
+		".set\treorder"
+		:"=&r" (temp), "=m" (*m), "=&r" (res)
+		:"r" (1UL << (nr & 0x3f)), "m" (*m));
+
+	return res != 0;
+}
+
+extern __inline__ unsigned long
+test_bit(int nr, volatile void * addr)
+{
+	return 1UL & (((const long *) addr)[nr >> 6] >> (nr & 0x3f));
+}
+
+#ifndef __MIPSEB__
+
+/* Little endian versions. */
+
+extern __inline__ int
+find_first_zero_bit (void *addr, unsigned size)
+{
+	unsigned long dummy;
+	int res;
+
+	if (!size)
+		return 0;
+
+	__asm__ (".set\tnoreorder\n\t"
+		".set\tnoat\n"
+		"1:\tsubu\t$1,%6,%0\n\t"
+		"blez\t$1,2f\n\t"
+		"lw\t$1,(%5)\n\t"
+		"addiu\t%5,4\n\t"
+#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \
+    (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
+		"beql\t%1,$1,1b\n\t"
+		"addiu\t%0,32\n\t"
+#else
+		"addiu\t%0,32\n\t"
+		"beq\t%1,$1,1b\n\t"
+		"nop\n\t"
+		"subu\t%0,32\n\t"
+#endif
+#ifdef __MIPSEB__
+#error "Fix this for big endian"
+#endif /* __MIPSEB__ */
+		"li\t%1,1\n"
+		"1:\tand\t%2,$1,%1\n\t"
+		"beqz\t%2,2f\n\t"
+		"sll\t%1,%1,1\n\t"
+		"bnez\t%1,1b\n\t"
+		"add\t%0,%0,1\n\t"
+		".set\tat\n\t"
+		".set\treorder\n"
+		"2:"
+		: "=r" (res),
+		  "=r" (dummy),
+		  "=r" (addr)
+		: "0" ((signed int) 0),
+		  "1" ((unsigned int) 0xffffffff),
+		  "2" (addr),
+		  "r" (size)
+		: "$1");
+
+	return res;
+}
+
+extern __inline__ int
+find_next_zero_bit (void * addr, int size, int offset)
+{
+	unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
+	int set = 0, bit = offset & 31, res;
+	unsigned long dummy;
+	
+	if (bit) {
+		/*
+		 * Look for zero in first byte
+		 */
+#ifdef __MIPSEB__
+#error "Fix this for big endian byte order"
+#endif
+		__asm__(".set\tnoreorder\n\t"
+			".set\tnoat\n"
+			"1:\tand\t$1,%4,%1\n\t"
+			"beqz\t$1,1f\n\t"
+			"sll\t%1,%1,1\n\t"
+			"bnez\t%1,1b\n\t"
+			"addiu\t%0,1\n\t"
+			".set\tat\n\t"
+			".set\treorder\n"
+			"1:"
+			: "=r" (set),
+			  "=r" (dummy)
+			: "0" (0),
+			  "1" (1 << bit),
+			  "r" (*p)
+			: "$1");
+		if (set < (32 - bit))
+			return set + offset;
+		set = 32 - bit;
+		p++;
+	}
+	/*
+	 * No zero yet, search remaining full bytes for a zero
+	 */
+	res = find_first_zero_bit(p, size - 32 * (p - (unsigned int *) addr));
+	return offset + set + res;
+}
+
+#endif /* !(__MIPSEB__) */
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+extern __inline__ unsigned long ffz(unsigned long word)
+{
+	unsigned long k;
+
+	word = ~word;
+	k = 63;
+	if (word & 0x00000000ffffffffUL) { k -= 32; word <<= 32; }
+	if (word & 0x0000ffff00000000UL) { k -= 16; word <<= 16; }
+	if (word & 0x00ff000000000000UL) { k -= 8;  word <<= 8;  }
+	if (word & 0x0f00000000000000UL) { k -= 4;  word <<= 4;  }
+	if (word & 0x3000000000000000UL) { k -= 2;  word <<= 2;  }
+	if (word & 0x4000000000000000UL) { k -= 1; }
+
+	return k;
+}
+
+#ifdef __KERNEL__
+
+/*
+ * ffs: find first bit set. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+
+#define ffs(x) generic_ffs(x)
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x)  generic_hweight8(x)
+
+#endif /* __KERNEL__ */
+
+#ifdef __MIPSEB__
+
+/*
+ * find_next_zero_bit() finds the first zero bit in a bit string of length
+ * 'size' bits, starting the search at bit 'offset'. This is largely based
+ * on Linus's ALPHA routines, which are pretty portable BTW.
+ */
+
+extern __inline__ unsigned long
+find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
+	unsigned long result = offset & ~63UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 63UL;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (64-offset);
+		if (size < 64)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 64;
+		result += 64;
+	}
+	while (size & ~63UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 64;
+		size -= 64;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL << size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+#endif /* (__MIPSEB__) */
+
+#ifdef __KERNEL__
+
+/* Now for the ext2 filesystem bit operations and helper routines. */
+
+#ifdef __MIPSEB__
+
+extern inline int
+ext2_set_bit(int nr,void * addr)
+{
+	int		mask, retval, flags;
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR |= mask;
+	restore_flags(flags);
+	return retval;
+}
+
+extern inline int
+ext2_clear_bit(int nr, void * addr)
+{
+	int		mask, retval, flags;
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR &= ~mask;
+	restore_flags(flags);
+	return retval;
+}
+
+extern inline int
+ext2_test_bit(int nr, const void * addr)
+{
+	int			mask;
+	const unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+extern inline unsigned long
+ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if(offset) {
+		/* We hold the little endian value in tmp, but then the
+		 * shift is illegal. So we could keep a big endian value
+		 * in tmp, like this:
+		 *
+		 * tmp = __swab32(*(p++));
+		 * tmp |= ~0UL >> (32-offset);
+		 *
+		 * but this would decrease preformance, so we change the
+		 * shift:
+		 */
+		tmp = *(p++);
+		tmp |= __swab32(~0UL >> (32-offset));
+		if(size < 32)
+			goto found_first;
+		if(~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while(size & ~31UL) {
+		if(~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if(!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	/* tmp is little endian, so we would have to swab the shift,
+	 * see above. But then we have to swab tmp below for ffz, so
+	 * we might as well do this here.
+	 */
+	return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+	return result + ffz(__swab32(tmp));
+}
+#else /* !(__MIPSEB__) */
+
+/* Native ext2 byte ordering, just collapse using defines. */
+#define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr))
+#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr), (addr))
+#define ext2_test_bit(nr, addr) test_bit((nr), (addr))
+#define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size))
+#define ext2_find_next_zero_bit(addr, size, offset) \
+                find_next_zero_bit((addr), (size), (offset))
+ 
+#endif /* !(__MIPSEB__) */
+
+/*
+ * Bitmap functions for the minix filesystem.
+ * FIXME: These assume that Minix uses the native byte/bitorder.
+ * This limits the Minix filesystem's value for data exchange very much.
+ */
+#define minix_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_BITOPS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/bootinfo.h linux/include/asm-mips64/bootinfo.h
--- v2.3.47/linux/include/asm-mips64/bootinfo.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/bootinfo.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,162 @@
+/* $Id: bootinfo.h,v 1.2 2000/01/17 23:32:47 ralf Exp $
+ *
+ * bootinfo.h -- Definition of the Linux/MIPS boot information structure
+ *
+ * Copyright (C) 1995 - 1999 by Ralf Baechle
+ * Copyright (C) 1995, 1996 by Stoned Elipot and Paul M. Antoine.
+ * Copyright (C) 1999 Ralf Baechle
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_BOOTINFO_H
+#define _ASM_BOOTINFO_H
+
+/*
+ * Values for machgroup
+ */
+#define MACH_GROUP_UNKNOWN      0 /* whatever... */
+#define MACH_GROUP_JAZZ     	1 /* Jazz                                     */
+#define MACH_GROUP_DEC          2 /* Digital Equipment                        */
+#define MACH_GROUP_ARC		3 /* Wreckstation Tyne, rPC44, possibly other */
+#define MACH_GROUP_SNI_RM	4 /* Siemens Nixdorf RM series                */
+#define MACH_GROUP_ACN		5
+#define MACH_GROUP_SGI          6 /* Silicon Graphics workstations and servers */
+#define MACH_GROUP_COBALT       7 /* Cobalt servers		 	      */
+
+#define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", \
+                      "SNI", "ACN", "SGI", "Cobalt" }
+
+/*
+ * Valid machtype values for group unknown (low order halfword of mips_machtype)
+ */
+#define MACH_UNKNOWN		0	/* whatever...			*/
+
+#define GROUP_UNKNOWN_NAMES { "unknown" }
+
+/*
+ * Valid machtype values for group JAZZ
+ */
+#define MACH_ACER_PICA_61	0	/* Acer PICA-61 (PICA1)		*/
+#define MACH_MIPS_MAGNUM_4000	1	/* Mips Magnum 4000 "RC4030"	*/
+#define MACH_OLIVETTI_M700      2	/* Olivetti M700-10 (-15 ??)    */
+
+#define GROUP_JAZZ_NAMES { "Acer PICA 61", "Mips Magnum 4000", "Olivetti M700" }
+
+/*
+ * Valid machtype for group DEC 
+ */
+#define MACH_DSUNKNOWN		0
+#define MACH_DS23100		1	/* DECstation 2100 or 3100	*/
+#define MACH_DS5100		2	/* DECstation 5100		*/
+#define MACH_DS5000_200		3	/* DECstation 5000/200		*/
+#define MACH_DS5000_1XX		4	/* DECstation 5000/120, 125, 133, 150 */
+#define MACH_DS5000_XX		5	/* DECstation 5000/20, 25, 33, 50 */
+#define MACH_DS5000_2X0		6	/* DECstation 5000/240, 260	*/
+#define MACH_DS5400		7	/* DECstation 5400		*/
+#define MACH_DS5500		8	/* DECstation 5500		*/
+#define MACH_DS5800		9	/* DECstation 5800		*/
+
+#define GROUP_DEC_NAMES { "unknown", "DECstation 2100/3100", "DECstation 5100", \
+	"DECstation 5000/200", "DECstation 5000/1xx", "Personal DECstation 5000/xx", \
+	"DECstation 5000/2x0", "DECstation 5400", "DECstation 5500", \
+	"DECstation 5800" }
+
+/*
+ * Valid machtype for group ARC
+ */
+#define MACH_DESKSTATION_RPC44  0	/* Deskstation rPC44 */
+#define MACH_DESKSTATION_TYNE	1	/* Deskstation Tyne */
+
+#define GROUP_ARC_NAMES { "Deskstation rPC44", "Deskstation Tyne" }
+
+/*
+ * Valid machtype for group SNI_RM
+ */
+#define MACH_SNI_RM200_PCI	0	/* RM200/RM300/RM400 PCI series */
+
+#define GROUP_SNI_RM_NAMES { "RM200 PCI" }
+
+/*
+ * Valid machtype for group ACN
+ */
+#define MACH_ACN_MIPS_BOARD	0       /* ACN MIPS single board        */
+
+#define GROUP_ACN_NAMES { "ACN" }
+
+/*
+ * Valid machtype for group SGI
+ */
+#define MACH_SGI_INDY		0	/* R4?K and R5K Indy workstaions */
+#define MACH_SGI_IP27		1	/* Origin 200, Origin 2000, Onyx 2 */
+
+#define GROUP_SGI_NAMES { "Indy", "IP27" }
+
+/*
+ * Valid machtype for group COBALT
+ */
+#define MACH_COBALT_27 		 0	/* Proto "27" hardware */
+
+#define GROUP_COBALT_NAMES { "Microserver 27" }
+
+/*
+ * Valid cputype values
+ */
+#define CPU_UNKNOWN		0
+#define CPU_R2000		1
+#define CPU_R3000		2
+#define CPU_R3000A		3
+#define CPU_R3041		4
+#define CPU_R3051		5
+#define CPU_R3052		6
+#define CPU_R3081		7
+#define CPU_R3081E		8
+#define CPU_R4000PC		9
+#define CPU_R4000SC		10
+#define CPU_R4000MC		11
+#define CPU_R4200		12
+#define CPU_R4400PC		13
+#define CPU_R4400SC		14
+#define CPU_R4400MC		15
+#define CPU_R4600		16
+#define CPU_R6000		17
+#define CPU_R6000A		18
+#define CPU_R8000		19
+#define CPU_R10000		20
+#define CPU_R4300		21
+#define CPU_R4650		22
+#define CPU_R4700		23
+#define CPU_R5000		24
+#define CPU_R5000A		25
+#define CPU_R4640		26
+#define CPU_NEVADA		27	/* RM5230, RM5260 */
+#define CPU_LAST		27
+
+#define CPU_NAMES { "unknown", "R2000", "R3000", "R3000A", "R3041", "R3051", \
+        "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC",         \
+        "R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000",          \
+        "R6000A", "R8000", "R10000", "R4300", "R4650", "R4700", "R5000",     \
+        "R5000A", "R4640", "Nevada" }
+
+#define CL_SIZE      (80)
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/*
+ * Some machine parameters passed by the bootloaders. 
+ */
+
+struct drive_info_struct {
+	char dummy[32];
+};
+
+extern unsigned long mips_memory_upper;
+extern unsigned long mips_cputype;
+extern unsigned long mips_machtype;
+extern unsigned long mips_machgroup;
+extern unsigned long mips_tlb_entries;
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+#endif /* _ASM_BOOTINFO_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/branch.h linux/include/asm-mips64/branch.h
--- v2.3.47/linux/include/asm-mips64/branch.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/branch.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,28 @@
+/* $Id: branch.h,v 1.1 1999/08/21 22:19:17 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Branch and jump emulation.
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ */
+#include <asm/ptrace.h>
+
+extern inline int delay_slot(struct pt_regs *regs)
+{
+	return regs->cp0_cause & CAUSEF_BD;
+}
+
+extern int __compute_return_epc(struct pt_regs *regs);
+
+extern inline int compute_return_epc(struct pt_regs *regs)
+{
+	if (!delay_slot(regs)) {
+		regs->cp0_epc += 4;
+		return 0;
+	}
+
+	return __compute_return_epc(regs);
+}
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/bugs.h linux/include/asm-mips64/bugs.h
--- v2.3.47/linux/include/asm-mips64/bugs.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/bugs.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,39 @@
+/* $Id: bugs.h,v 1.1 1999/08/18 23:37:50 ralf Exp $
+ *
+ *  Copyright (C) 1995 Waldorf Electronics
+ *  Copyright (C) 1997, 1999 Ralf Baechle
+ */
+#include <asm/bootinfo.h>
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+
+static inline void check_wait(void)
+{
+	printk("Checking for 'wait' instruction... ");
+	switch(mips_cputype) {
+	case CPU_R4200: 
+	case CPU_R4300: 
+	case CPU_R4600: 
+	case CPU_R4700: 
+	case CPU_R5000: 
+	case CPU_NEVADA:
+		wait_available = 1;
+		printk(" available.\n");
+		break;
+	default:
+		printk(" unavailable.\n");
+		break;
+	}
+}
+
+static void __init
+check_bugs(void)
+{
+	check_wait();
+}
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/byteorder.h linux/include/asm-mips64/byteorder.h
--- v2.3.47/linux/include/asm-mips64/byteorder.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/byteorder.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,30 @@
+/* $Id: byteorder.h,v 1.1 1999/08/18 23:37:50 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_BYTEORDER_H
+#define _ASM_BYTEORDER_H
+
+#include <asm/types.h>
+
+#ifdef __GNUC__
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#endif
+
+#endif /* __GNUC__ */
+
+#if defined (__MIPSEB__)
+#  include <linux/byteorder/big_endian.h>
+#elif defined (__MIPSEL__)
+#  include <linux/byteorder/little_endian.h>
+#else
+#  error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???"
+#endif
+
+#endif /* _ASM_BYTEORDER_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/cache.h linux/include/asm-mips64/cache.h
--- v2.3.47/linux/include/asm-mips64/cache.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/cache.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,16 @@
+/* $Id: cache.h,v 1.3 2000/02/04 07:40:53 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_CACHE_H
+#define _ASM_CACHE_H
+
+/* bytes per L1 cache line */
+#define L1_CACHE_BYTES	32	/* A guess */
+
+#endif /* _ASM_CACHE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/cachectl.h linux/include/asm-mips64/cachectl.h
--- v2.3.47/linux/include/asm-mips64/cachectl.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/cachectl.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,27 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef	_ASM_CACHECTL
+#define	_ASM_CACHECTL
+
+/*
+ * Options for cacheflush system call
+ */
+#define	ICACHE	(1<<0)		/* flush instruction cache        */
+#define	DCACHE	(1<<1)		/* writeback and flush data cache */
+#define	BCACHE	(ICACHE|DCACHE)	/* flush both caches              */
+
+/*
+ * Caching modes for the cachectl(2) call
+ *
+ * cachctl(2) is currently not supported and returns ENOSYS.
+ */
+#define CACHEABLE	0	/* make pages cacheable */
+#define UNCACHEABLE	1	/* make pages uncacheable */
+
+#endif	/* _ASM_CACHECTL */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/checksum.h linux/include/asm-mips64/checksum.h
--- v2.3.47/linux/include/asm-mips64/checksum.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/checksum.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,258 @@
+/* $Id: checksum.h,v 1.6 2000/02/18 22:06:19 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_CHECKSUM_H
+#define _ASM_CHECKSUM_H
+
+#include <asm/checksum.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * this is a new version of the above that records errors it finds in *errp,
+ * but continues and zeros the rest of the buffer.
+ */
+#define csum_partial_copy_nocheck csum_partial_copy
+
+/*
+ * this is a new version of the above that records errors it finds in *errp,
+ * but continues and zeros the rest of the buffer.
+ */
+unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len,
+                                         unsigned int sum, int *errp);
+
+/*
+ * Copy and checksum to user
+ */
+#define HAVE_CSUM_COPY_USER
+extern inline unsigned int
+csum_and_copy_to_user (const char *src, char *dst,
+                       int len, int sum, int *err_ptr)
+{
+	sum = csum_partial(src, len, sum);
+
+	if (copy_to_user(dst, src, len)) {
+		*err_ptr = -EFAULT;
+		return -1;
+	}
+
+	return sum;
+}
+
+/*
+ * the same as csum_partial, but copies from user space (but on MIPS
+ * we have just one address space, so this is identical to the above)
+ *
+ * this is obsolete and will go away.
+ */
+#define csum_partial_copy_fromuser csum_partial_copy
+unsigned int csum_partial_copy(const char *src, char *dst, int len, unsigned int sum);
+  
+/*
+ *	Fold a partial checksum without adding pseudo headers
+ */
+static inline unsigned short int
+csum_fold(unsigned int sum)
+{
+	__asm__("
+	.set	noat            
+	sll	$1, %0, 16
+	addu	%0, $1
+	sltu	$1, %0, $1
+	srl	%0, %0, 16
+	addu	%0, $1
+	xori	%0, 0xffff
+	.set	at"
+	: "=r" (sum)
+	: "0" (sum)
+	: "$1");
+
+ 	return sum;
+}
+ 
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ *
+ *	By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
+ *	Arnt Gulbrandsen.
+ */
+static inline unsigned short
+ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+	unsigned int sum;
+	unsigned long dummy;
+
+	/*
+	 * This is for 32-bit processors ...  but works just fine for 64-bit
+	 * processors for now ...  XXX
+	 */
+	__asm__ __volatile__("
+	.set	noreorder
+	.set	noat
+	lw	%0, (%1)
+	subu	%2, 4
+	dsll	%2, 2
+
+	lw	%3, 4(%1)
+	daddu	%2, %1
+	addu	%0, %3
+	sltu	$1, %0, %3
+	lw	%3, 8(%1)
+	addu	%0, $1
+	addu	%0, %3
+	sltu	$1, %0, %3
+	lw	%3, 12(%1)
+	addu	%0, $1
+	addu	%0, %3
+	sltu	$1, %0, %3
+	addu	%0, $1
+
+1:	lw	%3, 16(%1)
+	daddiu	%1, 4
+	addu	%0, %3
+	sltu	$1, %0, %3
+	bne	%2, %1, 1b
+	 addu	%0, $1
+
+2:	.set	at
+	.set	reorder"
+	: "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (dummy)
+	: "1" (iph), "2" (ihl)
+	: "$1");
+
+	return csum_fold(sum);
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline unsigned long
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
+                   unsigned short len, unsigned short proto, unsigned int sum)
+{
+    __asm__("
+	.set	noat
+	daddu	%0, %2
+	daddu	%0, %3
+	daddu	%0, %4
+	dsll32	$1, %0, 0
+	daddu	%0, $1		# never results in an overflow
+	dsrl32	%0, %0, 0
+	.set	at"
+	: "=r" (sum)
+	: "0" (sum), "r"(saddr), "r" (daddr),
+#ifdef __MIPSEL__
+	    "r" ((ntohs(len)<<16)+proto*256)
+#else
+	    "r" (((proto)<<16)+len)
+#endif
+	: "$1");
+
+	return sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline unsigned short int
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
+                  unsigned short proto, unsigned int sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+static inline unsigned short
+ip_compute_csum(unsigned char * buff, int len)
+{
+	return csum_fold(csum_partial(buff, len, 0));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+static inline unsigned short int
+csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len,
+                unsigned short proto, unsigned int sum) 
+{
+	__asm__("
+		.set	noreorder
+		.set	noat
+		addu	%0, %5		# proto (long in network byte order)
+		sltu	$1, %0, %5
+		addu	%0, $1
+
+		addu	%0, %6		# csum
+		sltu	$1, %0, %6
+		lw	%1, 0(%2)	# four words source address
+		addu	%0, $1
+		addu	%0, %1
+		sltu	$1, %0, $1
+
+		lw	%1, 4(%2)
+		addu	%0, $1
+		addu	%0, %1
+		sltu	$1, %0, $1
+
+		lw	%1, 8(%2)
+		addu	%0, $1
+		addu	%0, %1
+		sltu	$1, %0, $1
+
+		lw	%1, 12(%2)
+		addu	%0, $1
+		addu	%0, %1
+		sltu	$1, %0, $1
+
+		lw	%1, 0(%3)
+		addu	%0, $1
+		addu	%0, %1
+		sltu	$1, %0, $1
+
+		lw	%1, 4(%3)
+		addu	%0, $1
+		addu	%0, %1
+		sltu	$1, %0, $1
+
+		lw	%1, 8(%3)
+		addu	%0, $1
+		addu	%0, %1
+		sltu	$1, %0, $1
+
+		lw	%1, 12(%3)
+		addu	%0, $1
+		addu	%0, %1
+		sltu	$1, %0, $1
+		.set	noat
+		.set	noreorder"
+		: "=r" (sum), "=r" (proto)
+		: "r" (saddr), "r" (daddr),
+		  "0" (htonl(len)), "1" (htonl(proto)), "r"(sum)
+		: "$1");
+
+	return csum_fold(sum);
+}
+
+#endif /* _ASM_CHECKSUM_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/cpu.h linux/include/asm-mips64/cpu.h
--- v2.3.47/linux/include/asm-mips64/cpu.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/cpu.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,45 @@
+/* $Id: cpu.h,v 1.1 1999/12/04 03:59:12 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * cpu.h: Values of the PRId register used to match up
+ *        various MIPS cpu types.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#ifndef _ASM_CPU_H
+#define _ASM_CPU_H
+
+/*
+ * Assigned values for the product ID register.  In order to detect a
+ * certain CPU type exactly eventually additional registers may need to
+ * be examined.
+ */
+#define PRID_IMP_R2000    0x0100
+#define PRID_IMP_R3000    0x0200
+#define PRID_IMP_R6000    0x0300
+#define PRID_IMP_R4000    0x0400
+#define PRID_IMP_R6000A   0x0600
+#define PRID_IMP_R10000   0x0900
+#define PRID_IMP_R4300    0x0b00
+#define PRID_IMP_R8000    0x1000
+#define PRID_IMP_R4600    0x2000
+#define PRID_IMP_R4700    0x2100
+#define PRID_IMP_R4640    0x2200
+#define PRID_IMP_R4650    0x2200		/* Same as R4640 */
+#define PRID_IMP_R5000    0x2300
+#define PRID_IMP_SONIC    0x2400
+#define PRID_IMP_MAGIC    0x2500
+#define PRID_IMP_RM7000   0x2700
+#define PRID_IMP_NEVADA   0x2800
+
+#define PRID_IMP_UNKNOWN  0xff00
+
+#define PRID_REV_R4400    0x0040
+#define PRID_REV_R3000A   0x0030
+#define PRID_REV_R3000    0x0020
+#define PRID_REV_R2000A   0x0010
+
+#endif /* _ASM_CPU_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/current.h linux/include/asm-mips64/current.h
--- v2.3.47/linux/include/asm-mips64/current.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/current.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,35 @@
+/* $Id: current.h,v 1.4 2000/01/17 23:32:47 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ */
+#ifndef _ASM_CURRENT_H
+#define _ASM_CURRENT_H
+
+#ifdef _LANGUAGE_C
+
+/* MIPS rules... */
+register struct task_struct *current asm("$28");
+
+#endif /* _LANGUAGE_C */
+#ifdef _LANGUAGE_ASSEMBLY
+
+/*
+ * Special variant for use by exception handlers when the stack pointer
+ * is not loaded.
+ */
+#define _GET_CURRENT(reg)			\
+	lui	reg, %hi(kernelsp);		\
+	.set	push;				\
+	.set	noreorder;			\
+	ld	reg, %lo(kernelsp)(reg);	\
+	.set	pop;				\
+	ori	reg, 0x3fff;			\
+	xori	reg, 0x3fff
+
+#endif
+
+#endif /* _ASM_CURRENT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/delay.h linux/include/asm-mips64/delay.h
--- v2.3.47/linux/include/asm-mips64/delay.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/delay.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,54 @@
+/* $Id: delay.h,v 1.1 1999/08/18 23:37:50 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 by Waldorf Electronics
+ * Copyright (C) 1995 - 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_DELAY_H
+#define _ASM_DELAY_H
+
+extern __inline__ void
+__delay(unsigned long loops)
+{
+	__asm__ __volatile__ (
+		".set\tnoreorder\n"
+		"1:\tbnez\t%0,1b\n\t"
+		"dsubu\t%0,1\n\t"
+		".set\treorder"
+		:"=r" (loops)
+		:"0" (loops));
+}
+
+/*
+ * Division by multiplication: you don't have to worry about
+ * loss of precision.
+ *
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+extern __inline__ void __udelay(unsigned long usecs, unsigned long lps)
+{
+	usecs *= 0x000010c6f7a0b5edUL;		/* 2**64 / 1000000 */
+	__asm__("dmultu\t%0,%2\n\t"
+		"mfhi\t%0"
+		:"=r" (usecs)
+		:"0" (usecs),"r" (lps));
+	__delay(usecs);
+}
+
+#ifdef __SMP__
+#define __udelay_val cpu_data[smp_processor_id()].udelay_val
+#else
+#define __udelay_val loops_per_sec
+#endif
+
+#define udelay(usecs) __udelay((usecs),__udelay_val)
+
+#endif /* _ASM_DELAY_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/div64.h linux/include/asm-mips64/div64.h
--- v2.3.47/linux/include/asm-mips64/div64.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/div64.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,20 @@
+/* $Id: div64.h,v 1.1 2000/01/29 01:42:28 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_DIV64_H
+#define _ASM_DIV64_H
+
+/*
+ * Hey, we're already 64-bit, no
+ * need to play games..
+ */
+#define do_div(n,base) ({ \
+	int __res; \
+	__res = ((unsigned long) n) % (unsigned) base; \
+	n = ((unsigned long) n) / (unsigned) base; \
+	__res; })
+
+#endif /* _ASM_DIV64_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/dma.h linux/include/asm-mips64/dma.h
--- v2.3.47/linux/include/asm-mips64/dma.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/dma.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,299 @@
+/* $Id: dma.h,v 1.4 2000/01/29 01:42:28 ralf Exp $
+ *
+ * linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ * Written by Hennus Bergman, 1992.
+ * High DMA channel support & info by Hannu Savolainen
+ * and John Boyd, Nov. 1992.
+ *
+ * NOTE: all this is true *only* for ISA/EISA expansions on Mips boards
+ * and can only be used for expansion cards. Onboard DMA controllers, such
+ * as the R4030 on Jazz boards behave totally different!
+ */
+
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H
+
+#include <linux/config.h>
+#include <asm/io.h>			/* need byte IO */
+#include <linux/spinlock.h>		/* And spinlocks */
+#include <linux/delay.h>
+#include <asm/system.h>
+
+
+#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
+#define dma_outb	outb_p
+#else
+#define dma_outb	outb
+#endif
+
+#define dma_inb		inb
+
+/*
+ * NOTES about DMA transfers:
+ *
+ *  controller 1: channels 0-3, byte operations, ports 00-1F
+ *  controller 2: channels 4-7, word operations, ports C0-DF
+ *
+ *  - ALL registers are 8 bits only, regardless of transfer size
+ *  - channel 4 is not used - cascades 1 into 2.
+ *  - channels 0-3 are byte - addresses/counts are for physical bytes
+ *  - channels 5-7 are word - addresses/counts are for physical words
+ *  - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
+ *  - transfer count loaded to registers is 1 less than actual count
+ *  - controller 2 offsets are all even (2x offsets for controller 1)
+ *  - page registers for 5-7 don't use data bit 0, represent 128K pages
+ *  - page registers for 0-3 use bit 0, represent 64K pages
+ *
+ * DMA transfers are limited to the lower 16MB of _physical_ memory.  
+ * Note that addresses loaded into registers must be _physical_ addresses,
+ * not logical addresses (which may differ if paging is active).
+ *
+ *  Address mapping for channels 0-3:
+ *
+ *   A23 ... A16 A15 ... A8  A7 ... A0    (Physical addresses)
+ *    |  ...  |   |  ... |   |  ... |
+ *    |  ...  |   |  ... |   |  ... |
+ *    |  ...  |   |  ... |   |  ... |
+ *   P7  ...  P0  A7 ... A0  A7 ... A0   
+ * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
+ *
+ *  Address mapping for channels 5-7:
+ *
+ *   A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0    (Physical addresses)
+ *    |  ...  |   \   \   ... \  \  \  ... \  \
+ *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
+ *    |  ...  |     \   \   ... \  \  \  ... \
+ *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0   
+ * |      Page      |  Addr MSB   |  Addr LSB  |   (DMA registers)
+ *
+ * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
+ * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
+ * the hardware level, so odd-byte transfers aren't possible).
+ *
+ * Transfer count (_not # bytes_) is limited to 64K, represented as actual
+ * count - 1 : 64K => 0xFFFF, 1 => 0x0000.  Thus, count is always 1 or more,
+ * and up to 128K bytes may be transferred on channels 5-7 in one operation. 
+ *
+ */
+
+#define MAX_DMA_CHANNELS	8
+
+/*
+ * The maximum address in KSEG0 that we can perform a DMA transfer to on this
+ * platform.  This describes only the PC style part of the DMA logic like on
+ * Deskstations or Acer PICA but not the much more versatile DMA logic used
+ * for the local devices on Acer PICA or Magnums.
+ */
+#define MAX_DMA_ADDRESS		(PAGE_OFFSET + 0x01000000)
+
+/* 8237 DMA controllers */
+#define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
+#define IO_DMA2_BASE	0xC0	/* 16 bit master DMA, ch 4(=slave input)..7 */
+
+/* DMA controller registers */
+#define DMA1_CMD_REG		0x08	/* command register (w) */
+#define DMA1_STAT_REG		0x08	/* status register (r) */
+#define DMA1_REQ_REG            0x09    /* request register (w) */
+#define DMA1_MASK_REG		0x0A	/* single-channel mask (w) */
+#define DMA1_MODE_REG		0x0B	/* mode register (w) */
+#define DMA1_CLEAR_FF_REG	0x0C	/* clear pointer flip-flop (w) */
+#define DMA1_TEMP_REG           0x0D    /* Temporary Register (r) */
+#define DMA1_RESET_REG		0x0D	/* Master Clear (w) */
+#define DMA1_CLR_MASK_REG       0x0E    /* Clear Mask */
+#define DMA1_MASK_ALL_REG       0x0F    /* all-channels mask (w) */
+
+#define DMA2_CMD_REG		0xD0	/* command register (w) */
+#define DMA2_STAT_REG		0xD0	/* status register (r) */
+#define DMA2_REQ_REG            0xD2    /* request register (w) */
+#define DMA2_MASK_REG		0xD4	/* single-channel mask (w) */
+#define DMA2_MODE_REG		0xD6	/* mode register (w) */
+#define DMA2_CLEAR_FF_REG	0xD8	/* clear pointer flip-flop (w) */
+#define DMA2_TEMP_REG           0xDA    /* Temporary Register (r) */
+#define DMA2_RESET_REG		0xDA	/* Master Clear (w) */
+#define DMA2_CLR_MASK_REG       0xDC    /* Clear Mask */
+#define DMA2_MASK_ALL_REG       0xDE    /* all-channels mask (w) */
+
+#define DMA_ADDR_0              0x00    /* DMA address registers */
+#define DMA_ADDR_1              0x02
+#define DMA_ADDR_2              0x04
+#define DMA_ADDR_3              0x06
+#define DMA_ADDR_4              0xC0
+#define DMA_ADDR_5              0xC4
+#define DMA_ADDR_6              0xC8
+#define DMA_ADDR_7              0xCC
+
+#define DMA_CNT_0               0x01    /* DMA count registers */
+#define DMA_CNT_1               0x03
+#define DMA_CNT_2               0x05
+#define DMA_CNT_3               0x07
+#define DMA_CNT_4               0xC2
+#define DMA_CNT_5               0xC6
+#define DMA_CNT_6               0xCA
+#define DMA_CNT_7               0xCE
+
+#define DMA_PAGE_0              0x87    /* DMA page registers */
+#define DMA_PAGE_1              0x83
+#define DMA_PAGE_2              0x81
+#define DMA_PAGE_3              0x82
+#define DMA_PAGE_5              0x8B
+#define DMA_PAGE_6              0x89
+#define DMA_PAGE_7              0x8A
+
+#define DMA_MODE_READ	0x44	/* I/O to memory, no autoinit, increment, single mode */
+#define DMA_MODE_WRITE	0x48	/* memory to I/O, no autoinit, increment, single mode */
+#define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
+
+
+extern spinlock_t  dma_spin_lock;
+
+static __inline__ unsigned long claim_dma_lock(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&dma_spin_lock, flags);
+	return flags;
+}
+
+static __inline__ void release_dma_lock(unsigned long flags)
+{
+	spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+	if (dmanr<=3)
+		dma_outb(dmanr,  DMA1_MASK_REG);
+	else
+		dma_outb(dmanr & 3,  DMA2_MASK_REG);
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+	if (dmanr<=3)
+		dma_outb(dmanr | 4,  DMA1_MASK_REG);
+	else
+		dma_outb((dmanr & 3) | 4,  DMA2_MASK_REG);
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while holding the DMA lock ! ---
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+	if (dmanr<=3)
+		dma_outb(0,  DMA1_CLEAR_FF_REG);
+	else
+		dma_outb(0,  DMA2_CLEAR_FF_REG);
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+	if (dmanr<=3)
+		dma_outb(mode | dmanr,  DMA1_MODE_REG);
+	else
+		dma_outb(mode | (dmanr&3),  DMA2_MODE_REG);
+}
+
+/* Set only the page register bits of the transfer address.
+ * This is used for successive transfers when we know the contents of
+ * the lower 16 bits of the DMA current address register, but a 64k boundary
+ * may have been crossed.
+ */
+static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
+{
+	switch(dmanr) {
+		case 0:
+			dma_outb(pagenr, DMA_PAGE_0);
+			break;
+		case 1:
+			dma_outb(pagenr, DMA_PAGE_1);
+			break;
+		case 2:
+			dma_outb(pagenr, DMA_PAGE_2);
+			break;
+		case 3:
+			dma_outb(pagenr, DMA_PAGE_3);
+			break;
+		case 5:
+			dma_outb(pagenr & 0xfe, DMA_PAGE_5);
+			break;
+		case 6:
+			dma_outb(pagenr & 0xfe, DMA_PAGE_6);
+			break;
+		case 7:
+			dma_outb(pagenr & 0xfe, DMA_PAGE_7);
+			break;
+	}
+}
+
+
+/* Set transfer address & page bits for specific DMA channel.
+ * Assumes dma flipflop is clear.
+ */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+	set_dma_page(dmanr, a>>16);
+	if (dmanr <= 3)  {
+	    dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+            dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+	}  else  {
+	    dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+	    dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+	}
+}
+
+
+/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
+ * a specific DMA channel.
+ * You must ensure the parameters are valid.
+ * NOTE: from a manual: "the number of transfers is one more
+ * than the initial word count"! This is taken into account.
+ * Assumes dma flip-flop is clear.
+ * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+        count--;
+	if (dmanr <= 3)  {
+	    dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+	    dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+        } else {
+	    dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+	    dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+        }
+}
+
+
+/* Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * If called before the channel has been used, it may return 1.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ *
+ * Assumes DMA flip-flop is clear.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+	unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
+					 : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
+
+	/* using short to get 16-bit wrap around */
+	unsigned short count;
+
+	count = 1 + dma_inb(io_port);
+	count += dma_inb(io_port) << 8;
+	
+	return (dmanr<=3)? count : (count<<1);
+}
+
+
+/* These are in kernel/dma.c: */
+extern int request_dma(unsigned int dmanr, const char * device_id);	/* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr);	/* release it again */
+
+#endif /* _ASM_DMA_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/ds1286.h linux/include/asm-mips64/ds1286.h
--- v2.3.47/linux/include/asm-mips64/ds1286.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/ds1286.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,71 @@
+/* $Id: ds1286.h,v 1.1 1999/08/19 22:56:34 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * mc146818rtc.h - register definitions for the Real-Time-Clock / CMOS RAM
+ * Copyright Torsten Duwe <duwe@informatik.uni-erlangen.de> 1993
+ * derived from Data Sheet, Copyright Motorola 1984 (!).
+ * It was written to be part of the Linux operating system.
+ *
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ */
+#ifndef _ASM_DS1286_h
+#define _ASM_DS1286_h
+
+#include <asm/mc146818rtc.h>
+
+/**********************************************************************
+ * register summary
+ **********************************************************************/
+#define RTC_HUNDREDTH_SECOND	0
+#define RTC_SECONDS		1
+#define RTC_MINUTES		2
+#define RTC_MINUTES_ALARM	3
+#define RTC_HOURS		4
+#define RTC_HOURS_ALARM		5
+#define RTC_DAY			6
+#define RTC_DAY_ALARM		7
+#define RTC_DATE		8
+#define RTC_MONTH		9
+#define RTC_YEAR		10
+#define RTC_CMD			11
+#define RTC_WHSEC		12
+#define RTC_WSEC		13
+#define RTC_UNUSED		14
+
+/* RTC_*_alarm is always true if 2 MSBs are set */
+# define RTC_ALARM_DONT_CARE 	0xC0
+
+
+/*
+ * Bits in the month register
+ */
+#define RTC_EOSC		0x80
+#define RTC_ESQW		0x40
+
+/*
+ * Bits in the Command register
+ */
+#define RTC_TDF			0x01
+#define RTC_WAF			0x02
+#define RTC_TDM			0x04
+#define RTC_WAM			0x08
+#define RTC_PU_LVL		0x10
+#define RTC_IBH_LO		0x20
+#define RTC_IPSW		0x40
+#define RTC_TE			0x80
+
+/*
+ * Conversion between binary and BCD.
+ */
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+#endif /* _ASM_DS1286_h */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/elf.h linux/include/asm-mips64/elf.h
--- v2.3.47/linux/include/asm-mips64/elf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/elf.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,100 @@
+/* $Id: elf.h,v 1.4 2000/02/24 00:13:20 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_ELF_H
+#define _ASM_ELF_H
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+#ifndef ELF_ARCH
+/* ELF register definitions */
+#define ELF_NGREG	45
+#define ELF_NFPREG	33
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x) == EM_MIPS || (x) == EM_MIPS_RS4_BE)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS64
+#ifdef __MIPSEB__
+#define ELF_DATA	ELFDATA2MSB
+#elif __MIPSEL__
+#define ELF_DATA	ELFDATA2LSB
+#endif
+#define ELF_ARCH	EM_MIPS
+#endif /* !defined(ELF_ARCH) */
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	4096
+
+#define ELF_CORE_COPY_REGS(_dest,_regs)				\
+	memcpy((char *) &_dest, (char *) _regs,			\
+	       sizeof(struct pt_regs));
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  This could be done in userspace,
+   but it's not easy, and we've already done it here.  */
+
+#define ELF_HWCAP       (0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.
+
+   For the moment, we have only optimizations for the Intel generations,
+   but that could change... */
+
+#define ELF_PLATFORM  (NULL)
+
+/*
+ * See comments in asm-alpha/elf.h, this is the same thing
+ * on the MIPS.
+ */
+#define ELF_PLAT_INIT(_r)	do { \
+	_r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0;	\
+	_r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0;	\
+	_r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0;	\
+	_r->regs[13] = _r->regs[14] = _r->regs[15] = _r->regs[16] = 0;	\
+	_r->regs[17] = _r->regs[18] = _r->regs[19] = _r->regs[20] = 0;	\
+	_r->regs[21] = _r->regs[22] = _r->regs[23] = _r->regs[24] = 0;	\
+	_r->regs[25] = _r->regs[26] = _r->regs[27] = _r->regs[28] = 0;	\
+	_r->regs[30] = _r->regs[31] = 0;				\
+} while (0)
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#ifndef ELF_ET_DYN_BASE
+#define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
+#endif
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2)			\
+do {	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)	\
+		current->thread.mflags |= MF_32BIT;	\
+	else						\
+		current->thread.mflags &= ~MF_32BIT;	\
+	if (ibcs2)					\
+		current->personality = PER_SVR4;	\
+	else if (current->personality != PER_LINUX32)	\
+		current->personality = PER_LINUX;	\
+} while (0)
+#endif
+
+#endif /* _ASM_ELF_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/errno.h linux/include/asm-mips64/errno.h
--- v2.3.47/linux/include/asm-mips64/errno.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/errno.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,155 @@
+/* $Id: errno.h,v 1.2 1999/09/28 22:27:19 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 by Ralf Baechle
+ */
+#ifndef _ASM_ERRNO_H
+#define _ASM_ERRNO_H
+
+/*
+ * These error numbers are intended to be MIPS ABI compatible
+ */
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	ENOMSG		35	/* No message of desired type */
+#define	EIDRM		36	/* Identifier removed */
+#define	ECHRNG		37	/* Channel number out of range */
+#define	EL2NSYNC	38	/* Level 2 not synchronized */
+#define	EL3HLT		39	/* Level 3 halted */
+#define	EL3RST		40	/* Level 3 reset */
+#define	ELNRNG		41	/* Link number out of range */
+#define	EUNATCH		42	/* Protocol driver not attached */
+#define	ENOCSI		43	/* No CSI structure available */
+#define	EL2HLT		44	/* Level 2 halted */
+#define	EDEADLK		45	/* Resource deadlock would occur */
+#define	ENOLCK		46	/* No record locks available */
+#define	EBADE		50	/* Invalid exchange */
+#define	EBADR		51	/* Invalid request descriptor */
+#define	EXFULL		52	/* Exchange full */
+#define	ENOANO		53	/* No anode */
+#define	EBADRQC		54	/* Invalid request code */
+#define	EBADSLT		55	/* Invalid slot */
+#define	EDEADLOCK	56	/* File locking deadlock error */
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EMULTIHOP	74	/* Multihop attempted */
+#define	EBADMSG		77	/* Not a data message */
+#define	ENAMETOOLONG	78	/* File name too long */
+#define	EOVERFLOW	79	/* Value too large for defined data type */
+#define	ENOTUNIQ	80	/* Name not unique on network */
+#define	EBADFD		81	/* File descriptor in bad state */
+#define	EREMCHG		82	/* Remote address changed */
+#define	ELIBACC		83	/* Can not access a needed shared library */
+#define	ELIBBAD		84	/* Accessing a corrupted shared library */
+#define	ELIBSCN		85	/* .lib section in a.out corrupted */
+#define	ELIBMAX		86	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	87	/* Cannot exec a shared library directly */
+#define	EILSEQ		88	/* Illegal byte sequence */
+#define	ENOSYS		89	/* Function not implemented */
+#define	ELOOP		90	/* Too many symbolic links encountered */
+#define	ERESTART	91	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	92	/* Streams pipe error */
+#define	ENOTEMPTY	93	/* Directory not empty */
+#define	EUSERS		94	/* Too many users */
+#define	ENOTSOCK	95	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	96	/* Destination address required */
+#define	EMSGSIZE	97	/* Message too long */
+#define	EPROTOTYPE	98	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	99	/* Protocol not available */
+#define	EPROTONOSUPPORT	120	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	121	/* Socket type not supported */
+#define	EOPNOTSUPP	122	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	123	/* Protocol family not supported */
+#define	EAFNOSUPPORT	124	/* Address family not supported by protocol */
+#define	EADDRINUSE	125	/* Address already in use */
+#define	EADDRNOTAVAIL	126	/* Cannot assign requested address */
+#define	ENETDOWN	127	/* Network is down */
+#define	ENETUNREACH	128	/* Network is unreachable */
+#define	ENETRESET	129	/* Network dropped connection because of reset */
+#define	ECONNABORTED	130	/* Software caused connection abort */
+#define	ECONNRESET	131	/* Connection reset by peer */
+#define	ENOBUFS		132	/* No buffer space available */
+#define	EISCONN		133	/* Transport endpoint is already connected */
+#define	ENOTCONN	134	/* Transport endpoint is not connected */
+#define	EUCLEAN		135	/* Structure needs cleaning */
+#define	ENOTNAM		137	/* Not a XENIX named type file */
+#define	ENAVAIL		138	/* No XENIX semaphores available */
+#define	EISNAM		139	/* Is a named type file */
+#define	EREMOTEIO	140	/* Remote I/O error */
+#define EINIT		141	/* Reserved */
+#define EREMDEV		142	/* Error 142 */
+#define	ESHUTDOWN	143	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	144	/* Too many references: cannot splice */
+#define	ETIMEDOUT	145	/* Connection timed out */
+#define	ECONNREFUSED	146	/* Connection refused */
+#define	EHOSTDOWN	147	/* Host is down */
+#define	EHOSTUNREACH	148	/* No route to host */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	EALREADY	149	/* Operation already in progress */
+#define	EINPROGRESS	150	/* Operation now in progress */
+#define	ESTALE		151	/* Stale NFS file handle */
+#define ECANCELED	158	/* AIO operation canceled */
+
+/*
+ * These error are Linux extensions.
+ */
+#define ENOMEDIUM	159	/* No medium found */
+#define EMEDIUMTYPE	160	/* Wrong medium type */
+
+#define EDQUOT		1133	/* Quota exceeded */
+
+#ifdef __KERNEL__
+
+/* The biggest error number defined here or in <linux/errno.h>. */
+#define EMAXERRNO	1133
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_ERRNO_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/fcntl.h linux/include/asm-mips64/fcntl.h
--- v2.3.47/linux/include/asm-mips64/fcntl.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/fcntl.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,76 @@
+/* $Id: fcntl.h,v 1.1 1999/08/18 23:37:51 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_FCNTL_H
+#define _ASM_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	0x0003
+#define O_RDONLY	0x0000
+#define O_WRONLY	0x0001
+#define O_RDWR		0x0002
+#define O_APPEND	0x0008
+#define O_SYNC		0x0010
+#define O_NONBLOCK	0x0080
+#define O_CREAT         0x0100	/* not fcntl */
+#define O_TRUNC		0x0200	/* not fcntl */
+#define O_EXCL		0x0400	/* not fcntl */
+#define O_NOCTTY	0x0800	/* not fcntl */
+#define FASYNC		0x1000	/* fcntl, for BSD compatibility */
+#define O_LARGEFILE	0x2000	/* allow large file opens - currently ignored */
+#define O_DIRECT	0x8000	/* direct disk access hint - currently ignored */
+#define O_DIRECTORY	0x10000	/* must be a directory */
+#define O_NOFOLLOW	0x20000	/* don't follow links */
+
+#define O_NDELAY	O_NONBLOCK
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get f_flags */
+#define F_SETFD		2	/* set f_flags */
+#define F_GETFL		3	/* more flags (cloexec) */
+#define F_SETFL		4
+#define F_GETLK		14
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	24	/*  for sockets. */
+#define F_GETOWN	23	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent		XXXXXXXXXXXXXXXXXX
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+typedef struct flock {
+	short l_type;
+	short l_whence;
+	__kernel_off_t l_start;
+	__kernel_off_t l_len;
+	long  l_sysid;			/* XXXXXXXXXXXXXXXXXXXXXXXXX */
+	__kernel_pid_t l_pid;
+	long  pad[4];			/* ZZZZZZZZZZZZZZZZZZZZZZZZZZ */
+} flock_t;
+
+#endif /* _ASM_FCNTL_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/floppy.h linux/include/asm-mips64/floppy.h
--- v2.3.47/linux/include/asm-mips64/floppy.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/floppy.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,102 @@
+/* $Id: floppy.h,v 1.2 1999/08/21 22:19:17 ralf Exp $
+ *
+ * Architecture specific parts of the Floppy driver
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 Ralf Baechle
+ */
+#ifndef _ASM_FLOPPY_H
+#define _ASM_FLOPPY_H
+
+#include <asm/bootinfo.h>
+
+struct fd_ops {
+	unsigned char (*fd_inb)(unsigned int port);
+	void (*fd_outb)(unsigned char value, unsigned int port);
+
+	/*
+	 * How to access the floppy DMA functions.
+	 */
+	void (*fd_enable_dma)(int channel);
+	void (*fd_disable_dma)(int channel);
+	int (*fd_request_dma)(int channel);
+	void (*fd_free_dma)(int channel);
+	void (*fd_clear_dma_ff)(int channel);
+	void (*fd_set_dma_mode)(int channel, char mode);
+	void (*fd_set_dma_addr)(int channel, unsigned int a);
+	void (*fd_set_dma_count)(int channel, unsigned int count);
+	int (*fd_get_dma_residue)(int channel);
+	void (*fd_enable_irq)(int irq);
+	void (*fd_disable_irq)(int irq);
+	unsigned long (*fd_getfdaddr1)(void);
+	unsigned long (*fd_dma_mem_alloc)(unsigned long size);
+	void (*fd_dma_mem_free)(unsigned long addr, unsigned long size);
+	unsigned long (*fd_drive_type)(unsigned long);
+};
+
+extern struct fd_ops *fd_ops;
+
+#define fd_inb(port)			fd_ops->fd_inb(port)
+#define fd_outb(value,port)		fd_ops->fd_outb(value,port)
+
+#define fd_enable_dma(channel)		fd_ops->fd_enable_dma(channel)
+#define fd_disable_dma(channel)		fd_ops->fd_disable_dma(channel)
+#define fd_request_dma(channel)		fd_ops->fd_request_dma(channel)
+#define fd_free_dma(channel)		fd_ops->fd_free_dma(channel)
+#define fd_clear_dma_ff(channel)	fd_ops->fd_clear_dma_ff(channel)
+#define fd_set_dma_mode(channel, mode)	fd_ops->fd_set_dma_mode(channel, mode)
+#define fd_set_dma_addr(channel, addr)	fd_ops->fd_set_dma_addr(channel, \
+					         virt_to_bus(addr))
+#define fd_set_dma_count(channel,count)	fd_ops->fd_set_dma_count(channel,count)
+#define fd_get_dma_residue(channel)	fd_ops->fd_get_dma_residue(channel)
+
+#define fd_enable_irq(irq)		fd_ops->fd_enable_irq(irq)
+#define fd_disable_irq(irq)		fd_ops->fd_disable_irq(irq)
+#define fd_request_irq(irq)		request_irq(irq, floppy_interrupt, \
+						    SA_INTERRUPT \
+					            | SA_SAMPLE_RANDOM, \
+				                    "floppy", NULL)
+#define fd_free_irq(irq)		free_irq(irq, NULL);
+#define fd_dma_mem_alloc(size) fd_ops->fd_dma_mem_alloc(size)
+#define fd_dma_mem_free(mem,size) fd_ops->fd_dma_mem_free(mem,size)
+#define fd_drive_type(n)		fd_ops->fd_drive_type(n)
+
+#define MAX_BUFFER_SECTORS 24
+
+
+/*
+ * And on Mips's the CMOS info fails also ...
+ *
+ * FIXME: This information should come from the ARC configuration tree
+ *        or whereever a particular machine has stored this ...
+ */
+#define FLOPPY0_TYPE 			fd_drive_type(0)
+#define FLOPPY1_TYPE			fd_drive_type(1)
+
+#define FDC1			fd_ops->fd_getfdaddr1();
+static int __attribute__((__unused__)) FDC2=-1;
+
+#define N_FDC 1			/* do you *really* want a second controller? */
+#define N_DRIVE 8
+
+#define FLOPPY_MOTOR_MASK 0xf0
+
+/*
+ * The DMA channel used by the floppy controller cannot access data at
+ * addresses >= 16MB
+ *
+ * Went back to the 1MB limit, as some people had problems with the floppy
+ * driver otherwise. It doesn't matter much for performance anyway, as most
+ * floppy accesses go through the track buffer.
+ *
+ * On MIPSes using vdma, this actually means that *all* transfers go thru
+ * the * track buffer since 0x1000000 is always smaller than KSEG0/1.
+ * Actually this needs to be a bit more complicated since the so much different
+ * hardware available with MIPS CPUs ...
+ */
+#define CROSS_64KB(a,s) ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)
+
+#endif /* _ASM_FLOPPY_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/fpregdef.h linux/include/asm-mips64/fpregdef.h
--- v2.3.47/linux/include/asm-mips64/fpregdef.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/fpregdef.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,50 @@
+/*
+ * Definitions for the FPU register names
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999 Ralf Baechle
+ * Copyright (C) 1985 MIPS Computer Systems, Inc.
+ * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_FPREGDEF_H
+#define _ASM_FPREGDEF_H
+
+#define fv0	$f0	/* return value */
+#define fv1	$f2
+#define fa0	$f12	/* argument registers */
+#define fa1	$f13
+#define fa2	$f14
+#define fa3	$f15
+#define fa4	$f16
+#define fa5	$f17
+#define fa6	$f18
+#define fa7	$f19
+#define ft0	$f4	/* caller saved */
+#define ft1	$f5
+#define ft2	$f6
+#define ft3	$f7
+#define ft4	$f8
+#define ft5	$f9
+#define ft6	$f10
+#define ft7	$f11
+#define ft8	$f20
+#define ft9	$f21
+#define ft10	$f22
+#define ft11	$f23
+#define ft12	$f1
+#define ft13	$f3
+#define fs0	$f24	/* callee saved */
+#define fs1	$f25
+#define fs2	$f26
+#define fs3	$f27
+#define fs4	$f28
+#define fs5	$f29
+#define fs6	$f30
+#define fs7	$f31
+
+#define fcr31	$31
+
+#endif /* _ASM_FPREGDEF_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/gfx.h linux/include/asm-mips64/gfx.h
--- v2.3.47/linux/include/asm-mips64/gfx.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/gfx.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,56 @@
+/* $Id: gfx.h,v 1.1 1999/08/19 22:56:34 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * This is the user-visible SGI GFX interface.
+ *
+ * This must be used verbatim into the GNU libc.  It does not include
+ * any kernel-only bits on it.  
+ *
+ * miguel@nuclecu.unam.mx
+ */
+#ifndef _ASM_GFX_H
+#define _ASM_GFX_H
+
+/* The iocls, yes, they do not make sense, but such is life */
+#define GFX_BASE             100
+#define GFX_GETNUM_BOARDS    (GFX_BASE + 1)
+#define GFX_GETBOARD_INFO    (GFX_BASE + 2)
+#define GFX_ATTACH_BOARD     (GFX_BASE + 3)
+#define GFX_DETACH_BOARD     (GFX_BASE + 4)
+#define GFX_IS_MANAGED       (GFX_BASE + 5)
+
+#define GFX_MAPALL           (GFX_BASE + 10)
+#define GFX_LABEL            (GFX_BASE + 11)
+
+#define GFX_INFO_NAME_SIZE  16
+#define GFX_INFO_LABEL_SIZE 16
+
+struct gfx_info {
+	char name  [GFX_INFO_NAME_SIZE];  /* board name */
+	char label [GFX_INFO_LABEL_SIZE]; /* label name */
+	unsigned short int xpmax, ypmax;  /* screen resolution */
+	unsigned int lenght;	          /* size of a complete gfx_info for this board */
+};
+
+struct gfx_getboardinfo_args {
+	unsigned int board;     /* board number.  starting from zero */
+	void *buf;              /* pointer to gfx_info */
+	unsigned int len;       /* buffer size of buf */
+};
+
+struct gfx_attach_board_args {
+	unsigned int board;	/* board number, starting from zero */
+	void        *vaddr;	/* address where the board registers should be mapped */
+};
+
+#ifdef __KERNEL__
+/* umap.c */
+extern void remove_mapping (struct task_struct *, unsigned long, unsigned long);
+extern void *vmalloc_uncached (unsigned long size);
+extern int vmap_page_range (unsigned long from, unsigned long size, unsigned long vaddr);
+#endif
+
+#endif /* _ASM_GFX_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/hardirq.h linux/include/asm-mips64/hardirq.h
--- v2.3.47/linux/include/asm-mips64/hardirq.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/hardirq.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,40 @@
+/* $Id: hardirq.h,v 1.4 2000/02/23 00:41:38 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_HARDIRQ_H
+#define _ASM_HARDIRQ_H
+
+#include <linux/threads.h>
+
+extern unsigned int local_irq_count[NR_CPUS];
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() ({ int __cpu = smp_processor_id(); \
+	(local_irq_count[__cpu] + local_bh_count[__cpu] != 0); })
+#define in_irq() (local_irq_count[smp_processor_id()] != 0)
+
+#ifndef __SMP__
+
+#define hardirq_trylock(cpu)	(local_irq_count[cpu] == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
+
+#define irq_enter(cpu)		(local_irq_count[cpu]++)
+#define irq_exit(cpu)		(local_irq_count[cpu]--)
+
+#define synchronize_irq()	barrier();
+
+#else
+
+#error No habla MIPS SMP
+
+#endif /* __SMP__ */
+#endif /* _ASM_HARDIRQ_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/hdreg.h linux/include/asm-mips64/hdreg.h
--- v2.3.47/linux/include/asm-mips64/hdreg.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/hdreg.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,18 @@
+/* $Id: hdreg.h,v 1.1 1999/08/21 22:19:17 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *  This file contains the MIPS architecture specific IDE code.
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ */
+
+#ifndef _ASM_HDREG_H
+#define _ASM_HDREG_H
+
+typedef unsigned short ide_ioreg_t;
+
+#endif /* _ASM_HDREG_H */
+
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/highmem.h linux/include/asm-mips64/highmem.h
--- v2.3.47/linux/include/asm-mips64/highmem.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/highmem.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,28 @@
+/* $Id: highmem.h,v 1.2 2000/01/29 01:42:28 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 by Ralf Baechle
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#include <linux/init.h>
+#include <asm/pgtable.h>
+
+/* declarations for highmem.c */
+extern unsigned long highstart_pfn, highend_pfn;
+
+extern pte_t *kmap_pte;
+extern pgprot_t kmap_prot;
+
+#define kmap_init()			do { } while(0)
+#define kmap(page)			page_address(page)
+#define kunmap(page)			do { } while(0)
+#define kmap_atomic(page, type)		page_address(page)
+#define kunmap_atomic(page, type)	do { } while(0)
+
+#endif /* _ASM_HIGHMEM_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/ide.h linux/include/asm-mips64/ide.h
--- v2.3.47/linux/include/asm-mips64/ide.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/ide.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,132 @@
+/* $Id: ide.h,v 1.1 1999/08/21 22:19:17 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *  This file contains the MIPS architecture specific IDE code.
+ *
+ * Copyright (C) 1994-1996  Linus Torvalds & authors
+ */
+
+#ifndef _ASM_IDE_H
+#define _ASM_IDE_H
+
+#ifdef __KERNEL__
+
+#ifndef MAX_HWIFS
+#define MAX_HWIFS	6
+#endif
+
+#define ide__sti()	__sti()
+
+struct ide_ops {
+	int (*ide_default_irq)(ide_ioreg_t base);
+	ide_ioreg_t (*ide_default_io_base)(int index);
+	void (*ide_init_hwif_ports)(hw_regs_t *hw, ide_ioreg_t data_port,
+	                            ide_ioreg_t ctrl_port, int *irq);
+	int (*ide_request_irq)(unsigned int irq, void (*handler)(int, void *,
+	                       struct pt_regs *), unsigned long flags,
+	                       const char *device, void *dev_id);
+	void (*ide_free_irq)(unsigned int irq, void *dev_id);
+	int (*ide_check_region) (ide_ioreg_t from, unsigned int extent);
+	void (*ide_request_region)(ide_ioreg_t from, unsigned int extent,
+	                        const char *name);
+	void (*ide_release_region)(ide_ioreg_t from, unsigned int extent);
+};
+
+extern struct ide_ops *ide_ops;
+
+static inline int
+ide_default_irq(ide_ioreg_t base)
+{
+	return ide_ops->ide_default_irq(base);
+}
+
+static inline ide_ioreg_t
+ide_default_io_base(int index)
+{
+	return ide_ops->ide_default_io_base(index);
+}
+
+static inline void
+ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
+                    ide_ioreg_t ctrl_port, int *irq)
+{
+	ide_ops->ide_init_hwif_ports(hw, data_port, ctrl_port, &hw->irq);
+
+	hw->irq = ide_ops->ide_default_irq(data_port);
+}
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static inline void ide_init_default_hwifs(void)
+{
+#ifdef __DO_I_NEED_THIS
+	hw_regs_t hw;
+	int index;
+
+	for (index = 0; index < MAX_HWIFS; index++) {
+		ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, 0);
+		hw.irq = ide_default_irq(ide_default_io_base(index));
+		ide_register_hw(&hw, NULL);
+	}
+#endif /* __DO_I_NEED_THIS */
+}
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned head		: 4;	/* always zeros here */
+		unsigned unit		: 1;	/* drive select number, 0 or 1 */
+		unsigned bit5		: 1;	/* always 1 */
+		unsigned lba		: 1;	/* using LBA instead of CHS */
+		unsigned bit7		: 1;	/* always 1 */
+	} b;
+	} select_t;
+
+static inline int
+ide_request_irq(unsigned int irq,
+                void (*handler)(int,void *, struct pt_regs *),
+                unsigned long flags, const char *device, void *dev_id)
+{
+	return ide_ops->ide_request_irq(irq, handler, flags, device, dev_id);
+}
+
+static inline void
+ide_free_irq(unsigned int irq, void *dev_id)
+{
+	ide_ops->ide_free_irq(irq, dev_id);
+}
+
+static inline int
+ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+	return ide_ops->ide_check_region(from, extent);
+}
+
+static inline void
+ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
+{
+	ide_ops->ide_request_region(from, extent, name);
+}
+
+static inline void
+ide_release_region(ide_ioreg_t from, unsigned int extent)
+{
+	ide_ops->ide_release_region(from, extent);
+}
+
+/*
+ * The following are not needed for the non-m68k ports
+ */
+#define ide_ack_intr(hwif)		(1)
+#define ide_fix_driveid(id)		do {} while (0)
+#define ide_release_lock(lock)		do {} while (0)
+#define ide_get_lock(lock, hdlr, data)	do {} while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IDE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/init.h linux/include/asm-mips64/init.h
--- v2.3.47/linux/include/asm-mips64/init.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/init.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,26 @@
+/* $Id: init.h,v 1.1 1999/08/18 23:37:51 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ */
+#ifndef _ASM_INIT_H
+#define _ASM_INIT_H
+
+#define __init __attribute__ ((__section__ (".text.init")))
+#define __initdata __attribute__ ((__section__ (".data.init")))
+#define __initfunc(__arginit) \
+	__arginit __init; \
+	__arginit
+
+#define __initlocaldata  __initdata
+
+/* For assembly routines */
+#define __INIT		.section	.text.init,"ax"
+#define __FINIT		.previous
+#define __INITDATA	.section	.data.init,"a"
+#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
+
+#endif /* _ASM_INIT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/inst.h linux/include/asm-mips64/inst.h
--- v2.3.47/linux/include/asm-mips64/inst.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/inst.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,305 @@
+/* $Id: inst.h,v 1.1 1999/12/04 03:59:12 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Format of an instruction in memory.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#ifndef _ASM_INST_H
+#define _ASM_INST_H
+
+/*
+ * Major opcodes; before MIPS IV cop1x was called cop3.
+ */
+enum major_op {
+	spec_op, bcond_op, j_op, jal_op,
+	beq_op, bne_op, blez_op, bgtz_op,
+	addi_op, addiu_op, slti_op, sltiu_op,
+	andi_op, ori_op, xori_op, lui_op,
+	cop0_op, cop1_op, cop2_op, cop1x_op,
+	beql_op, bnel_op, blezl_op, bgtzl_op,
+	daddi_op, daddiu_op, ldl_op, ldr_op,
+	major_1c_op, major_1d_op, major_1e_op, major_1f_op,
+	lb_op, lh_op, lwl_op, lw_op,
+	lbu_op, lhu_op, lwr_op, lwu_op,
+	sb_op, sh_op, swl_op, sw_op,
+	sdl_op, sdr_op, swr_op, cache_op,
+	ll_op, lwc1_op, lwc2_op, pref_op,
+	lld_op, ldc1_op, ldc2_op, ld_op,
+	sc_op, swc1_op, swc2_op, major_3b_op, /* Opcode 0x3b is unused */
+	scd_op, sdc1_op, sdc2_op, sd_op
+};
+
+/*
+ * func field of spec opcode.
+ */
+enum spec_op {
+	sll_op, movc_op, srl_op, sra_op,
+	sllv_op, srlv_op, srav_op, spec1_unused_op, /* Opcode 0x07 is unused */
+	jr_op, jalr_op, movz_op, movn_op,
+	syscall_op, break_op, spim_op, sync_op,
+	mfhi_op, mthi_op, mflo_op, mtlo_op,
+	dsllv_op, spec2_unused_op, dsrlv_op, dsrav_op,
+	mult_op, multu_op, div_op, divu_op,
+	dmult_op, dmultu_op, ddiv_op, ddivu_op,
+	add_op, addu_op, sub_op, subu_op,
+	and_op, or_op, xor_op, nor_op,
+	spec3_unused_op, spec4_unused_op, slt_op, sltu_op,
+	dadd_op, daddu_op, dsub_op, dsubu_op,
+	tge_op, tgeu_op, tlt_op, tltu_op,
+	teq_op, spec5_unused_op, tne_op, spec6_unused_op,
+	dsll_op, spec7_unused_op, dsrl_op, dsra_op,
+	dsll32_op, spec8_unused_op, dsrl32_op, dsra32_op
+};
+
+/*
+ * rt field of bcond opcodes.
+ */
+enum rt_op {
+	bltz_op, bgez_op, bltzl_op, bgezl_op,
+	spimi_op, unused_rt_op_0x05, unused_rt_op_0x06, unused_rt_op_0x07,
+	tgei_op, tgeiu_op, tlti_op, tltiu_op,
+	teqi_op, unused_0x0d_rt_op, tnei_op, unused_0x0f_rt_op,
+	bltzal_op, bgezal_op, bltzall_op, bgezall_op
+	/*
+	 * The others (0x14 - 0x1f) are unused.
+ 	 */
+};
+
+/*
+ * rs field of cop opcodes.
+ */
+enum cop_op {
+	mfc_op        = 0x00, dmfc_op       = 0x01,
+	cfc_op        = 0x02, mtc_op        = 0x04,
+	dmtc_op       = 0x05, ctc_op        = 0x06,
+	bc_op         = 0x08, cop_op        = 0x10,
+	copm_op       = 0x18
+};
+
+/*
+ * func field of cop0 coi opcodes.
+ */
+enum cop0_coi_func {
+	tlbr_op       = 0x01, tlbwi_op      = 0x02,
+	tlbwr_op      = 0x06, tlbp_op       = 0x08,
+	rfe_op        = 0x10, eret_op       = 0x18
+};
+
+/*
+ * func field of cop0 com opcodes.
+ */
+enum cop0_com_func {
+	tlbr1_op      = 0x01, tlbw_op       = 0x02,
+	tlbp1_op      = 0x08, dctr_op       = 0x09,
+	dctw_op       = 0x0a
+};
+
+/*
+ * fmt field of cop1 opcodes.
+ */
+enum cop1_fmt {
+	s_fmt, d_fmt, e_fmt, q_fmt,
+	w_fmt, l_fmt
+};
+
+/*
+ * func field of cop1 instructions using d, s or w format.
+ */
+enum cop1_sdw_func {
+	fadd_op      =  0x00, fsub_op      =  0x01,
+	fmul_op      =  0x02, fdiv_op      =  0x03,
+	fsqrt_op     =  0x04, fabs_op      =  0x05,
+	fmov_op      =  0x06, fneg_op      =  0x07,
+	froundl_op   =  0x08, ftruncl_op   =  0x09,
+	fceill_op    =  0x0a, ffloorl_op   =  0x0b,
+	fround_op    =  0x0c, ftrunc_op    =  0x0d,
+	fceil_op     =  0x0e, ffloor_op    =  0x0f,
+	fmovc_op     =  0x11, fmovz_op     =  0x12,
+	fmovn_op     =  0x13, frecip_op    =  0x15,
+	frsqrt_op    =  0x16, fcvts_op     =  0x20,
+	fcvtd_op     =  0x21, fcvte_op     =  0x22,
+	fcvtw_op     =  0x24, fcvtl_op     =  0x25,
+	fcmp_op      =  0x30
+};
+
+/*
+ * func field of cop1x opcodes (MIPS IV).
+ */
+enum cop1x_func {
+	lwxc1_op     =  0x00, ldxc1_op     =  0x01,
+	pfetch_op    =  0x07, swxc1_op     =  0x08,
+	sdxc1_op     =  0x09, madd_s_op    =  0x20,
+	madd_d_op    =  0x21, madd_e_op    =  0x22,
+	msub_s_op    =  0x28, msub_d_op    =  0x29,
+	msub_e_op    =  0x2a, nmadd_s_op   =  0x30,
+	nmadd_d_op   =  0x31, nmadd_e_op   =  0x32,
+	nmsub_s_op   =  0x38, nmsub_d_op   =  0x39,
+	nmsub_e_op   =  0x3a
+};
+
+/*
+ * func field for mad opcodes (MIPS IV).
+ */
+enum mad_func {
+	madd_op      = 0x08, msub_op      = 0x0a,
+	nmadd_op     = 0x0c, nmsub_op     = 0x0e
+};
+
+/*
+ * Damn ...  bitfields depend from byteorder :-(
+ */
+#ifdef __MIPSEB__
+struct j_format {	/* Jump format */
+	unsigned int opcode : 6;
+	unsigned int target : 26;
+};
+
+struct i_format {	/* Immediate format (addi, lw, ...) */
+	unsigned int opcode : 6;
+	unsigned int rs : 5;
+	unsigned int rt : 5;
+	signed int simmediate : 16;
+};
+
+struct u_format {	/* Unsigned immediate format (ori, xori, ...) */
+	unsigned int opcode : 6;
+	unsigned int rs : 5;
+	unsigned int rt : 5;
+	unsigned int uimmediate : 16;
+};
+
+struct c_format {	/* Cache (>= R6000) format */
+	unsigned int opcode : 6;
+	unsigned int rs : 5;
+	unsigned int c_op : 3;
+	unsigned int cache : 2;
+	unsigned int simmediate : 16;
+};
+
+struct r_format {	/* Register format */
+	unsigned int opcode : 6;
+	unsigned int rs : 5;
+	unsigned int rt : 5;
+	unsigned int rd : 5;
+	unsigned int re : 5;
+	unsigned int func : 6;
+};
+
+struct p_format {	/* Performance counter format (R10000) */
+	unsigned int opcode : 6;
+	unsigned int rs : 5;
+	unsigned int rt : 5;
+	unsigned int rd : 5;
+	unsigned int re : 5;
+	unsigned int func : 6;
+};
+
+struct f_format {	/* FPU register format */
+	unsigned int opcode : 6;
+	unsigned int : 1;
+	unsigned int fmt : 4;
+	unsigned int rt : 5;
+	unsigned int rd : 5;
+	unsigned int re : 5;
+	unsigned int func : 6;
+};
+
+struct ma_format {	/* FPU multipy and add format (MIPS IV) */
+	unsigned int opcode : 6;
+	unsigned int fr : 5;
+	unsigned int ft : 5;
+	unsigned int fs : 5;
+	unsigned int fd : 5;
+	unsigned int func : 4;
+	unsigned int fmt : 2;
+};
+
+#elif defined(__MIPSEL__)
+
+struct j_format {	/* Jump format */
+	unsigned int target : 26;
+	unsigned int opcode : 6;
+};
+
+struct i_format {	/* Immediate format */
+	signed int simmediate : 16;
+	unsigned int rt : 5;
+	unsigned int rs : 5;
+	unsigned int opcode : 6;
+};
+
+struct u_format {	/* Unsigned immediate format */
+	unsigned int uimmediate : 16;
+	unsigned int rt : 5;
+	unsigned int rs : 5;
+	unsigned int opcode : 6;
+};
+
+struct c_format {	/* Cache (>= R6000) format */
+	unsigned int simmediate : 16;
+	unsigned int cache : 2;
+	unsigned int c_op : 3;
+	unsigned int rs : 5;
+	unsigned int opcode : 6;
+};
+
+struct r_format {	/* Register format */
+	unsigned int func : 6;
+	unsigned int re : 5;
+	unsigned int rd : 5;
+	unsigned int rt : 5;
+	unsigned int rs : 5;
+	unsigned int opcode : 6;
+};
+
+struct p_format {	/* Performance counter format (R10000) */
+	unsigned int func : 6;
+	unsigned int re : 5;
+	unsigned int rd : 5;
+	unsigned int rt : 5;
+	unsigned int rs : 5;
+	unsigned int opcode : 6;
+};
+
+struct f_format {	/* FPU register format */
+	unsigned int func : 6;
+	unsigned int re : 5;
+	unsigned int rd : 5;
+	unsigned int rt : 5;
+	unsigned int fmt : 4;
+	unsigned int : 1;
+	unsigned int opcode : 6;
+};
+
+struct ma_format {	/* FPU multipy and add format (MIPS IV) */
+	unsigned int fmt : 2;
+	unsigned int func : 4;
+	unsigned int fd : 5;
+	unsigned int fs : 5;
+	unsigned int ft : 5;
+	unsigned int fr : 5;
+	unsigned int opcode : 6;
+};
+
+#else /* !defined (__MIPSEB__) && !defined (__MIPSEL__) */
+#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
+#endif
+
+union mips_instruction {
+	unsigned int word;
+	unsigned short halfword[2];
+	unsigned char byte[4];
+	struct j_format j_format;
+	struct i_format i_format;
+	struct u_format u_format;
+	struct c_format c_format;
+	struct r_format r_format;
+	struct f_format f_format;
+        struct ma_format ma_format;
+};
+
+#endif /* _ASM_INST_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/io.h linux/include/asm-mips64/io.h
--- v2.3.47/linux/include/asm-mips64/io.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/io.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,402 @@
+/* $Id: io.h,v 1.10 2000/02/24 00:13:20 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995 Waldorf GmbH
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+#include <linux/config.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+
+#ifdef CONFIG_SGI_IP22
+#include <asm/sgi/io.h>
+#endif
+
+#ifdef CONFIG_SGI_IP27
+#include <asm/sn/io.h>
+#endif
+
+/*
+ * Slowdown I/O port space accesses for antique hardware.
+ */
+#undef CONF_SLOWDOWN_IO
+
+/*
+ * On MIPS, we have the whole physical address space mapped at all
+ * times, so "ioremap()" and "iounmap()" do not need to do anything.
+ *
+ * We cheat a bit and always return uncachable areas until we've fixed
+ * the drivers to handle caching properly.
+ */
+extern inline void *
+ioremap(unsigned long offset, unsigned long size)
+{
+	return (void *) (IO_SPACE_BASE | offset);
+}
+
+/* This one maps high address device memory and turns off caching for that
+ *  area.  It's useful if some control registers are in such an area and write
+ * combining or read caching is not desirable.
+ */
+extern inline void *
+ioremap_nocache (unsigned long offset, unsigned long size)
+{
+	return (void *) (IO_SPACE_BASE | offset);
+}
+
+extern inline void iounmap(void *addr)
+{
+}
+
+/*
+ * This assumes sane hardware.  The Origin is.
+ */
+#define readb(addr)		(*(volatile unsigned char *) (addr))
+#define readw(addr)		(*(volatile unsigned short *) (addr))
+#define readl(addr)		(*(volatile unsigned int *) (addr))
+
+#define writeb(b,addr)		(*(volatile unsigned char *) (addr) = (b))
+#define writew(b,addr)		(*(volatile unsigned short *) (addr) = (b))
+#define writel(b,addr)		(*(volatile unsigned int *) (addr) = (b))
+
+#define memset_io(a,b,c)	memset((void *) a,(b),(c))
+#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+/* The ISA versions are supplied by system specific code */
+
+/*
+ * On MIPS I/O ports are memory mapped, so we access them using normal
+ * load/store instructions. mips_io_port_base is the virtual address to
+ * which all ports are being mapped.  For sake of efficiency some code
+ * assumes that this is an address that can be loaded with a single lui
+ * instruction, so the lower 16 bits must be zero.  Should be true on
+ * on any sane architecture; generic code does not use this assumption.
+ */
+extern unsigned long mips_io_port_base;
+
+#define __SLOW_DOWN_IO \
+	__asm__ __volatile__( \
+		"sb\t$0,0x80(%0)" \
+		: : "r" (mips_io_port_base));
+
+#ifdef CONF_SLOWDOWN_IO
+#ifdef REALLY_SLOW_IO
+#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
+#else
+#define SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+#else
+#define SLOW_DOWN_IO
+#endif
+
+/*
+ * Change virtual addresses to physical addresses and vv.
+ * These are trivial on the 1:1 Linux/MIPS mapping
+ */
+extern inline unsigned long virt_to_phys(volatile void * address)
+{
+	return (unsigned long)address - PAGE_OFFSET;
+}
+
+extern inline void * phys_to_virt(unsigned long address)
+{
+	return (void *)(address + PAGE_OFFSET);
+}
+
+#define	BRIDGE_DIRECT_MAPPED_BASE	0xa200000000000000ull
+
+/*
+ * IO bus memory addresses are also 1:1 with the physical address
+ * This simplistic model doesn't hold for the Origin.
+ */
+extern inline unsigned long virt_to_bus(volatile void * address)
+{
+	return (((unsigned long)address - PAGE_OFFSET)|BRIDGE_DIRECT_MAPPED_BASE);
+}
+
+extern inline void * bus_to_virt(unsigned long address)
+{
+	return (void *)((address & ~BRIDGE_DIRECT_MAPPED_BASE) + PAGE_OFFSET);
+}
+
+/*
+ * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped
+ * for the processor.  This implies the assumption that there is only
+ * one of these busses.
+ */
+extern unsigned long isa_slot_offset;
+
+/*
+ * We don't have csum_partial_copy_fromio() yet, so we cheat here and
+ * just copy it. The net code will then do the checksum later.
+ */
+#define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len))
+
+static inline int
+check_signature(unsigned long io_addr, const unsigned char *signature,
+                int length)
+{
+	int retval = 0;
+	do {
+		if (readb(io_addr) != *signature)
+			goto out;
+		io_addr++;
+		signature++;
+		length--;
+	} while (length);
+	retval = 1;
+out:
+	return retval;
+}
+
+/*
+ * Talk about misusing macros..
+ */
+
+#define __OUT1(s) \
+extern inline void __out##s(unsigned int value, unsigned int port) {
+
+#define __OUT2(m) \
+__asm__ __volatile__ ("s" #m "\t%0,%1(%2)"
+
+#define __OUT(m,s) \
+__OUT1(s) __OUT2(m) : : "r" (value), "i" (0), "r" (mips_io_port_base+port)); } \
+__OUT1(s##c) __OUT2(m) : : "r" (value), "ir" (port), "r" (mips_io_port_base)); } \
+__OUT1(s##_p) __OUT2(m) : : "r" (value), "i" (0), "r" (mips_io_port_base+port)); \
+	SLOW_DOWN_IO; } \
+__OUT1(s##c_p) __OUT2(m) : : "r" (value), "ir" (port), "r" (mips_io_port_base)); \
+	SLOW_DOWN_IO; }
+
+#define __IN1(t,s) \
+extern __inline__ t __in##s(unsigned int port) { t _v;
+
+/*
+ * Required nops will be inserted by the assembler
+ */
+#define __IN2(m) \
+__asm__ __volatile__ ("l" #m "\t%0,%1(%2)"
+
+#define __IN(t,m,s) \
+__IN1(t,s) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); return _v; } \
+__IN1(t,s##c) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); return _v; } \
+__IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); SLOW_DOWN_IO; return _v; } \
+__IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return _v; }
+
+#define __INS1(s) \
+extern inline void __ins##s(unsigned int port, void * addr, unsigned long count) {
+
+#define __INS2(m) \
+if (count) \
+__asm__ __volatile__ ( \
+	".set\tnoreorder\n\t" \
+	".set\tnoat\n" \
+	"1:\tl" #m "\t$1, %4(%5)\n\t" \
+	"dsubiu\t%1, 1\n\t" \
+	"s" #m "\t$1,(%0)\n\t" \
+	"bnez\t%1, 1b\n\t" \
+	"daddiu\t%0, %6\n\t" \
+	".set\tat\n\t" \
+	".set\treorder"
+
+#define __INS(m,s,i) \
+__INS1(s) __INS2(m) \
+	: "=r" (addr), "=r" (count) \
+	: "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \
+	: "$1");} \
+__INS1(s##c) __INS2(m) \
+	: "=r" (addr), "=r" (count) \
+	: "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \
+	: "$1");}
+
+#define __OUTS1(s) \
+extern inline void __outs##s(unsigned int port, const void * addr, unsigned long count) {
+
+#define __OUTS2(m) \
+if (count) \
+__asm__ __volatile__ ( \
+	".set\tnoreorder\n\t" \
+	".set\tnoat\n" \
+	"1:\tl" #m "\t$1, (%0)\n\t" \
+	"dsubu\t%1, 1\n\t" \
+	"s" #m "\t$1, %4(%5)\n\t" \
+	"bnez\t%1, 1b\n\t" \
+	"daddiu\t%0, %6\n\t" \
+	".set\tat\n\t" \
+	".set\treorder"
+
+#define __OUTS(m,s,i) \
+__OUTS1(s) __OUTS2(m) \
+	: "=r" (addr), "=r" (count) \
+	: "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \
+	: "$1");} \
+__OUTS1(s##c) __OUTS2(m) \
+	: "=r" (addr), "=r" (count) \
+	: "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \
+	: "$1");}
+
+__IN(unsigned char,b,b)
+__IN(unsigned short,h,w)
+__IN(unsigned int,w,l)
+
+__OUT(b,b)
+__OUT(h,w)
+__OUT(w,l)
+
+__INS(b,b,1)
+__INS(h,w,2)
+__INS(w,l,4)
+
+__OUTS(b,b,1)
+__OUTS(h,w,2)
+__OUTS(w,l,4)
+
+/*
+ * Note that due to the way __builtin_constant_p() works, you
+ *  - can't use it inside an inline function (it will never be true)
+ *  - you don't have to worry about side effects within the __builtin..
+ */
+#define outb(val,port) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__outbc((val),(port)) : \
+	__outb((val),(port)))
+
+#define inb(port) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__inbc(port) : \
+	__inb(port))
+
+#define outb_p(val,port) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__outbc_p((val),(port)) : \
+	__outb_p((val),(port)))
+
+#define inb_p(port) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__inbc_p(port) : \
+	__inb_p(port))
+
+#define outw(val,port) \
+((__builtin_constant_p((port^2)) && (port^2) < 32768) ? \
+	__outwc((val),(port^2)) : \
+	__outw((val),(port^2)))
+
+#define inw(port) \
+((__builtin_constant_p((port^2)) && (port^2) < 32768) ? \
+	__inwc(port^2) : \
+	__inw(port^2))
+
+#define outw_p(val,port) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__outwc_p((val),(port)) : \
+	__outw_p((val),(port)))
+
+#define inw_p(port) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__inwc_p(port) : \
+	__inw_p(port))
+
+#define outl(val,port) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__outlc((val),(port)) : \
+	__outl((val),(port)))
+
+#define inl(port) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__inlc(port) : \
+	__inl(port))
+
+#define outl_p(val,port) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__outlc_p((val),(port)) : \
+	__outl_p((val),(port)))
+
+#define inl_p(port) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__inlc_p(port) : \
+	__inl_p(port))
+
+
+#define outsb(port,addr,count) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__outsbc((port),(addr),(count)) : \
+	__outsb ((port),(addr),(count)))
+
+#define insb(port,addr,count) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__insbc((port),(addr),(count)) : \
+	__insb((port),(addr),(count)))
+
+#define outsw(port,addr,count) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__outswc((port),(addr),(count)) : \
+	__outsw ((port),(addr),(count)))
+
+#define insw(port,addr,count) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__inswc((port),(addr),(count)) : \
+	__insw((port),(addr),(count)))
+
+#define outsl(port,addr,count) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__outslc((port),(addr),(count)) : \
+	__outsl ((port),(addr),(count)))
+
+#define insl(port,addr,count) \
+((__builtin_constant_p((port)) && (port) < 32768) ? \
+	__inslc((port),(addr),(count)) : \
+	__insl((port),(addr),(count)))
+
+/*
+ * The caches on some architectures aren't dma-coherent and have need to
+ * handle this in software.  There are three types of operations that
+ * can be applied to dma buffers.
+ *
+ *  - dma_cache_wback_inv(start, size) makes caches and coherent by
+ *    writing the content of the caches back to memory, if necessary.
+ *    The function also invalidates the affected part of the caches as
+ *    necessary before DMA transfers from outside to memory.
+ *  - dma_cache_wback(start, size) makes caches and coherent by
+ *    writing the content of the caches back to memory, if necessary.
+ *    The function also invalidates the affected part of the caches as
+ *    necessary before DMA transfers from outside to memory.
+ *  - dma_cache_inv(start, size) invalidates the affected parts of the
+ *    caches.  Dirty lines of the caches may be written back or simply
+ *    be discarded.  This operation is necessary before dma operations
+ *    to the memory.
+ */
+#ifdef CONFIG_COHERENT_IO
+
+/* This is for example for IP27.  */
+extern inline void dma_cache_wback_inv(unsigned long start, unsigned long size)
+{
+}
+
+extern inline void dma_cache_wback(unsigned long start, unsigned long size)
+{
+}
+
+extern inline void dma_cache_inv(unsigned long start, unsigned long size)
+{
+}
+
+#else
+
+extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
+extern void (*_dma_cache_wback)(unsigned long start, unsigned long size);
+extern void (*_dma_cache_inv)(unsigned long start, unsigned long size);
+
+#define dma_cache_wback_inv(start,size)	_dma_cache_wback_inv(start,size)
+#define dma_cache_wback(start,size)	_dma_cache_wback(start,size)
+#define dma_cache_inv(start,size)	_dma_cache_inv(start,size)
+
+#endif
+
+#endif /* _ASM_IO_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/ioc3.h linux/include/asm-mips64/ioc3.h
--- v2.3.47/linux/include/asm-mips64/ioc3.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/ioc3.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,661 @@
+/* $Id: ioc3.h,v 1.2 2000/02/18 09:54:39 ulfc Exp $
+ *
+ * Copyright (C) 1999 Ralf Baechle
+ * This file is part of the Linux driver for the SGI IOC3.
+ */
+#ifndef IOC3_H
+#define IOC3_H
+
+/* SUPERIO uart register map */
+typedef volatile struct ioc3_uartregs {
+	union {
+		volatile u8	rbr;	/* read only, DLAB == 0 */
+		volatile u8	thr;	/* write only, DLAB == 0 */
+		volatile u8	dll;	/* DLAB == 1 */
+	} u1;
+	union {
+		volatile u8	ier;	/* DLAB == 0 */
+		volatile u8	dlm;	/* DLAB == 1 */
+	} u2;
+	union {
+		volatile u8	iir;	/* read only */
+		volatile u8	fcr;	/* write only */
+	} u3;
+	volatile u8	    iu_lcr;
+	volatile u8	    iu_mcr;
+	volatile u8	    iu_lsr;
+	volatile u8	    iu_msr;
+	volatile u8	    iu_scr;
+} ioc3_uregs_t;
+
+#define iu_rbr u1.rbr
+#define iu_thr u1.thr
+#define iu_dll u1.dll
+#define iu_ier u2.ier
+#define iu_dlm u2.dlm
+#define iu_iir u3.iir
+#define iu_fcr u3.fcr
+
+struct ioc3_sioregs {
+	volatile u8		fill[0x141];	/* starts at 0x141 */
+
+	volatile u8		uartc;
+	volatile u8		kbdcg;
+
+	volatile u8		fill0[0x150 - 0x142 - 1];
+
+	volatile u8		pp_data;
+	volatile u8		pp_dsr;
+	volatile u8		pp_dcr;
+
+	volatile u8		fill1[0x158 - 0x152 - 1];
+
+	volatile u8		pp_fifa;
+	volatile u8		pp_cfgb;
+	volatile u8		pp_ecr;
+
+	volatile u8		fill2[0x168 - 0x15a - 1];
+
+	volatile u8		rtcad;
+	volatile u8		rtcdat;
+
+	volatile u8		fill3[0x170 - 0x169 - 1];
+
+	struct ioc3_uartregs    uartb;	/* 0x20170  */
+	struct ioc3_uartregs    uarta;	/* 0x20178  */
+};
+
+/* Register layout of IOC3 in configuration space.  */
+struct ioc3 {
+	volatile u32	pad0[7];	/* 0x00000  */
+	volatile u32	sio_ir;		/* 0x0001c  */
+	volatile u32	sio_ies;	/* 0x00020  */
+	volatile u32	sio_iec;	/* 0x00024  */
+	volatile u32	sio_cr;		/* 0x00028  */
+	volatile u32	int_out;	/* 0x0002c  */
+	volatile u32	mcr;		/* 0x00030  */
+
+	/* General Purpose I/O registers  */
+	volatile u32	gpcr_s;		/* 0x00034  */
+	volatile u32	gpcr_c;		/* 0x00038  */
+	volatile u32	gpdr;		/* 0x0003c  */
+	volatile u32	gppr_0;		/* 0x00040  */
+	volatile u32	gppr_1;		/* 0x00044  */
+	volatile u32	gppr_2;		/* 0x00048  */
+	volatile u32	gppr_3;		/* 0x0004c  */
+	volatile u32	gppr_4;		/* 0x00050  */
+	volatile u32	gppr_5;		/* 0x00054  */
+	volatile u32	gppr_6;		/* 0x00058  */
+	volatile u32	gppr_7;		/* 0x0005c  */
+	volatile u32	gppr_8;		/* 0x00060  */
+	volatile u32	gppr_9;		/* 0x00064  */
+	volatile u32	gppr_10;	/* 0x00068  */
+	volatile u32	gppr_11;	/* 0x0006c  */
+	volatile u32	gppr_12;	/* 0x00070  */
+	volatile u32	gppr_13;	/* 0x00074  */
+	volatile u32	gppr_14;	/* 0x00078  */
+	volatile u32	gppr_15;	/* 0x0007c  */
+
+	/* Parallel Port Registers  */
+	volatile u32	ppbr_h_a;	/* 0x00080  */
+	volatile u32	ppbr_l_a;	/* 0x00084  */
+	volatile u32	ppcr_a;		/* 0x00088  */
+	volatile u32	ppcr;		/* 0x0008c  */
+	volatile u32	ppbr_h_b;	/* 0x00090  */
+	volatile u32	ppbr_l_b;	/* 0x00094  */
+	volatile u32	ppcr_b;		/* 0x00098  */
+
+	/* Keyboard and Mouse Registers  */
+	volatile u32	km_csr;		/* 0x0009c  */
+	volatile u32	k_rd;		/* 0x000a0  */
+	volatile u32	m_rd;		/* 0x000a4  */
+	volatile u32	k_wd;		/* 0x000a8  */
+	volatile u32	m_wd;		/* 0x000ac  */
+
+	/* Serial Port Registers  */
+	volatile u32	sbbr_h;		/* 0x000b0  */
+	volatile u32	sbbr_l;		/* 0x000b4  */
+	volatile u32	sscr_a;		/* 0x000b8  */
+	volatile u32	stpir_a;	/* 0x000bc  */
+	volatile u32	stcir_a;	/* 0x000c0  */
+	volatile u32	srpir_a;	/* 0x000c4  */
+	volatile u32	srcir_a;	/* 0x000c8  */
+	volatile u32	srtr_a;		/* 0x000cc  */
+	volatile u32	shadow_a;	/* 0x000d0  */
+	volatile u32	sscr_b;		/* 0x000d4  */
+	volatile u32	stpir_b;	/* 0x000d8  */
+	volatile u32	stcir_b;	/* 0x000dc  */
+	volatile u32	srpir_b;	/* 0x000e0  */
+	volatile u32	srcir_b;	/* 0x000e4  */
+	volatile u32	srtr_b;		/* 0x000e8  */
+	volatile u32	shadow_b;	/* 0x000ec  */
+
+	/* Ethernet Registers  */
+	volatile u32	emcr;		/* 0x000f0  */
+	volatile u32	eisr;		/* 0x000f4  */
+	volatile u32	eier;		/* 0x000f8  */
+	volatile u32	ercsr;		/* 0x000fc  */
+	volatile u32	erbr_h;		/* 0x00100  */
+	volatile u32	erbr_l;		/* 0x00104  */
+	volatile u32	erbar;		/* 0x00108  */
+	volatile u32	ercir;		/* 0x0010c  */
+	volatile u32	erpir;		/* 0x00110  */
+	volatile u32	ertr;		/* 0x00114  */
+	volatile u32	etcsr;		/* 0x00118  */
+	volatile u32	ersr;		/* 0x0011c  */
+	volatile u32	etcdc;		/* 0x00120  */
+	volatile u32	ebir;		/* 0x00124  */
+	volatile u32	etbr_h;		/* 0x00128  */
+	volatile u32	etbr_l;		/* 0x0012c  */
+	volatile u32	etcir;		/* 0x00130  */
+	volatile u32	etpir;		/* 0x00134  */
+	volatile u32	emar_h;		/* 0x00138  */
+	volatile u32	emar_l;		/* 0x0013c  */
+	volatile u32	ehar_h;		/* 0x00140  */
+	volatile u32	ehar_l;		/* 0x00144  */
+	volatile u32	micr;		/* 0x00148  */
+	volatile u32	midr;		/* 0x0014c  */
+	volatile u32	pad1[(0x20000 - 0x00150) / 4];
+
+	/* SuperIO Registers  XXX */
+	struct ioc3_sioregs	sregs;	/* 0x20000 */
+	volatile u32	pad2[(0x40000 - 0x20180) / 4];
+
+	/* SSRAM Diagnostic Access */
+	volatile u32	ssram[(0x80000 - 0x40000) / 4];
+
+	/* Bytebus device offsets
+	   0x80000 -   Access to the generic devices selected with   DEV0
+	   0x9FFFF     bytebus DEV_SEL_0
+	   0xA0000 -   Access to the generic devices selected with   DEV1
+	   0xBFFFF     bytebus DEV_SEL_1
+	   0xC0000 -   Access to the generic devices selected with   DEV2
+	   0xDFFFF     bytebus DEV_SEL_2
+	   0xE0000 -   Access to the generic devices selected with   DEV3
+	   0xFFFFF     bytebus DEV_SEL_3  */
+};
+
+/*
+ * Ethernet RX Buffer
+ */
+struct ioc3_erxbuf {
+	u32	w0;			/* first word (valid,bcnt,cksum) */
+	u32	err;			/* second word various errors */
+	/* next comes n bytes of padding */
+	/* then the received ethernet frame itself */
+};
+
+#define ERXBUF_IPCKSUM_MASK	0x0000ffff
+#define ERXBUF_BYTECNT_MASK	0x07ff0000
+#define ERXBUF_BYTECNT_SHIFT	16
+#define ERXBUF_V		0x80000000
+
+#define ERXBUF_CRCERR		0x00000001	/* aka RSV15 */
+#define ERXBUF_FRAMERR		0x00000002	/* aka RSV14 */
+#define ERXBUF_CODERR		0x00000004	/* aka RSV13 */
+#define ERXBUF_INVPREAMB	0x00000008	/* aka RSV18 */
+#define ERXBUF_LOLEN		0x00007000	/* aka RSV2_0 */
+#define ERXBUF_HILEN		0x03ff0000	/* aka RSV12_3 */
+#define ERXBUF_MULTICAST	0x04000000	/* aka RSV16 */
+#define ERXBUF_BROADCAST	0x08000000	/* aka RSV17 */
+#define ERXBUF_LONGEVENT	0x10000000	/* aka RSV19 */
+#define ERXBUF_BADPKT		0x20000000	/* aka RSV20 */
+#define ERXBUF_GOODPKT		0x40000000	/* aka RSV21 */
+#define ERXBUF_CARRIER		0x80000000	/* aka RSV22 */
+
+/*
+ * Ethernet TX Descriptor
+ */
+#define ETXD_DATALEN    104
+struct ioc3_etxd {
+	u32	cmd;				/* command field */
+	u32	bufcnt;				/* buffer counts field */
+	u64	p1;				/* buffer pointer 1 */
+	u64	p2;				/* buffer pointer 2 */
+	u8	data[ETXD_DATALEN];		/* opt. tx data */
+};
+
+#define ETXD_BYTECNT_MASK	0x000007ff	/* total byte count */
+#define ETXD_INTWHENDONE	0x00001000	/* intr when done */
+#define ETXD_D0V		0x00010000	/* data 0 valid */
+#define ETXD_B1V		0x00020000	/* buf 1 valid */
+#define ETXD_B2V		0x00040000	/* buf 2 valid */
+#define ETXD_DOCHECKSUM		0x00080000	/* insert ip cksum */
+#define ETXD_CHKOFF_MASK	0x07f00000	/* cksum byte offset */
+#define ETXD_CHKOFF_SHIFT	20
+
+#define ETXD_D0CNT_MASK		0x0000007f
+#define ETXD_B1CNT_MASK		0x0007ff00
+#define ETXD_B1CNT_SHIFT	8
+#define ETXD_B2CNT_MASK		0x7ff00000
+#define ETXD_B2CNT_SHIFT	20
+
+/*
+ * Bytebus device space
+ */
+#define IOC3_BYTEBUS_DEV0	0x80000L
+#define IOC3_BYTEBUS_DEV1	0xa0000L
+#define IOC3_BYTEBUS_DEV2	0xc0000L
+#define IOC3_BYTEBUS_DEV3	0xe0000L
+
+/* ------------------------------------------------------------------------- */
+
+/* Superio Registers (PIO Access) */
+#define IOC3_SIO_BASE		0x20000
+#define IOC3_SIO_UARTC		(IOC3_SIO_BASE+0x141)	/* UART Config */
+#define IOC3_SIO_KBDCG		(IOC3_SIO_BASE+0x142)	/* KBD Config */
+#define IOC3_SIO_PP_BASE	(IOC3_SIO_BASE+PP_BASE)		/* Parallel Port */
+#define IOC3_SIO_RTC_BASE	(IOC3_SIO_BASE+0x168)	/* Real Time Clock */
+#define IOC3_SIO_UB_BASE	(IOC3_SIO_BASE+UARTB_BASE)	/* UART B */
+#define IOC3_SIO_UA_BASE	(IOC3_SIO_BASE+UARTA_BASE)	/* UART A */
+
+/* SSRAM Diagnostic Access */
+#define IOC3_SSRAM	IOC3_RAM_OFF	/* base of SSRAM diagnostic access */
+#define IOC3_SSRAM_LEN	0x40000 /* 256kb (address space size, may not be fully populated) */
+#define IOC3_SSRAM_DM	0x0000ffff	/* data mask */
+#define IOC3_SSRAM_PM	0x00010000	/* parity mask */
+
+/* bitmasks for PCI_SCR */
+#define PCI_SCR_PAR_RESP_EN	0x00000040	/* enb PCI parity checking */
+#define PCI_SCR_SERR_EN		0x00000100	/* enable the SERR# driver */
+#define PCI_SCR_DROP_MODE_EN	0x00008000	/* drop pios on parity err */
+#define PCI_SCR_RX_SERR		(0x1 << 16)
+#define PCI_SCR_DROP_MODE	(0x1 << 17)
+#define PCI_SCR_SIG_PAR_ERR	(0x1 << 24)
+#define PCI_SCR_SIG_TAR_ABRT	(0x1 << 27)
+#define PCI_SCR_RX_TAR_ABRT	(0x1 << 28)
+#define PCI_SCR_SIG_MST_ABRT	(0x1 << 29)
+#define PCI_SCR_SIG_SERR	(0x1 << 30)
+#define PCI_SCR_PAR_ERR		(0x1 << 31)
+
+/* bitmasks for IOC3_KM_CSR */
+#define KM_CSR_K_WRT_PEND 0x00000001	/* kbd port xmitting or resetting */
+#define KM_CSR_M_WRT_PEND 0x00000002	/* mouse port xmitting or resetting */
+#define KM_CSR_K_LCB	  0x00000004	/* Line Cntrl Bit for last KBD write */
+#define KM_CSR_M_LCB	  0x00000008	/* same for mouse */
+#define KM_CSR_K_DATA	  0x00000010	/* state of kbd data line */
+#define KM_CSR_K_CLK	  0x00000020	/* state of kbd clock line */
+#define KM_CSR_K_PULL_DATA 0x00000040	/* pull kbd data line low */
+#define KM_CSR_K_PULL_CLK 0x00000080	/* pull kbd clock line low */
+#define KM_CSR_M_DATA	  0x00000100	/* state of ms data line */
+#define KM_CSR_M_CLK	  0x00000200	/* state of ms clock line */
+#define KM_CSR_M_PULL_DATA 0x00000400	/* pull ms data line low */
+#define KM_CSR_M_PULL_CLK 0x00000800	/* pull ms clock line low */
+#define KM_CSR_EMM_MODE	  0x00001000	/* emulation mode */
+#define KM_CSR_SIM_MODE	  0x00002000	/* clock X8 */
+#define KM_CSR_K_SM_IDLE  0x00004000	/* Keyboard is idle */
+#define KM_CSR_M_SM_IDLE  0x00008000	/* Mouse is idle */
+#define KM_CSR_K_TO	  0x00010000	/* Keyboard trying to send/receive */
+#define KM_CSR_M_TO	  0x00020000	/* Mouse trying to send/receive */
+#define KM_CSR_K_TO_EN	  0x00040000	/* KM_CSR_K_TO + KM_CSR_K_TO_EN = cause
+					   SIO_IR to assert */
+#define KM_CSR_M_TO_EN	  0x00080000	/* KM_CSR_M_TO + KM_CSR_M_TO_EN = cause
+					   SIO_IR to assert */
+#define KM_CSR_K_CLAMP_ONE	0x00100000	/* Pull K_CLK low after rec. one char */
+#define KM_CSR_M_CLAMP_ONE	0x00200000	/* Pull M_CLK low after rec. one char */
+#define KM_CSR_K_CLAMP_THREE	0x00400000	/* Pull K_CLK low after rec. three chars */
+#define KM_CSR_M_CLAMP_THREE	0x00800000	/* Pull M_CLK low after rec. three char */
+
+/* bitmasks for IOC3_K_RD and IOC3_M_RD */
+#define KM_RD_DATA_2	0x000000ff	/* 3rd char recvd since last read */
+#define KM_RD_DATA_2_SHIFT 0
+#define KM_RD_DATA_1	0x0000ff00	/* 2nd char recvd since last read */
+#define KM_RD_DATA_1_SHIFT 8
+#define KM_RD_DATA_0	0x00ff0000	/* 1st char recvd since last read */
+#define KM_RD_DATA_0_SHIFT 16
+#define KM_RD_FRAME_ERR_2 0x01000000	/*  framing or parity error in byte 2 */
+#define KM_RD_FRAME_ERR_1 0x02000000	/* same for byte 1 */
+#define KM_RD_FRAME_ERR_0 0x04000000	/* same for byte 0 */
+
+#define KM_RD_KBD_MSE	0x08000000	/* 0 if from kbd, 1 if from mouse */
+#define KM_RD_OFLO	0x10000000	/* 4th char recvd before this read */
+#define KM_RD_VALID_2	0x20000000	/* DATA_2 valid */
+#define KM_RD_VALID_1	0x40000000	/* DATA_1 valid */
+#define KM_RD_VALID_0	0x80000000	/* DATA_0 valid */
+#define KM_RD_VALID_ALL (KM_RD_VALID_0|KM_RD_VALID_1|KM_RD_VALID_2)
+
+/* bitmasks for IOC3_K_WD & IOC3_M_WD */
+#define KM_WD_WRT_DATA	0x000000ff	/* write to keyboard/mouse port */
+#define KM_WD_WRT_DATA_SHIFT 0
+
+/* bitmasks for serial RX status byte */
+#define RXSB_OVERRUN	0x01	/* char(s) lost */
+#define RXSB_PAR_ERR	0x02	/* parity error */
+#define RXSB_FRAME_ERR	0x04	/* framing error */
+#define RXSB_BREAK	0x08	/* break character */
+#define RXSB_CTS	0x10	/* state of CTS */
+#define RXSB_DCD	0x20	/* state of DCD */
+#define RXSB_MODEM_VALID 0x40	/* DCD, CTS and OVERRUN are valid */
+#define RXSB_DATA_VALID 0x80	/* data byte, FRAME_ERR PAR_ERR & BREAK valid */
+
+/* bitmasks for serial TX control byte */
+#define TXCB_INT_WHEN_DONE 0x20 /* interrupt after this byte is sent */
+#define TXCB_INVALID	0x00	/* byte is invalid */
+#define TXCB_VALID	0x40	/* byte is valid */
+#define TXCB_MCR	0x80	/* data<7:0> to modem control register */
+#define TXCB_DELAY	0xc0	/* delay data<7:0> mSec */
+
+/* bitmasks for IOC3_SBBR_L */
+#define SBBR_L_SIZE	0x00000001	/* 0 == 1KB rings, 1 == 4KB rings */
+#define SBBR_L_BASE	0xfffff000	/* lower serial ring base addr */
+
+/* bitmasks for IOC3_SSCR_<A:B> */
+#define SSCR_RX_THRESHOLD 0x000001ff	/* hiwater mark */
+#define SSCR_TX_TIMER_BUSY 0x00010000	/* TX timer in progress */
+#define SSCR_HFC_EN	0x00020000	/* hardware flow control enabled */
+#define SSCR_RX_RING_DCD 0x00040000	/* post RX record on delta-DCD */
+#define SSCR_RX_RING_CTS 0x00080000	/* post RX record on delta-CTS */
+#define SSCR_HIGH_SPD	0x00100000	/* 4X speed */
+#define SSCR_DIAG	0x00200000	/* bypass clock divider for sim */
+#define SSCR_RX_DRAIN	0x08000000	/* drain RX buffer to memory */
+#define SSCR_DMA_EN	0x10000000	/* enable ring buffer DMA */
+#define SSCR_DMA_PAUSE	0x20000000	/* pause DMA */
+#define SSCR_PAUSE_STATE 0x40000000	/* sets when PAUSE takes effect */
+#define SSCR_RESET	0x80000000	/* reset DMA channels */
+
+/* all producer/comsumer pointers are the same bitfield */
+#define PROD_CONS_PTR_4K 0x00000ff8	/* for 4K buffers */
+#define PROD_CONS_PTR_1K 0x000003f8	/* for 1K buffers */
+#define PROD_CONS_PTR_OFF 3
+
+/* bitmasks for IOC3_SRCIR_<A:B> */
+#define SRCIR_ARM	0x80000000	/* arm RX timer */
+
+/* bitmasks for IOC3_SRPIR_<A:B> */
+#define SRPIR_BYTE_CNT	0x07000000	/* bytes in packer */
+#define SRPIR_BYTE_CNT_SHIFT 24
+
+/* bitmasks for IOC3_STCIR_<A:B> */
+#define STCIR_BYTE_CNT	0x0f000000	/* bytes in unpacker */
+#define STCIR_BYTE_CNT_SHIFT 24
+
+/* bitmasks for IOC3_SHADOW_<A:B> */
+#define SHADOW_DR	0x00000001	/* data ready */
+#define SHADOW_OE	0x00000002	/* overrun error */
+#define SHADOW_PE	0x00000004	/* parity error */
+#define SHADOW_FE	0x00000008	/* framing error */
+#define SHADOW_BI	0x00000010	/* break interrupt */
+#define SHADOW_THRE	0x00000020	/* transmit holding register empty */
+#define SHADOW_TEMT	0x00000040	/* transmit shift register empty */
+#define SHADOW_RFCE	0x00000080	/* char in RX fifo has an error */
+#define SHADOW_DCTS	0x00010000	/* delta clear to send */
+#define SHADOW_DDCD	0x00080000	/* delta data carrier detect */
+#define SHADOW_CTS	0x00100000	/* clear to send */
+#define SHADOW_DCD	0x00800000	/* data carrier detect */
+#define SHADOW_DTR	0x01000000	/* data terminal ready */
+#define SHADOW_RTS	0x02000000	/* request to send */
+#define SHADOW_OUT1	0x04000000	/* 16550 OUT1 bit */
+#define SHADOW_OUT2	0x08000000	/* 16550 OUT2 bit */
+#define SHADOW_LOOP	0x10000000	/* loopback enabled */
+
+/* bitmasks for IOC3_SRTR_<A:B> */
+#define SRTR_CNT	0x00000fff	/* reload value for RX timer */
+#define SRTR_CNT_VAL	0x0fff0000	/* current value of RX timer */
+#define SRTR_CNT_VAL_SHIFT 16
+#define SRTR_HZ		16000	/* SRTR clock frequency */
+
+/* bitmasks for IOC3_SIO_IR, IOC3_SIO_IEC and IOC3_SIO_IES  */
+#define SIO_IR_SA_TX_MT		0x00000001	/* Serial port A TX empty */
+#define SIO_IR_SA_RX_FULL	0x00000002	/* port A RX buf full */
+#define SIO_IR_SA_RX_HIGH	0x00000004	/* port A RX hiwat */
+#define SIO_IR_SA_RX_TIMER	0x00000008	/* port A RX timeout */
+#define SIO_IR_SA_DELTA_DCD	0x00000010	/* port A delta DCD */
+#define SIO_IR_SA_DELTA_CTS	0x00000020	/* port A delta CTS */
+#define SIO_IR_SA_INT		0x00000040	/* port A pass-thru intr */
+#define SIO_IR_SA_TX_EXPLICIT	0x00000080	/* port A explicit TX thru */
+#define SIO_IR_SA_MEMERR	0x00000100	/* port A PCI error */
+#define SIO_IR_SB_TX_MT		0x00000200	/* */
+#define SIO_IR_SB_RX_FULL	0x00000400	/* */
+#define SIO_IR_SB_RX_HIGH	0x00000800	/* */
+#define SIO_IR_SB_RX_TIMER	0x00001000	/* */
+#define SIO_IR_SB_DELTA_DCD	0x00002000	/* */
+#define SIO_IR_SB_DELTA_CTS	0x00004000	/* */
+#define SIO_IR_SB_INT		0x00008000	/* */
+#define SIO_IR_SB_TX_EXPLICIT	0x00010000	/* */
+#define SIO_IR_SB_MEMERR	0x00020000	/* */
+#define SIO_IR_PP_INT		0x00040000	/* P port pass-thru intr */
+#define SIO_IR_PP_INTA		0x00080000	/* PP context A thru */
+#define SIO_IR_PP_INTB		0x00100000	/* PP context B thru */
+#define SIO_IR_PP_MEMERR	0x00200000	/* PP PCI error */
+#define SIO_IR_KBD_INT		0x00400000	/* kbd/mouse intr */
+#define SIO_IR_RT_INT		0x08000000	/* RT output pulse */
+#define SIO_IR_GEN_INT1		0x10000000	/* RT input pulse */
+#define SIO_IR_GEN_INT_SHIFT	28
+
+/* per device interrupt masks */
+#define SIO_IR_SA		(SIO_IR_SA_TX_MT | SIO_IR_SA_RX_FULL | \
+				 SIO_IR_SA_RX_HIGH | SIO_IR_SA_RX_TIMER | \
+				 SIO_IR_SA_DELTA_DCD | SIO_IR_SA_DELTA_CTS | \
+				 SIO_IR_SA_INT | SIO_IR_SA_TX_EXPLICIT | \
+				 SIO_IR_SA_MEMERR)
+#define SIO_IR_SB		(SIO_IR_SB_TX_MT | SIO_IR_SB_RX_FULL | \
+				 SIO_IR_SB_RX_HIGH | SIO_IR_SB_RX_TIMER | \
+				 SIO_IR_SB_DELTA_DCD | SIO_IR_SB_DELTA_CTS | \
+				 SIO_IR_SB_INT | SIO_IR_SB_TX_EXPLICIT | \
+				 SIO_IR_SB_MEMERR)
+#define SIO_IR_PP		(SIO_IR_PP_INT | SIO_IR_PP_INTA | \
+				 SIO_IR_PP_INTB | SIO_IR_PP_MEMERR)
+#define SIO_IR_RT		(SIO_IR_RT_INT | SIO_IR_GEN_INT1)
+
+/* macro to load pending interrupts */
+#define IOC3_PENDING_INTRS(mem) (PCI_INW(&((mem)->sio_ir)) & \
+				 PCI_INW(&((mem)->sio_ies_ro)))
+
+/* bitmasks for SIO_CR */
+#define SIO_CR_SIO_RESET	0x00000001	/* reset the SIO */
+#define SIO_CR_SER_A_BASE	0x000000fe	/* DMA poll addr port A */
+#define SIO_CR_SER_A_BASE_SHIFT 1
+#define SIO_CR_SER_B_BASE	0x00007f00	/* DMA poll addr port B */
+#define SIO_CR_SER_B_BASE_SHIFT 8
+#define SIO_SR_CMD_PULSE	0x00078000	/* byte bus strobe length */
+#define SIO_CR_CMD_PULSE_SHIFT	15
+#define SIO_CR_ARB_DIAG		0x00380000	/* cur !enet PCI requet (ro) */
+#define SIO_CR_ARB_DIAG_TXA	0x00000000
+#define SIO_CR_ARB_DIAG_RXA	0x00080000
+#define SIO_CR_ARB_DIAG_TXB	0x00100000
+#define SIO_CR_ARB_DIAG_RXB	0x00180000
+#define SIO_CR_ARB_DIAG_PP	0x00200000
+#define SIO_CR_ARB_DIAG_IDLE	0x00400000	/* 0 -> active request (ro) */
+
+/* bitmasks for INT_OUT */
+#define INT_OUT_COUNT	0x0000ffff	/* pulse interval timer */
+#define INT_OUT_MODE	0x00070000	/* mode mask */
+#define INT_OUT_MODE_0	0x00000000	/* set output to 0 */
+#define INT_OUT_MODE_1	0x00040000	/* set output to 1 */
+#define INT_OUT_MODE_1PULSE 0x00050000	/* send 1 pulse */
+#define INT_OUT_MODE_PULSES 0x00060000	/* send 1 pulse every interval */
+#define INT_OUT_MODE_SQW 0x00070000	/* toggle output every interval */
+#define INT_OUT_DIAG	0x40000000	/* diag mode */
+#define INT_OUT_INT_OUT 0x80000000	/* current state of INT_OUT */
+
+/* time constants for INT_OUT */
+#define INT_OUT_NS_PER_TICK (30 * 260)	/* 30 ns PCI clock, divisor=260 */
+#define INT_OUT_TICKS_PER_PULSE 3	/* outgoing pulse lasts 3 ticks */
+#define INT_OUT_US_TO_COUNT(x)		/* convert uS to a count value */ \
+	(((x) * 10 + INT_OUT_NS_PER_TICK / 200) *	\
+	 100 / INT_OUT_NS_PER_TICK - 1)
+#define INT_OUT_COUNT_TO_US(x)		/* convert count value to uS */ \
+	(((x) + 1) * INT_OUT_NS_PER_TICK / 1000)
+#define INT_OUT_MIN_TICKS 3	/* min period is width of pulse in "ticks" */
+#define INT_OUT_MAX_TICKS INT_OUT_COUNT		/* largest possible count */
+
+/* bitmasks for GPCR */
+#define GPCR_DIR	0x000000ff	/* tristate pin input or output */
+#define GPCR_DIR_PIN(x) (1<<(x))	/* access one of the DIR bits */
+#define GPCR_EDGE	0x000f0000	/* extint edge or level sensitive */
+#define GPCR_EDGE_PIN(x) (1<<((x)+15))	/* access one of the EDGE bits */
+
+/* values for GPCR */
+#define GPCR_INT_OUT_EN 0x00100000	/* enable INT_OUT to pin 0 */
+#define GPCR_MLAN_EN	0x00200000	/* enable MCR to pin 8 */
+#define GPCR_DIR_SERA_XCVR 0x00000080	/* Port A Transceiver select enable */
+#define GPCR_DIR_SERB_XCVR 0x00000040	/* Port B Transceiver select enable */
+#define GPCR_DIR_PHY_RST   0x00000020	/* ethernet PHY reset enable */
+
+/* defs for some of the generic I/O pins */
+#define GPCR_PHY_RESET		0x20	/* pin is output to PHY reset */
+#define GPCR_UARTB_MODESEL	0x40	/* pin is output to port B mode sel */
+#define GPCR_UARTA_MODESEL	0x80	/* pin is output to port A mode sel */
+
+#define GPPR_PHY_RESET_PIN	5	/* GIO pin controlling phy reset */
+#define GPPR_UARTB_MODESEL_PIN	6	/* GIO pin controlling uart b mode select */
+#define GPPR_UARTA_MODESEL_PIN	7	/* GIO pin controlling uart a mode select */
+
+#define EMCR_DUPLEX		0x00000001
+#define EMCR_PROMISC		0x00000002
+#define EMCR_PADEN		0x00000004
+#define EMCR_RXOFF_MASK		0x000001f8
+#define EMCR_RXOFF_SHIFT	3
+#define EMCR_RAMPAR		0x00000200
+#define EMCR_BADPAR		0x00000800
+#define EMCR_BUFSIZ		0x00001000
+#define EMCR_TXDMAEN		0x00002000
+#define EMCR_TXEN		0x00004000
+#define EMCR_RXDMAEN		0x00008000
+#define EMCR_RXEN		0x00010000
+#define EMCR_LOOPBACK		0x00020000
+#define EMCR_ARB_DIAG		0x001c0000
+#define EMCR_ARB_DIAG_IDLE	0x00200000
+#define EMCR_RST		0x80000000
+
+#define EISR_RXTIMERINT		0x00000001
+#define EISR_RXTHRESHINT	0x00000002
+#define EISR_RXOFLO		0x00000004
+#define EISR_RXBUFOFLO		0x00000008
+#define EISR_RXMEMERR		0x00000010
+#define EISR_RXPARERR		0x00000020
+#define EISR_TXEMPTY		0x00010000
+#define EISR_TXRTRY		0x00020000
+#define EISR_TXEXDEF		0x00040000
+#define EISR_TXLCOL		0x00080000
+#define EISR_TXGIANT		0x00100000
+#define EISR_TXBUFUFLO		0x00200000
+#define EISR_TXEXPLICIT		0x00400000
+#define EISR_TXCOLLWRAP		0x00800000
+#define EISR_TXDEFERWRAP	0x01000000
+#define EISR_TXMEMERR		0x02000000
+#define EISR_TXPARERR		0x04000000
+
+#define ERCSR_THRESH_MASK	0x000001ff	/* enet RX threshold */
+#define ERCSR_RX_TMR		0x40000000	/* simulation only */
+#define ERCSR_DIAG_OFLO		0x80000000	/* simulation only */
+
+#define ERBR_ALIGNMENT		4096
+#define ERBR_L_RXRINGBASE_MASK	0xfffff000
+
+#define ERBAR_BARRIER_BIT	0x0100
+#define ERBAR_RXBARR_MASK	0xffff0000
+#define ERBAR_RXBARR_SHIFT	16
+
+#define ERCIR_RXCONSUME_MASK	0x00000fff
+
+#define ERPIR_RXPRODUCE_MASK	0x00000fff
+#define ERPIR_ARM		0x80000000
+
+#define ERTR_CNT_MASK		0x000007ff
+
+#define ETCSR_IPGT_MASK		0x0000007f
+#define ETCSR_IPGR1_MASK	0x00007f00
+#define ETCSR_IPGR1_SHIFT	8
+#define ETCSR_IPGR2_MASK	0x007f0000
+#define ETCSR_IPGR2_SHIFT	16
+#define ETCSR_NOTXCLK		0x80000000
+
+#define ETCDC_COLLCNT_MASK	0x0000ffff
+#define ETCDC_DEFERCNT_MASK	0xffff0000
+#define ETCDC_DEFERCNT_SHIFT	16
+
+#define ETBR_ALIGNMENT		(64*1024)
+#define ETBR_L_RINGSZ_MASK	0x00000001
+#define ETBR_L_RINGSZ128	0
+#define ETBR_L_RINGSZ512	1
+#define ETBR_L_TXRINGBASE_MASK	0xffffc000
+
+#define ETCIR_TXCONSUME_MASK	0x0000ffff
+#define ETCIR_IDLE		0x80000000
+
+#define ETPIR_TXPRODUCE_MASK	0x0000ffff
+
+#define EBIR_TXBUFPROD_MASK	0x0000001f
+#define EBIR_TXBUFCONS_MASK	0x00001f00
+#define EBIR_TXBUFCONS_SHIFT	8
+#define EBIR_RXBUFPROD_MASK	0x007fc000
+#define EBIR_RXBUFPROD_SHIFT	14
+#define EBIR_RXBUFCONS_MASK	0xff800000
+#define EBIR_RXBUFCONS_SHIFT	23
+
+#define MICR_REGADDR_MASK	0x0000001f
+#define MICR_PHYADDR_MASK	0x000003e0
+#define MICR_PHYADDR_SHIFT	5
+#define MICR_READTRIG		0x00000400
+#define MICR_BUSY		0x00000800
+
+#define MIDR_DATA_MASK		0x0000ffff
+
+#define ERXBUF_IPCKSUM_MASK	0x0000ffff
+#define ERXBUF_BYTECNT_MASK	0x07ff0000
+#define ERXBUF_BYTECNT_SHIFT	16
+#define ERXBUF_V		0x80000000
+
+#define ERXBUF_CRCERR		0x00000001	/* aka RSV15 */
+#define ERXBUF_FRAMERR		0x00000002	/* aka RSV14 */
+#define ERXBUF_CODERR		0x00000004	/* aka RSV13 */
+#define ERXBUF_INVPREAMB	0x00000008	/* aka RSV18 */
+#define ERXBUF_LOLEN		0x00007000	/* aka RSV2_0 */
+#define ERXBUF_HILEN		0x03ff0000	/* aka RSV12_3 */
+#define ERXBUF_MULTICAST	0x04000000	/* aka RSV16 */
+#define ERXBUF_BROADCAST	0x08000000	/* aka RSV17 */
+#define ERXBUF_LONGEVENT	0x10000000	/* aka RSV19 */
+#define ERXBUF_BADPKT		0x20000000	/* aka RSV20 */
+#define ERXBUF_GOODPKT		0x40000000	/* aka RSV21 */
+#define ERXBUF_CARRIER		0x80000000	/* aka RSV22 */
+
+#define ETXD_BYTECNT_MASK	0x000007ff	/* total byte count */
+#define ETXD_INTWHENDONE	0x00001000	/* intr when done */
+#define ETXD_D0V		0x00010000	/* data 0 valid */
+#define ETXD_B1V		0x00020000	/* buf 1 valid */
+#define ETXD_B2V		0x00040000	/* buf 2 valid */
+#define ETXD_DOCHECKSUM		0x00080000	/* insert ip cksum */
+#define ETXD_CHKOFF_MASK	0x07f00000	/* cksum byte offset */
+#define ETXD_CHKOFF_SHIFT	20
+
+#define ETXD_D0CNT_MASK		0x0000007f
+#define ETXD_B1CNT_MASK		0x0007ff00
+#define ETXD_B1CNT_SHIFT	8
+#define ETXD_B2CNT_MASK		0x7ff00000
+#define ETXD_B2CNT_SHIFT	20
+
+typedef enum ioc3_subdevs_e {
+    ioc3_subdev_ether,
+    ioc3_subdev_generic,
+    ioc3_subdev_nic,
+    ioc3_subdev_kbms,
+    ioc3_subdev_ttya,
+    ioc3_subdev_ttyb,
+    ioc3_subdev_ecpp,
+    ioc3_subdev_rt,
+    ioc3_nsubdevs
+} ioc3_subdev_t;
+
+/* subdevice disable bits,
+ * from the standard INFO_LBL_SUBDEVS
+ */
+#define IOC3_SDB_ETHER		(1<<ioc3_subdev_ether)
+#define IOC3_SDB_GENERIC	(1<<ioc3_subdev_generic)
+#define IOC3_SDB_NIC		(1<<ioc3_subdev_nic)
+#define IOC3_SDB_KBMS		(1<<ioc3_subdev_kbms)
+#define IOC3_SDB_TTYA		(1<<ioc3_subdev_ttya)
+#define IOC3_SDB_TTYB		(1<<ioc3_subdev_ttyb)
+#define IOC3_SDB_ECPP		(1<<ioc3_subdev_ecpp)
+#define IOC3_SDB_RT		(1<<ioc3_subdev_rt)
+
+#define IOC3_ALL_SUBDEVS	((1<<ioc3_nsubdevs)-1)
+
+#define IOC3_SDB_SERIAL		(IOC3_SDB_TTYA|IOC3_SDB_TTYB)
+
+#define IOC3_STD_SUBDEVS	IOC3_ALL_SUBDEVS
+
+#define IOC3_INTA_SUBDEVS	IOC3_SDB_ETHER
+#define IOC3_INTB_SUBDEVS	(IOC3_SDB_GENERIC|IOC3_SDB_KBMS|IOC3_SDB_SERIAL|IOC3_SDB_ECPP|IOC3_SDB_RT)
+
+#endif /* IOC3_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/ioctl.h linux/include/asm-mips64/ioctl.h
--- v2.3.47/linux/include/asm-mips64/ioctl.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/ioctl.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,89 @@
+/* $Id: ioctl.h,v 1.1 1999/08/18 23:37:51 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_IOCTL_H
+#define _ASM_IOCTL_H
+
+/*
+ * The original linux ioctl numbering scheme was just a general
+ * "anything goes" setup, where more or less random numbers were
+ * assigned.  Sorry, I was clueless when I started out on this.
+ *
+ * On the alpha, we'll try to clean it up a bit, using a more sane
+ * ioctl numbering, and also trying to be compatible with OSF/1 in
+ * the process. I'd like to clean it up for the i386 as well, but
+ * it's so painful recognizing both the new and the old numbers..
+ *
+ * The same applies for for the MIPS ABI; in fact even the macros
+ * from Linux/Alpha fit almost perfectly.
+ */
+
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	13
+#define _IOC_DIRBITS	3
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * We to additionally limit parameters to a maximum 255 bytes.
+ */
+#define _IOC_SLMASK	0xff
+
+/*
+ * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit.
+ * And this turns out useful to catch old ioctl numbers in header
+ * files for us.
+ */
+#define _IOC_NONE	1U
+#define _IOC_READ	2U
+#define _IOC_WRITE	4U
+
+/*
+ * The following are included for compatibility
+ */
+#define _IOC_VOID	0x20000000
+#define _IOC_OUT	0x40000000
+#define _IOC_IN		0x80000000
+#define _IOC_INOUT	(IOC_IN|IOC_OUT)
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 (((size) & _IOC_SLMASK) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode them.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _ASM_IOCTL_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/ioctls.h linux/include/asm-mips64/ioctls.h
--- v2.3.47/linux/include/asm-mips64/ioctls.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/ioctls.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,118 @@
+/* $Id: ioctls.h,v 1.1 1999/08/18 23:37:51 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_IOCTLS_H
+#define _ASM_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+#if defined(__USE_MISC) || defined (__KERNEL__)
+#define tIOC		('t' << 8)
+#endif
+
+#define TCGETA		0x5401
+#define TCSETA		0x5402
+#define TCSETAW		0x5403
+#define TCSETAF		0x5404
+
+#define TCSBRK		0x5405
+#define TCXONC		0x5406
+#define TCFLSH		0x5407
+
+#define TCGETS		0x540d
+#define TCSETS		0x540e
+#define TCSETSW		0x540f
+#define TCSETSF		0x5410
+
+#define TIOCEXCL	0x740d		/* set exclusive use of tty */
+#define TIOCNXCL	0x740e		/* reset exclusive use of tty */
+#define TIOCOUTQ	0x7472		/* output queue size */
+#define TIOCSTI		0x5472		/* simulate terminal input */
+#define TIOCMGET	0x741d		/* get all modem bits */
+#define TIOCMBIS	0x741b		/* bis modem bits */
+#define TIOCMBIC	0x741c		/* bic modem bits */
+#define TIOCMSET	0x741a		/* set all modem bits */
+#define TIOCPKT		0x5470		/* pty: set/clear packet mode */
+#define		TIOCPKT_DATA		0x00	/* data packet */
+#define		TIOCPKT_FLUSHREAD	0x01	/* flush packet */
+#define		TIOCPKT_FLUSHWRITE	0x02	/* flush packet */
+#define		TIOCPKT_STOP		0x04	/* stop output */
+#define		TIOCPKT_START		0x08	/* start output */
+#define		TIOCPKT_NOSTOP		0x10	/* no more ^S, ^Q */
+#define		TIOCPKT_DOSTOP		0x20	/* now do ^S ^Q */
+#if 0
+#define		TIOCPKT_IOCTL		0x40	/* state change of pty driver */
+#endif
+#define TIOCSWINSZ	_IOW('t', 103, struct winsize)	/* set window size */
+#define TIOCGWINSZ	_IOR('t', 104, struct winsize)	/* get window size */
+#define TIOCNOTTY	0x5471		/* void tty association */
+#define TIOCSETD	(tIOC | 1)
+#define TIOCGETD	(tIOC | 0)
+
+#define FIOCLEX		0x6601
+#define FIONCLEX	0x6602		/* these numbers need to be adjusted. */
+#define FIOASYNC	0x667d
+#define FIONBIO		0x667e
+
+#if defined(__USE_MISC) || defined (__KERNEL__)
+#define TIOCGLTC	(tIOC | 116)		/* get special local chars */
+#define TIOCSLTC	(tIOC | 117)		/* set special local chars */
+#endif
+#define TIOCSPGRP	_IOW('t', 118, int)	/* set pgrp of tty */
+#define TIOCGPGRP	_IOR('t', 119, int)	/* get pgrp of tty */
+#define TIOCCONS	_IOW('t', 120, int)	/* become virtual console */
+
+#define FIONREAD	0x467f
+#define TIOCINQ		FIONREAD
+
+#if defined(__USE_MISC) || defined (__KERNEL__)
+#define TIOCGETP        (tIOC | 8)
+#define TIOCSETP        (tIOC | 9)
+#define TIOCSETN        (tIOC | 10)		/* TIOCSETP wo flush */
+#endif
+ 
+#if 0
+#define	TIOCSETA	_IOW('t', 20, struct termios) /* set termios struct */
+#define	TIOCSETAW	_IOW('t', 21, struct termios) /* drain output, set */
+#define	TIOCSETAF	_IOW('t', 22, struct termios) /* drn out, fls in, set */
+#define	TIOCGETD	_IOR('t', 26, int)	/* get line discipline */
+#define	TIOCSETD	_IOW('t', 27, int)	/* set line discipline */
+						/* 127-124 compat */
+#endif
+
+/* I hope the range from 0x5480 on is free ... */
+#define TIOCSCTTY	0x5480		/* become controlling tty */
+#define TIOCGSOFTCAR	0x5481
+#define TIOCSSOFTCAR	0x5482
+#define TIOCLINUX	0x5483
+#define TIOCGSERIAL	0x5484
+#define TIOCSSERIAL	0x5485
+
+#define TCSBRKP		0x5486	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5487  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x7416  /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define TIOCSERCONFIG	0x5488
+#define TIOCSERGWILD	0x5489
+#define TIOCSERSWILD	0x548a
+#define TIOCGLCKTRMIOS	0x548b
+#define TIOCSLCKTRMIOS	0x548c
+#define TIOCSERGSTRUCT	0x548d /* For debugging only */
+#define TIOCSERGETLSR   0x548e /* Get line status register */
+#define TIOCSERGETMULTI 0x548f /* Get multiport config  */
+#define TIOCSERSETMULTI 0x5490 /* Set multiport config */
+#define TIOCMIWAIT      0x5491 /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT     0x5492 /* read serial port inline interrupt counts */
+#define TIOCGHAYESESP	0x5493 /* Get Hayes ESP configuration */
+#define TIOCSHAYESESP	0x5494 /* Set Hayes ESP configuration */
+
+#endif /* _ASM_IOCTLS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/ipc.h linux/include/asm-mips64/ipc.h
--- v2.3.47/linux/include/asm-mips64/ipc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/ipc.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,32 @@
+#ifndef _ASM_IPC_H
+#define _ASM_IPC_H
+
+/* 
+ * These are used to wrap system calls on MIPS32.
+ *
+ * See arch/mips/kernel/sysmips.c for ugly details..
+ * FIXME: split up into ordinary syscalls ...
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC		25
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif /* _ASM_IPC_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/ipcbuf.h linux/include/asm-mips64/ipcbuf.h
--- v2.3.47/linux/include/asm-mips64/ipcbuf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/ipcbuf.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,28 @@
+#ifndef _ASM_IPCBUF_H
+#define _ASM_IPCBUF_H
+
+/* 
+ * The ipc64_perm structure for alpha architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit seq
+ * - 2 miscellaneous 64-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t	key;
+	__kernel_uid_t	uid;
+	__kernel_gid_t	gid;
+	__kernel_uid_t	cuid;
+	__kernel_gid_t	cgid;
+	__kernel_mode_t	mode; 
+	unsigned short	seq;
+	unsigned short	__pad1;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+};
+
+#endif /* _ASM_IPCBUF_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/irq.h linux/include/asm-mips64/irq.h
--- v2.3.47/linux/include/asm-mips64/irq.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/irq.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,28 @@
+/* $Id: irq.h,v 1.1 1999/08/19 22:56:34 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
+ * Copyright (C) 1995 - 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_IRQ_H
+#define _ASM_IRQ_H
+
+#define NR_IRQS 64
+
+#define TIMER_IRQ 0
+
+extern int (*irq_cannonicalize)(int irq);
+
+struct irqaction;
+extern int i8259_setup_irq(int irq, struct irqaction * new);
+extern void disable_irq(unsigned int);
+extern void enable_irq(unsigned int);
+
+/* Machine specific interrupt initialization  */
+extern void (*irq_setup)(void);
+
+#endif /* _ASM_IRQ_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/keyboard.h linux/include/asm-mips64/keyboard.h
--- v2.3.47/linux/include/asm-mips64/keyboard.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/keyboard.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,75 @@
+/* $Id: keyboard.h,v 1.1 1999/08/19 22:56:34 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999 Ralf Baechle
+ */
+#ifndef _ASM_KEYBOARD_H
+#define _ASM_KEYBOARD_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <asm/bootinfo.h>
+
+#define DISABLE_KBD_DURING_INTERRUPTS 0
+
+extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int pckbd_getkeycode(unsigned int scancode);
+extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+			   char raw_mode);
+extern char pckbd_unexpected_up(unsigned char keycode);
+extern void pckbd_leds(unsigned char leds);
+extern void pckbd_init_hw(void);
+extern unsigned char pckbd_sysrq_xlate[128];
+
+#define kbd_setkeycode		pckbd_setkeycode
+#define kbd_getkeycode		pckbd_getkeycode
+#define kbd_translate		pckbd_translate
+#define kbd_unexpected_up	pckbd_unexpected_up
+#define kbd_leds		pckbd_leds
+#define kbd_init_hw		pckbd_init_hw
+#define kbd_sysrq_xlate         pckbd_sysrq_xlate
+
+#define SYSRQ_KEY 0x54
+
+/* Some stoneage hardware needs delays after some operations.  */
+#define kbd_pause() do { } while(0)
+
+struct kbd_ops {
+	/* Keyboard driver resource allocation  */
+	void (*kbd_request_region)(void);
+	int (*kbd_request_irq)(void (*handler)(int, void *, struct pt_regs *));
+
+	/* PSaux driver resource managment  */
+	int (*aux_request_irq)(void (*handler)(int, void *, struct pt_regs *));
+	void (*aux_free_irq)(void);
+
+	/* Methods to access the keyboard processor's I/O registers  */
+	unsigned char (*kbd_read_input)(void);
+	void (*kbd_write_output)(unsigned char val);
+	void (*kbd_write_command)(unsigned char val);
+	unsigned char (*kbd_read_status)(void);
+};
+
+extern struct kbd_ops *kbd_ops;
+
+/* Do the actual calls via kbd_ops vector  */
+#define kbd_request_region() kbd_ops->kbd_request_region()
+#define kbd_request_irq(handler) kbd_ops->kbd_request_irq(handler)
+
+#define aux_request_irq(hand, dev_id) kbd_ops->aux_request_irq(hand)
+#define aux_free_irq(dev_id) kbd_ops->aux_free_irq()
+
+#define kbd_read_input() kbd_ops->kbd_read_input()
+#define kbd_write_output(val) kbd_ops->kbd_write_output(val)
+#define kbd_write_command(val) kbd_ops->kbd_write_command(val)
+#define kbd_read_status() kbd_ops->kbd_read_status()
+
+#endif /* __KERNEL */
+
+#endif /* _ASM_KEYBOARD_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/linux_logo.h linux/include/asm-mips64/linux_logo.h
--- v2.3.47/linux/include/asm-mips64/linux_logo.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/linux_logo.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,941 @@
+/* $Id: linux_logo.h,v 1.1 1999/08/19 22:56:34 ralf Exp $
+ *
+ * include/asm-mips/linux_logo.h: This is a linux logo
+ *                                to be displayed on boot.
+ *
+ * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
+ * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ *
+ * You can put anything here, but:
+ * LINUX_LOGO_COLORS has to be less than 224
+ * image size has to be 80x80
+ * values have to start from 0x20
+ * (i.e. RGB(linux_logo_red[0],
+ *	     linux_logo_green[0],
+ *	     linux_logo_blue[0]) is color 0x20)
+ * BW image has to be 80x80 as well, with MS bit
+ * on the left
+ * Serial_console ascii image can be any size,
+ * but should contain %s to display the version
+ */
+ 
+#include <linux/init.h>
+#include <linux/version.h>
+
+#define linux_logo_banner "Linux/MIPS64 version " UTS_RELEASE
+
+#define LINUX_LOGO_COLORS 212
+
+#ifdef INCLUDE_LINUX_LOGO_DATA
+
+unsigned char linux_logo_red[] __initdata = {
+  0x03, 0x82, 0xE9, 0xBF, 0x42, 0xC9, 0x7E, 0xC0,
+  0xE9, 0xE3, 0xC2, 0x24, 0xA4, 0x65, 0xEC, 0xC4,
+  0x82, 0x9F, 0xF3, 0x12, 0x5F, 0xA0, 0xC2, 0xED,
+  0x3E, 0xD5, 0xDB, 0xA0, 0x1C, 0xF4, 0xEB, 0xA4,
+  0xCD, 0x0A, 0x9A, 0x51, 0xCC, 0xBE, 0xC0, 0xBA,
+  0x74, 0xDC, 0xAA, 0xF6, 0xD3, 0xC5, 0xE6, 0x26,
+  0xC2, 0x83, 0x38, 0xEA, 0x49, 0xB0, 0xED, 0xE5,
+  0xF4, 0x96, 0x96, 0x1B, 0xFA, 0xCC, 0xF2, 0x0F,
+  0xCD, 0xE5, 0xF4, 0xD3, 0x50, 0x7A, 0xB5, 0xDE,
+  0xD5, 0xB6, 0x60, 0x0A, 0x6A, 0xEA, 0xD4, 0xEB,
+  0xC1, 0xCA, 0xEA, 0xEC, 0x2A, 0x96, 0x95, 0xDC,
+  0xE4, 0xCE, 0xEC, 0x1E, 0xDC, 0x8A, 0xD1, 0xF6,
+  0x3C, 0x5E, 0xC6, 0xB4, 0xB2, 0xAC, 0xBA, 0x9E,
+  0x0F, 0x59, 0xBA, 0xFA, 0xCC, 0xBF, 0x82, 0xCE,
+  0xE6, 0x4F, 0xAA, 0x4C, 0xCA, 0x8E, 0x8E, 0xDF,
+  0x2C, 0xB6, 0x3B, 0xDE, 0xCE, 0xEE, 0x46, 0x4A,
+  0x6F, 0x7A, 0x82, 0xE4, 0xAA, 0x88, 0xE2, 0xCE,
+  0xAE, 0xB6, 0x70, 0xC2, 0x9A, 0xDA, 0x35, 0x9E,
+  0x95, 0xC0, 0x7E, 0x8C, 0xC2, 0xB6, 0xCE, 0xB9,
+  0xD5, 0xAA, 0xC1, 0xF4, 0xC7, 0xB6, 0xB6, 0xA3,
+  0xF2, 0x68, 0xDB, 0x76, 0xDC, 0x57, 0xD3, 0xA8,
+  0xC0, 0xEF, 0x46, 0xF4, 0x2F, 0xD7, 0x53, 0x36,
+  0xE6, 0xA7, 0xCA, 0xCB, 0x7E, 0xE4, 0x86, 0x9A,
+  0xCE, 0x94, 0xB4, 0x1D, 0xDA, 0xCE, 0x6C, 0xE6,
+  0x9E, 0xC6, 0xDA, 0x16, 0xFA, 0xAA, 0x56, 0xB6,
+  0xFE, 0x6E, 0xEA, 0xCE, 0xE5, 0xCC, 0xDB, 0xD3,
+  0xED, 0xDC, 0xF4, 0x72
+};
+
+unsigned char linux_logo_green[] __initdata = {
+  0x03, 0x82, 0xC4, 0x83, 0x42, 0xA2, 0x4A, 0xA4,
+  0xE5, 0xA6, 0xC2, 0x24, 0xA4, 0x65, 0xB4, 0x94,
+  0x66, 0x87, 0xB6, 0x12, 0x44, 0x6C, 0x96, 0xD4,
+  0x36, 0x95, 0xB2, 0x92, 0x0E, 0xF4, 0xBC, 0x77,
+  0xA5, 0x0A, 0x92, 0x52, 0xB4, 0x9A, 0x8C, 0xB2,
+  0x74, 0xC2, 0x8E, 0xBD, 0xA2, 0xCA, 0xD2, 0x12,
+  0xB6, 0x61, 0x24, 0xDA, 0x33, 0x79, 0xCB, 0xAC,
+  0xDA, 0x84, 0x7A, 0x1B, 0xFA, 0x8D, 0xBE, 0x06,
+  0x93, 0xBB, 0xBC, 0xAB, 0x44, 0x62, 0x83, 0xDA,
+  0x9B, 0xA2, 0x4C, 0x04, 0x6A, 0xB6, 0xC8, 0xBD,
+  0x8D, 0xB6, 0xAD, 0xEC, 0x2A, 0x68, 0x62, 0x9D,
+  0xC4, 0xC4, 0xB4, 0x13, 0xA3, 0x8A, 0xD2, 0xD6,
+  0x3C, 0x5D, 0x8C, 0x7E, 0x82, 0xAC, 0x96, 0x7E,
+  0x0D, 0x5A, 0xBA, 0xBB, 0xCC, 0xBE, 0x76, 0xB6,
+  0xDE, 0x4E, 0x9A, 0x3C, 0xBE, 0x8E, 0x6E, 0xCB,
+  0x1C, 0xAA, 0x2E, 0xBE, 0xAA, 0xDE, 0x3E, 0x4B,
+  0x4D, 0x7A, 0x54, 0xE4, 0x8E, 0x6E, 0xCA, 0x9B,
+  0x70, 0x9E, 0x5A, 0xAA, 0x9A, 0xBE, 0x34, 0x9E,
+  0x71, 0x9E, 0x7E, 0x5F, 0xAA, 0x8A, 0xBE, 0x91,
+  0xCE, 0x88, 0x92, 0xDB, 0xC6, 0xAB, 0x8A, 0x72,
+  0xE2, 0x44, 0xC3, 0x54, 0xAA, 0x45, 0xBB, 0x92,
+  0xBA, 0xC4, 0x46, 0xCA, 0x2D, 0xD6, 0x3B, 0x1A,
+  0xC2, 0x7E, 0xA6, 0xCB, 0x7A, 0xDC, 0x86, 0x72,
+  0xB6, 0x94, 0xB4, 0x1C, 0xBC, 0xAE, 0x4C, 0xD6,
+  0x62, 0x86, 0xD3, 0x16, 0xF6, 0x7A, 0x55, 0x79,
+  0xFE, 0x6E, 0xC6, 0xC6, 0xAA, 0x93, 0xDC, 0x9D,
+  0xAE, 0xA4, 0xD4, 0x56
+};
+
+unsigned char linux_logo_blue[] __initdata = {
+  0x04, 0x84, 0x10, 0x0C, 0x41, 0x14, 0x04, 0x78,
+  0xC7, 0x0E, 0xC4, 0x24, 0xA4, 0x64, 0x0C, 0x0D,
+  0x17, 0x24, 0x0D, 0x13, 0x11, 0x07, 0x40, 0x22,
+  0x0C, 0x0C, 0x11, 0x78, 0x06, 0xF4, 0x0B, 0x0A,
+  0x47, 0x0B, 0x7C, 0x54, 0x6C, 0x0C, 0x0D, 0x9C,
+  0x73, 0x54, 0x14, 0x0C, 0x0F, 0xC7, 0x94, 0x04,
+  0x94, 0x17, 0x0A, 0x6C, 0x08, 0x0F, 0x14, 0x0B,
+  0x12, 0x68, 0x28, 0x11, 0xFA, 0x0A, 0x34, 0x09,
+  0x0A, 0x2F, 0x15, 0x19, 0x14, 0x3C, 0x06, 0xC4,
+  0x0B, 0x84, 0x24, 0x08, 0x69, 0x38, 0xBC, 0x15,
+  0x1F, 0xA0, 0x0A, 0xEC, 0x2A, 0x0C, 0x0C, 0x0C,
+  0x2C, 0xA0, 0x15, 0x07, 0x0B, 0x8C, 0xD3, 0x10,
+  0x3B, 0x5C, 0x0C, 0x04, 0x3C, 0xAC, 0x54, 0x1C,
+  0x0B, 0x5B, 0xBB, 0x0A, 0xC1, 0xBB, 0x5C, 0x3C,
+  0xBC, 0x4D, 0x74, 0x10, 0x8C, 0x8C, 0x14, 0x91,
+  0x0C, 0x74, 0x17, 0x0C, 0x48, 0x9C, 0x3C, 0x4C,
+  0x09, 0x7C, 0x05, 0xE4, 0x34, 0x38, 0x6C, 0x11,
+  0x08, 0x7C, 0x18, 0x2C, 0x9C, 0x4C, 0x34, 0x9C,
+  0x29, 0x54, 0x7C, 0x0C, 0x78, 0x18, 0x9C, 0x14,
+  0xBA, 0x30, 0x27, 0x31, 0xC2, 0x97, 0x24, 0x09,
+  0xB4, 0x04, 0x87, 0x0C, 0x14, 0x1F, 0x7C, 0x64,
+  0xB0, 0x0F, 0x45, 0x10, 0x2C, 0xD4, 0x0A, 0x04,
+  0x44, 0x1F, 0x2C, 0xCC, 0x7C, 0xD8, 0x84, 0x0C,
+  0x8C, 0x94, 0xB4, 0x1D, 0x20, 0x5C, 0x18, 0xB4,
+  0x04, 0x09, 0xBC, 0x14, 0xF4, 0x08, 0x54, 0x07,
+  0xFC, 0x6C, 0x24, 0xB4, 0x15, 0x18, 0xDB, 0x17,
+  0x17, 0x18, 0x21, 0x24
+};
+
+unsigned char linux_logo[] __initdata = {
+  0xBC, 0xAC, 0x7D, 0x95, 0xAF, 0x85, 0x2C, 0x2C,
+  0xAC, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0x2C, 0xAF,
+  0x7D, 0x48, 0xB2, 0xAC, 0x85, 0xDA, 0xDA, 0x2C,
+  0x7D, 0x48, 0x21, 0x2C, 0x8D, 0x2A, 0x8A, 0xDA,
+  0x85, 0x2C, 0xD9, 0xAC, 0x2C, 0x2C, 0xD9, 0xD9,
+  0xAF, 0x85, 0x85, 0x85, 0x8D, 0xBC, 0x2A, 0x2A,
+  0xBC, 0x8C, 0xBC, 0xAC, 0x7D, 0x95, 0xAF, 0x85,
+  0x2C, 0x2C, 0xAC, 0xD9, 0x95, 0x7D, 0x95, 0xAC,
+  0x2C, 0xAF, 0x7D, 0x48, 0xB2, 0xAC, 0x85, 0xDA,
+  0xDA, 0x2C, 0x7D, 0x48, 0x21, 0x2C, 0x8D, 0x2A,
+  0xAF, 0xA1, 0x48, 0x7D, 0xAF, 0x2C, 0x2C, 0xAC,
+  0xD9, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0xD9, 0x7D,
+  0x48, 0xE9, 0x21, 0xAF, 0xDA, 0xDA, 0x85, 0x2C,
+  0xD9, 0xD9, 0xAC, 0xDA, 0x8A, 0xDA, 0x85, 0x2C,
+  0x2C, 0xAC, 0xD9, 0xAC, 0xAF, 0xAF, 0x2C, 0x2C,
+  0x2C, 0x85, 0x2C, 0x2C, 0x85, 0xDA, 0xDA, 0xDA,
+  0xDA, 0xDA, 0xAF, 0xA1, 0x48, 0x7D, 0xAF, 0x2C,
+  0x2C, 0xAC, 0xD9, 0xD9, 0x95, 0x7D, 0x95, 0xAC,
+  0xD9, 0x7D, 0x48, 0xE9, 0x21, 0xAF, 0xDA, 0xDA,
+  0x85, 0x2C, 0xD9, 0xD9, 0xAC, 0xDA, 0x8A, 0xDA,
+  0x7D, 0x48, 0x48, 0x7D, 0x2C, 0x85, 0x2C, 0xAF,
+  0xD9, 0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0xD9, 0x7D,
+  0xB2, 0x21, 0xD9, 0x85, 0xDA, 0xDA, 0x85, 0x2C,
+  0xAF, 0x2C, 0x2C, 0xDA, 0x85, 0x85, 0x2C, 0x2C,
+  0xAC, 0xD9, 0xD9, 0xAF, 0xDA, 0x85, 0x2C, 0x2C,
+  0x85, 0xDA, 0xDA, 0x85, 0x85, 0xDA, 0x85, 0x85,
+  0x85, 0xAF, 0x7D, 0x48, 0x48, 0x7D, 0x2C, 0x85,
+  0x2C, 0xAF, 0xD9, 0xD9, 0x7D, 0x95, 0xD9, 0xD9,
+  0xD9, 0x7D, 0xB2, 0x21, 0xD9, 0x85, 0xDA, 0xDA,
+  0x85, 0x2C, 0xAF, 0x2C, 0x2C, 0xDA, 0xDA, 0x85,
+  0xA1, 0xE9, 0x48, 0x95, 0x85, 0xDA, 0x85, 0xAF,
+  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0x95, 0x95,
+  0xD9, 0xAC, 0x85, 0x85, 0xDA, 0xDA, 0x85, 0x2C,
+  0xAC, 0xAC, 0x2C, 0x2C, 0x85, 0x2C, 0x2C, 0xAC,
+  0xD9, 0xD9, 0x2C, 0x91, 0x41, 0x20, 0x6B, 0x20,
+  0x6B, 0x20, 0x6B, 0xAE, 0x2C, 0x85, 0x2C, 0x2C,
+  0xAC, 0xD9, 0xA1, 0xE9, 0x48, 0x95, 0x85, 0xDA,
+  0x85, 0xAF, 0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9,
+  0x95, 0x95, 0xD9, 0xAC, 0x85, 0x85, 0xDA, 0xDA,
+  0x85, 0x2C, 0xAC, 0xAC, 0x2C, 0x2C, 0x2C, 0x2C,
+  0xA1, 0xA1, 0xD6, 0xAF, 0xDA, 0xDA, 0x85, 0x2C,
+  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xD9,
+  0x2C, 0x2C, 0xDA, 0xDA, 0xDA, 0x85, 0x2C, 0xD9,
+  0xD9, 0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xAF, 0xAC,
+  0x2C, 0xB2, 0x88, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x6B, 0x80, 0x85, 0x2C,
+  0xD9, 0xD6, 0xA1, 0xA1, 0xD6, 0xAF, 0xDA, 0xDA,
+  0x85, 0x2C, 0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9,
+  0xD9, 0xD9, 0x2C, 0x2C, 0xDA, 0xDA, 0xDA, 0x85,
+  0x2C, 0xD9, 0xD9, 0xD9, 0xD9, 0xAF, 0xAF, 0xAF,
+  0xD6, 0xD6, 0xD9, 0x2C, 0xDA, 0xDA, 0x2C, 0xAC,
+  0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0xD9, 0xAF, 0x2C,
+  0x85, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0xAC, 0xD9,
+  0xD9, 0xD9, 0xAF, 0xAF, 0x2C, 0x2C, 0xAF, 0xDA,
+  0xAE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x41, 0xE3, 0x20, 0x6B, 0x48,
+  0xAC, 0x95, 0xD6, 0xD6, 0xD9, 0x2C, 0xDA, 0xDA,
+  0x2C, 0xAC, 0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0xD9,
+  0xAF, 0x2C, 0x85, 0x85, 0x85, 0x85, 0x2C, 0x2C,
+  0xAC, 0xD9, 0xD9, 0xD9, 0xAF, 0xAF, 0xAF, 0xAF,
+  0xD9, 0xD9, 0xD9, 0x2C, 0x85, 0x85, 0x2C, 0xD9,
+  0x7D, 0x21, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
+  0x85, 0x85, 0x85, 0x85, 0x2C, 0xAF, 0xAF, 0xAC,
+  0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x89,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x74, 0x43, 0x80, 0x41, 0x20,
+  0x9F, 0x2C, 0xD9, 0xD9, 0xD9, 0x2C, 0x85, 0x85,
+  0x2C, 0xD9, 0x7D, 0x21, 0xD6, 0xD9, 0xAF, 0x2C,
+  0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x2C, 0xAF,
+  0xAF, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
+  0xD9, 0x7D, 0xD9, 0xAF, 0x85, 0x85, 0x2C, 0xD9,
+  0xB2, 0x21, 0x7D, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
+  0x85, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC,
+  0xAF, 0xAC, 0xAF, 0xAF, 0xAC, 0xAC, 0x85, 0x41,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0xAE, 0x48, 0x89, 0x74, 0x41,
+  0x6B, 0xD6, 0xD9, 0x7D, 0xD9, 0xAF, 0x85, 0x85,
+  0x2C, 0xD9, 0xB2, 0x21, 0x7D, 0xD9, 0xAF, 0x2C,
+  0x85, 0x85, 0x85, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF,
+  0xAF, 0xAC, 0xAF, 0xAC, 0xAC, 0x2C, 0xAF, 0xAC,
+  0x2C, 0x7D, 0xD9, 0x2C, 0xDA, 0x85, 0x2C, 0x7D,
+  0xB2, 0xD6, 0xD9, 0xAF, 0x85, 0x85, 0x85, 0x85,
+  0xAF, 0xAC, 0xAC, 0xAF, 0xAF, 0xAC, 0xAC, 0xD9,
+  0x95, 0x7D, 0x95, 0x95, 0xD9, 0xD9, 0x48, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x6B, 0xAE, 0xE6, 0x80, 0x2B, 0x88,
+  0x20, 0x33, 0xDA, 0x95, 0xD9, 0x2C, 0xDA, 0x85,
+  0x2C, 0x7D, 0xB2, 0xD6, 0xD9, 0xAF, 0x85, 0x85,
+  0x85, 0x85, 0xAF, 0xAC, 0xAC, 0xAF, 0xAF, 0xAC,
+  0xAC, 0xD9, 0x95, 0x95, 0x7D, 0x95, 0x95, 0xD9,
+  0x85, 0xD9, 0x2C, 0x85, 0xDA, 0xDA, 0xD9, 0x21,
+  0xA1, 0xD9, 0xAF, 0x2C, 0x85, 0xDA, 0x85, 0xAF,
+  0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9, 0x7D, 0xD6,
+  0xD6, 0x7D, 0x95, 0xD9, 0xD9, 0x85, 0xDB, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0xDB, 0xE3, 0x6B, 0x20, 0x20,
+  0x20, 0x20, 0xE9, 0xD9, 0x2C, 0x85, 0xDA, 0xDA,
+  0xD9, 0x21, 0xA1, 0xD9, 0xAF, 0x2C, 0x85, 0xDA,
+  0x85, 0xAF, 0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9,
+  0x7D, 0xD6, 0xD6, 0x7D, 0x95, 0xD9, 0xD9, 0xD9,
+  0xDA, 0x2C, 0x85, 0xDA, 0xDA, 0x85, 0x95, 0x21,
+  0x21, 0xD9, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0xD9,
+  0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
+  0xAC, 0xAC, 0x2C, 0xAF, 0x2C, 0x85, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x88, 0xDA, 0x85, 0xDA, 0xDA, 0x85,
+  0x95, 0x21, 0x21, 0xD9, 0x85, 0x85, 0x85, 0x2C,
+  0x2C, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xD9,
+  0xD9, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C,
+  0xDA, 0x2C, 0x85, 0x85, 0x2C, 0xD9, 0xD6, 0xB2,
+  0x95, 0x2C, 0x85, 0x85, 0xAF, 0xAC, 0x95, 0x95,
+  0x7D, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0x2C, 0x85,
+  0x85, 0x85, 0x85, 0x85, 0x85, 0xAC, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0xAC, 0x85, 0x85, 0x2C, 0xD9,
+  0xD6, 0xB2, 0x95, 0x2C, 0x85, 0x85, 0xAF, 0xAC,
+  0x95, 0x95, 0x7D, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
+  0x2C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+  0x85, 0x2C, 0x2C, 0x2C, 0xAC, 0x95, 0xD6, 0x7D,
+  0xD9, 0x2C, 0x2C, 0xAF, 0x95, 0x7D, 0x7D, 0x95,
+  0x95, 0xD9, 0xD9, 0x95, 0xD9, 0xD9, 0x2C, 0x85,
+  0xDA, 0xDA, 0xDA, 0x85, 0x85, 0x21, 0x20, 0x20,
+  0x6B, 0x41, 0xDB, 0x6B, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x41, 0xDB, 0xDB, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0xE6, 0x2C, 0x2C, 0xAC, 0x95,
+  0xD6, 0x7D, 0xD9, 0x2C, 0x2C, 0xAF, 0x95, 0x7D,
+  0x7D, 0x95, 0x95, 0xD9, 0xD9, 0x95, 0xD9, 0xD9,
+  0x2C, 0x85, 0xDA, 0xDA, 0xDA, 0x85, 0x2C, 0x2C,
+  0x2C, 0xAF, 0xAC, 0xD9, 0x95, 0xD6, 0xD6, 0xD9,
+  0x2C, 0x2C, 0x2C, 0xD9, 0xD6, 0xD6, 0xD9, 0xAF,
+  0xAC, 0x95, 0xD6, 0x7D, 0x7D, 0xD9, 0x2C, 0x85,
+  0xDA, 0xDA, 0x2C, 0xAF, 0xAF, 0x21, 0x20, 0x20,
+  0x88, 0x2B, 0x88, 0x74, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0xAE, 0x2D, 0x2D, 0x74, 0x74, 0x88, 0x20,
+  0x20, 0x20, 0x20, 0x80, 0xAC, 0xD9, 0x95, 0xD6,
+  0xD6, 0xD9, 0x2C, 0x2C, 0x2C, 0xD9, 0xD6, 0xD6,
+  0xD9, 0xAF, 0xAC, 0x95, 0xD6, 0x7D, 0x7D, 0xD9,
+  0x2C, 0xDA, 0xDA, 0x85, 0x2C, 0xAF, 0xAF, 0xAF,
+  0x2C, 0xAF, 0xD9, 0x95, 0xD6, 0xD6, 0x95, 0xAF,
+  0x2C, 0x2C, 0xD9, 0x95, 0xD6, 0x95, 0xAF, 0x2C,
+  0xAC, 0x7D, 0x21, 0x95, 0xD9, 0x2C, 0x85, 0x85,
+  0x85, 0xAF, 0xD9, 0x95, 0xD9, 0x7D, 0x20, 0x33,
+  0x7D, 0x8A, 0x7D, 0x5B, 0x6B, 0x20, 0x20, 0x6B,
+  0xE6, 0xD9, 0x85, 0x2A, 0xDA, 0x2B, 0x41, 0x20,
+  0x20, 0x20, 0x6B, 0x74, 0xD9, 0x95, 0xD6, 0xD6,
+  0x95, 0xAF, 0x2C, 0x2C, 0xD9, 0x95, 0xD6, 0x95,
+  0xAF, 0x2C, 0xAC, 0x7D, 0x21, 0x95, 0xD9, 0x2C,
+  0x85, 0x85, 0x85, 0x2C, 0xD9, 0xD9, 0xD9, 0xD9,
+  0x85, 0xD9, 0x7D, 0x21, 0x21, 0x7D, 0xAC, 0x2C,
+  0x2C, 0xAC, 0xD9, 0x7D, 0xD9, 0xAF, 0x2C, 0x85,
+  0xAC, 0x7D, 0x7D, 0xAC, 0x85, 0xDA, 0x8A, 0xDA,
+  0x85, 0xAF, 0xD9, 0x7D, 0xD9, 0x95, 0x20, 0x91,
+  0xBC, 0x73, 0xEE, 0x7D, 0x20, 0x20, 0x20, 0x80,
+  0x4D, 0x3D, 0x73, 0x73, 0xA3, 0xD6, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x2B, 0x7D, 0x21, 0x21, 0x7D,
+  0xAC, 0x2C, 0x2C, 0xAC, 0xD9, 0x7D, 0xD9, 0xAF,
+  0x2C, 0x85, 0xAC, 0x7D, 0x7D, 0xAC, 0x85, 0xDA,
+  0x8A, 0x8A, 0x85, 0xAC, 0xD9, 0x7D, 0xD9, 0xAC,
+  0x2C, 0xD9, 0xD6, 0xB2, 0xB2, 0x7D, 0xAF, 0x85,
+  0x2C, 0xD9, 0x95, 0x95, 0xAF, 0x2C, 0x2C, 0x2C,
+  0xD9, 0xD9, 0xAC, 0x85, 0x8D, 0x2A, 0x2A, 0xDA,
+  0xAF, 0xD9, 0x95, 0x95, 0xD9, 0xAC, 0x20, 0xAF,
+  0x2C, 0xE6, 0x8D, 0x73, 0xE3, 0x20, 0x20, 0x48,
+  0x5C, 0xDA, 0x5B, 0x43, 0xBC, 0x73, 0x2B, 0x20,
+  0x20, 0x20, 0x20, 0x41, 0xD6, 0xB2, 0xB2, 0x7D,
+  0xAF, 0x85, 0x2C, 0xD9, 0x95, 0x95, 0xAF, 0x2C,
+  0x2C, 0x2C, 0xD9, 0xD9, 0xAC, 0x85, 0x8A, 0x2A,
+  0x8D, 0xDA, 0xAF, 0xD9, 0x95, 0x95, 0xD9, 0xAF,
+  0xAC, 0xD9, 0xD6, 0xB2, 0x21, 0xD9, 0x2C, 0x85,
+  0x2C, 0xD9, 0x95, 0xD9, 0xAF, 0x2C, 0x2C, 0xAC,
+  0xAC, 0xAF, 0x85, 0x8D, 0xBC, 0xBC, 0xDA, 0xD9,
+  0xD6, 0xA1, 0xA1, 0x21, 0xD9, 0xAC, 0x20, 0x2A,
+  0xCC, 0xAE, 0x9F, 0xE4, 0xAE, 0x5B, 0x74, 0xA1,
+  0xE4, 0xAE, 0x20, 0x9F, 0x89, 0xE8, 0xE6, 0x20,
+  0x20, 0x20, 0x20, 0x41, 0xD6, 0xB2, 0x21, 0xD9,
+  0x2C, 0x85, 0x2C, 0xD9, 0x95, 0xD9, 0xAF, 0x2C,
+  0x2C, 0xAC, 0xAC, 0xAF, 0x85, 0x8D, 0xBC, 0x2A,
+  0xDA, 0xD9, 0xD6, 0xA1, 0xA1, 0x21, 0xD9, 0xD9,
+  0xD9, 0x95, 0x21, 0xA1, 0x21, 0xAC, 0x85, 0x85,
+  0xAC, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0xAF, 0xAC,
+  0xAF, 0x85, 0x8A, 0x2A, 0x2A, 0xDA, 0xD9, 0xA1,
+  0x48, 0xE9, 0x48, 0x21, 0x95, 0xAC, 0x20, 0x2A,
+  0xDB, 0x41, 0x74, 0xBC, 0x2B, 0x7B, 0x7B, 0x80,
+  0x73, 0x41, 0x20, 0x6B, 0x2B, 0xE8, 0x2D, 0x20,
+  0x20, 0x20, 0x20, 0x33, 0x21, 0xA1, 0x21, 0xAC,
+  0x85, 0x85, 0xAC, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C,
+  0xAF, 0xAC, 0xAF, 0x85, 0x8A, 0xBC, 0x2A, 0xDA,
+  0xD9, 0xA1, 0x48, 0xE9, 0x48, 0x21, 0xD9, 0xD9,
+  0xA1, 0xB2, 0xB2, 0x48, 0xD6, 0xAC, 0x2C, 0x2C,
+  0xD9, 0x95, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
+  0x85, 0x8A, 0x8D, 0x8D, 0x85, 0x95, 0xA1, 0x6C,
+  0x6C, 0x48, 0xD6, 0xD9, 0x2C, 0x85, 0x20, 0x2C,
+  0x89, 0x20, 0x3C, 0xB9, 0xA7, 0x63, 0xD2, 0xB9,
+  0xC6, 0x9A, 0x20, 0x20, 0x43, 0x5C, 0xE6, 0x20,
+  0x20, 0x20, 0x20, 0x33, 0xB2, 0x48, 0xD6, 0xAC,
+  0x2C, 0x2C, 0xD9, 0x95, 0xAF, 0x2C, 0x2C, 0x2C,
+  0x2C, 0x2C, 0x85, 0x8A, 0x8D, 0x8D, 0x85, 0x95,
+  0xA1, 0x6C, 0x6C, 0x48, 0xD6, 0xD9, 0xAF, 0xAC,
+  0xA1, 0xD6, 0x7D, 0xB2, 0xD6, 0xAF, 0x85, 0x85,
+  0xD9, 0x95, 0x2C, 0x85, 0xDA, 0x85, 0x85, 0x2C,
+  0x85, 0x8A, 0x8D, 0xDA, 0xD9, 0x48, 0x81, 0x2D,
+  0x48, 0xD6, 0xD9, 0xAC, 0x2C, 0x85, 0x20, 0x2D,
+  0xEE, 0x93, 0xD1, 0xA7, 0x3E, 0x3E, 0x3A, 0x25,
+  0x56, 0xAB, 0xAA, 0xC5, 0xEE, 0xEE, 0x33, 0x20,
+  0x20, 0x20, 0x20, 0x41, 0xD9, 0xB2, 0xD6, 0xAF,
+  0x85, 0x85, 0xD9, 0x95, 0x2C, 0x85, 0xDA, 0x85,
+  0x85, 0x2C, 0x85, 0x8A, 0x8D, 0xDA, 0xD9, 0x48,
+  0x81, 0x2D, 0x48, 0xD6, 0xD9, 0xAF, 0x2C, 0x2C,
+  0xAC, 0xAF, 0xD9, 0x7D, 0xD6, 0x2C, 0x85, 0x2C,
+  0xD9, 0xD9, 0x2C, 0xDA, 0xDA, 0xDA, 0x2C, 0x2C,
+  0x85, 0x8D, 0x8D, 0x2C, 0x21, 0x2D, 0x2D, 0xE9,
+  0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0xDA, 0x20, 0xE3,
+  0xB4, 0xBE, 0xF1, 0x3E, 0x9B, 0x22, 0x56, 0xF2,
+  0xBB, 0x7F, 0x56, 0xDC, 0x8F, 0x5A, 0x5F, 0x20,
+  0x20, 0x20, 0x20, 0x6B, 0x2C, 0x7D, 0xD6, 0x2C,
+  0x85, 0x2C, 0xD9, 0xD9, 0x2C, 0xDA, 0xDA, 0xDA,
+  0x2C, 0x2C, 0x85, 0x8D, 0x8A, 0x85, 0x21, 0x2D,
+  0x2D, 0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
+  0x2A, 0x85, 0xAC, 0x95, 0x95, 0x2C, 0x85, 0x85,
+  0xAC, 0xAF, 0x85, 0xDA, 0xDA, 0x85, 0x2C, 0x2C,
+  0xDA, 0x8A, 0x8A, 0xAF, 0xA1, 0x2D, 0xE9, 0xD6,
+  0xD9, 0xAC, 0x85, 0x85, 0x85, 0xDA, 0x20, 0x52,
+  0x55, 0xED, 0x57, 0x3E, 0x22, 0x56, 0x37, 0xBB,
+  0xBB, 0x58, 0x7F, 0x7F, 0x56, 0x5E, 0xC5, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x2C, 0x95, 0x95, 0x2C,
+  0x85, 0x85, 0xAC, 0xAF, 0x85, 0xDA, 0xDA, 0x85,
+  0x2C, 0x2C, 0xDA, 0x8D, 0xDA, 0xAF, 0xA1, 0x2D,
+  0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85, 0x85,
+  0xCD, 0xAF, 0xD9, 0x95, 0xD9, 0x2C, 0xDA, 0x85,
+  0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x2C, 0xAC, 0xAF,
+  0x85, 0x8A, 0x85, 0xD9, 0x48, 0x48, 0xB2, 0x95,
+  0x95, 0xAC, 0x2C, 0x85, 0xDA, 0xDA, 0x6B, 0xB3,
+  0x46, 0x7C, 0x2E, 0x9B, 0x22, 0x56, 0xBB, 0x37,
+  0x58, 0x58, 0xF2, 0x3A, 0x46, 0x63, 0x64, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x2D, 0x95, 0xD9, 0x2C,
+  0xDA, 0x85, 0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x2C,
+  0xAC, 0xAF, 0x85, 0xDA, 0x85, 0xD9, 0x48, 0x48,
+  0xB2, 0x95, 0x95, 0xD9, 0x85, 0xDA, 0x85, 0x85,
+  0xBC, 0xB2, 0xB2, 0x7D, 0xD9, 0x2C, 0xDA, 0x85,
+  0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x85, 0xAF, 0x2C,
+  0x85, 0xDA, 0x2C, 0x7D, 0xA1, 0x48, 0xB2, 0x21,
+  0xD6, 0xD9, 0x85, 0xDA, 0x85, 0xDA, 0x41, 0x51,
+  0xB7, 0xEC, 0x2E, 0x22, 0x56, 0x37, 0xBB, 0xF2,
+  0x37, 0xEA, 0x2F, 0x2F, 0x77, 0xA7, 0x38, 0x20,
+  0x20, 0x6B, 0x20, 0x20, 0x5B, 0x2C, 0xD9, 0x2C,
+  0xDA, 0x85, 0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x85,
+  0xAF, 0x2C, 0xDA, 0xDA, 0x2C, 0x7D, 0xA1, 0x48,
+  0xB2, 0x21, 0xD6, 0xD9, 0x2C, 0xDA, 0x85, 0xAF,
+  0x2C, 0x2D, 0x48, 0x7D, 0xAF, 0x2C, 0x85, 0x2C,
+  0xD9, 0xAC, 0xAF, 0x85, 0x85, 0x2C, 0x2C, 0x2C,
+  0x85, 0x2C, 0xD9, 0xD6, 0xA1, 0xA1, 0x48, 0xA1,
+  0x21, 0x2C, 0xDA, 0xDA, 0x2C, 0x85, 0x41, 0x98,
+  0xA2, 0xA7, 0x6F, 0xC9, 0x37, 0xF2, 0xF2, 0x9B,
+  0xB7, 0x66, 0x60, 0x4C, 0xED, 0x84, 0x3C, 0x20,
+  0x5B, 0x2D, 0x2B, 0x6B, 0x20, 0xAF, 0xAF, 0x2C,
+  0x85, 0x2C, 0xD9, 0xAC, 0xAF, 0x85, 0x85, 0x2C,
+  0x2C, 0x2C, 0x2C, 0x85, 0xD9, 0xD6, 0xA1, 0xA1,
+  0x48, 0xA1, 0xD6, 0xAF, 0xDA, 0x8A, 0x2C, 0xD9,
+  0xB2, 0x2D, 0x48, 0x95, 0x2C, 0x2C, 0x2C, 0x85,
+  0xAC, 0xAC, 0xAF, 0x85, 0xDA, 0x85, 0xAF, 0xAC,
+  0xAF, 0x2C, 0xD9, 0xD6, 0xD6, 0xD6, 0x21, 0xD6,
+  0xD9, 0xDA, 0x8D, 0xDA, 0xAF, 0x2C, 0x20, 0x88,
+  0x42, 0x51, 0x3F, 0x2F, 0x45, 0xB7, 0x66, 0x55,
+  0x46, 0x60, 0x5D, 0x36, 0xD8, 0x71, 0x43, 0x20,
+  0x20, 0x2D, 0xB2, 0x80, 0x20, 0x2D, 0x2C, 0x2C,
+  0x2C, 0x85, 0xAC, 0xAC, 0xAF, 0x85, 0xDA, 0x85,
+  0xAF, 0xAC, 0xAC, 0xAF, 0xD9, 0xD6, 0xD6, 0xD6,
+  0x21, 0xD6, 0xD9, 0xDA, 0x8D, 0x8A, 0x2C, 0xD9,
+  0xB2, 0x48, 0xD6, 0xAC, 0xAF, 0x2C, 0x2C, 0x85,
+  0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85, 0xAF, 0xD9,
+  0xD9, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC,
+  0x85, 0x8D, 0xBC, 0xDA, 0xD9, 0xDA, 0x20, 0xE3,
+  0xDA, 0x69, 0x96, 0xB5, 0xF1, 0x68, 0x5D, 0x82,
+  0xE1, 0xBE, 0x27, 0x8D, 0x4D, 0xD3, 0x7D, 0x20,
+  0x20, 0xDB, 0xA1, 0xCA, 0x20, 0x88, 0x85, 0x2C,
+  0x2C, 0x85, 0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85,
+  0xAF, 0xD9, 0xAC, 0xAF, 0xD9, 0xD9, 0xD9, 0xD9,
+  0xD9, 0xAC, 0xDA, 0x8D, 0xBC, 0xDA, 0xD9, 0x95,
+  0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0x2C, 0x2C, 0x85,
+  0x85, 0xAF, 0xAF, 0x85, 0x85, 0x2C, 0x2C, 0xAC,
+  0xD9, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x85,
+  0x8D, 0x2A, 0x2A, 0x85, 0xD9, 0x95, 0x20, 0xDB,
+  0x8D, 0x8D, 0x99, 0xB0, 0x35, 0xE5, 0x3F, 0x35,
+  0xB9, 0x50, 0x8A, 0x4D, 0x73, 0xE8, 0xA3, 0xCC,
+  0x20, 0x20, 0x33, 0x6B, 0x20, 0x20, 0xCC, 0x85,
+  0x2C, 0x85, 0x85, 0xAF, 0xAF, 0x85, 0x85, 0x85,
+  0x2C, 0xD9, 0xD9, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C,
+  0x2C, 0x85, 0x8A, 0x2A, 0x8D, 0x2C, 0xD9, 0xD9,
+  0xAF, 0xAF, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x85,
+  0x2C, 0xAF, 0xAF, 0xAF, 0x2C, 0x2C, 0x2C, 0xAC,
+  0xD9, 0xAC, 0xAF, 0x2C, 0x85, 0x85, 0xDA, 0xDA,
+  0x8A, 0x8A, 0x85, 0xD9, 0x2C, 0x2B, 0x20, 0xAE,
+  0xA3, 0xBC, 0x8D, 0xC8, 0xA9, 0xC7, 0x92, 0x47,
+  0x8D, 0x8D, 0x7E, 0xE4, 0xE8, 0xE8, 0x5C, 0x2C,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6B, 0xAF,
+  0x2C, 0x85, 0x2C, 0xAF, 0xAF, 0xAF, 0x2C, 0x2C,
+  0x2C, 0xAF, 0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0x85,
+  0x85, 0xDA, 0x8D, 0x8A, 0x85, 0xAC, 0x95, 0xD9,
+  0xAC, 0xAC, 0xAC, 0xAC, 0x2C, 0xAF, 0xAF, 0x2C,
+  0x2C, 0xAF, 0xAF, 0xAC, 0x2C, 0xAF, 0x2C, 0xAF,
+  0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0x85, 0x85, 0x85,
+  0x85, 0x2C, 0xD9, 0xD9, 0x2D, 0x6B, 0x41, 0x2A,
+  0xE8, 0xA3, 0xC8, 0x8D, 0x8A, 0x8A, 0x8A, 0x8D,
+  0x4D, 0xA3, 0x3D, 0xE8, 0xE8, 0xE8, 0xE8, 0x5C,
+  0xAE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xDB,
+  0xDA, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC, 0xAF,
+  0x2C, 0xAC, 0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0x85,
+  0x85, 0x85, 0x85, 0x2C, 0xD9, 0x95, 0x7D, 0xD9,
+  0x7D, 0x7D, 0xD9, 0xAC, 0xAC, 0xAF, 0xAF, 0xAF,
+  0x2C, 0x2C, 0xAC, 0xAC, 0xD9, 0xAC, 0xAC, 0xD9,
+  0x95, 0xD9, 0xAC, 0xAF, 0xAF, 0xAC, 0xAF, 0xAC,
+  0xD9, 0x7D, 0x7D, 0x7D, 0x33, 0x41, 0x2D, 0xE8,
+  0xE8, 0x5C, 0xD3, 0x8D, 0x8D, 0x8D, 0x8D, 0x7E,
+  0x3D, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+  0xDA, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x81, 0x2C, 0x2C, 0x2C, 0xAC, 0xAC, 0xAC, 0xAC,
+  0xAC, 0xD9, 0x95, 0x95, 0xAC, 0xAF, 0xAF, 0xAF,
+  0xAF, 0xAC, 0xD9, 0x95, 0x7D, 0xD6, 0xD6, 0x7D,
+  0x21, 0xD6, 0x95, 0xD9, 0xD9, 0xAC, 0xAF, 0xAF,
+  0x2C, 0xAF, 0xAC, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
+  0x21, 0x21, 0x7D, 0x95, 0x95, 0x7D, 0xD6, 0x21,
+  0xB2, 0xA1, 0x2C, 0x88, 0x20, 0xE3, 0xA3, 0xE8,
+  0xE8, 0xE8, 0xE4, 0xEE, 0xD3, 0x7E, 0x73, 0x5C,
+  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+  0x5C, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x2C, 0xAF, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9,
+  0xD9, 0xD9, 0xD6, 0x21, 0x7D, 0x95, 0x95, 0x7D,
+  0xD6, 0xB2, 0xA1, 0xA1, 0xB2, 0xD6, 0x21, 0x21,
+  0x21, 0xD9, 0xD9, 0xD9, 0xAC, 0xAF, 0xAC, 0xAF,
+  0x2C, 0x2C, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9, 0x95,
+  0x7D, 0xB2, 0xD6, 0x95, 0xD9, 0x95, 0xD6, 0xA1,
+  0xA1, 0xAF, 0x5B, 0x20, 0x20, 0xD6, 0xE8, 0xE8,
+  0xE8, 0xE8, 0xE8, 0xE8, 0x5C, 0xE8, 0xE8, 0xE8,
+  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+  0xE8, 0x48, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0xE3, 0x8A, 0x2C, 0xAC, 0xAC, 0xD9, 0xD9,
+  0xD9, 0x95, 0xD6, 0xB2, 0xD6, 0x95, 0xD9, 0x95,
+  0x21, 0xB2, 0xA1, 0xB2, 0xD6, 0xD6, 0xD6, 0xA1,
+  0xD9, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAF,
+  0x2C, 0x2C, 0xAF, 0xAC, 0xD9, 0xAC, 0xD9, 0xD9,
+  0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0xAC, 0x95, 0x7D,
+  0xD9, 0x91, 0x20, 0x20, 0xE3, 0xA3, 0xE8, 0xE8,
+  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+  0xE8, 0x85, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x2B, 0x8A, 0xAF, 0xAC, 0xD9, 0xAC,
+  0xD9, 0xD9, 0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0xAC,
+  0x95, 0x7D, 0x95, 0x95, 0xD9, 0x95, 0x7D, 0x21,
+  0x2C, 0xDA, 0xDA, 0x85, 0x2C, 0xAF, 0xAF, 0xAF,
+  0xAF, 0xAF, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC, 0xAC,
+  0xD9, 0xAF, 0x85, 0x85, 0x2C, 0xAF, 0xD9, 0xAF,
+  0x48, 0x20, 0x20, 0x20, 0xE6, 0xA3, 0xE8, 0xE8,
+  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0x5C,
+  0xE4, 0x73, 0x41, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x2B, 0xDA, 0xAF, 0xAF, 0xAC,
+  0xAC, 0xAF, 0xD9, 0x2C, 0x85, 0x85, 0x2C, 0xAF,
+  0xD9, 0xD9, 0xAC, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9,
+  0x85, 0xDA, 0xDA, 0x85, 0x2C, 0x2C, 0xAC, 0xAF,
+  0xAF, 0xAF, 0xAF, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC,
+  0xAF, 0x2C, 0x2C, 0x2C, 0xAC, 0x95, 0x95, 0xA1,
+  0x20, 0x20, 0x20, 0x20, 0xE9, 0x8C, 0x5C, 0xE8,
+  0xE8, 0xE8, 0xE8, 0x3D, 0x73, 0x73, 0xE8, 0xE8,
+  0xE8, 0xE8, 0xE8, 0xE4, 0x73, 0x73, 0x73, 0xCD,
+  0x7E, 0xA3, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x24, 0x85, 0xAF, 0xAF,
+  0xAC, 0xAC, 0xAC, 0xAF, 0x85, 0x2C, 0xAC, 0x95,
+  0x95, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9, 0xAC, 0xAF,
+  0x8A, 0x8A, 0xDA, 0xDA, 0x85, 0x2C, 0x2C, 0x2C,
+  0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAF, 0xAC,
+  0xAC, 0xAF, 0xAF, 0xD9, 0xD6, 0xD6, 0x2C, 0x88,
+  0x20, 0x20, 0x20, 0x88, 0xB2, 0xDA, 0x7E, 0x73,
+  0xE8, 0xE8, 0xE8, 0x3D, 0x73, 0xE8, 0xE8, 0xE8,
+  0xE8, 0xE8, 0xE8, 0xA3, 0xCD, 0xD3, 0x2A, 0x2A,
+  0x2A, 0x8C, 0x8D, 0x88, 0x20, 0xE3, 0x6B, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x41, 0x85, 0xAF, 0xAC,
+  0xAC, 0xAC, 0xAC, 0xAF, 0xAC, 0xD9, 0x7D, 0xD6,
+  0x7D, 0x7D, 0xD9, 0x95, 0xD9, 0xAC, 0xAC, 0xAF,
+  0xD3, 0x8D, 0xDA, 0xDA, 0x85, 0x85, 0x2C, 0x2C,
+  0x2C, 0xAF, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
+  0xAF, 0xAF, 0xAC, 0xD9, 0x95, 0x7D, 0xAC, 0x20,
+  0x20, 0x20, 0x20, 0xDB, 0x2C, 0xA3, 0x5C, 0xE8,
+  0xE8, 0xE8, 0xE8, 0x5C, 0x3D, 0x3D, 0xE8, 0xE8,
+  0xE8, 0xE4, 0xE8, 0xE8, 0xE8, 0xE4, 0x73, 0xEE,
+  0xD3, 0x2A, 0xEE, 0xAC, 0x20, 0x33, 0x2B, 0xE3,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x9F, 0xAF, 0xD9,
+  0xD9, 0xAC, 0xAF, 0xAF, 0xAC, 0xD9, 0x95, 0x7D,
+  0xD9, 0x95, 0x95, 0x95, 0x95, 0xD9, 0xAF, 0xAF,
+  0x7E, 0x85, 0x85, 0x2C, 0x85, 0x85, 0x85, 0x2C,
+  0x2C, 0x2C, 0xAF, 0xD9, 0xD9, 0x95, 0xD9, 0xAC,
+  0xAC, 0xAF, 0xAF, 0xAC, 0xAC, 0xAC, 0x91, 0x20,
+  0x33, 0xE3, 0x41, 0x48, 0x73, 0x5C, 0xE8, 0xE8,
+  0xE8, 0xE8, 0xE8, 0xA3, 0xD6, 0x6C, 0x85, 0xE8,
+  0xDA, 0xAE, 0xB2, 0xA3, 0x5C, 0xE8, 0xE8, 0xE8,
+  0x3D, 0xEE, 0x4D, 0xA3, 0x24, 0x20, 0x6B, 0xDB,
+  0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x85, 0x95,
+  0xD9, 0xD9, 0xAC, 0xAF, 0xAF, 0xAC, 0xD9, 0xAC,
+  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC, 0xD9, 0xAC,
+  0x8A, 0xD9, 0xAC, 0xD9, 0xAC, 0xAC, 0x2C, 0x2C,
+  0xAF, 0xAF, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
+  0xAF, 0xAF, 0xAF, 0xAC, 0xAC, 0x85, 0x33, 0x20,
+  0xCC, 0x20, 0xE3, 0xA3, 0xE8, 0xE8, 0xE8, 0xE8,
+  0xE8, 0xA3, 0xD9, 0x81, 0xAC, 0xDA, 0x2D, 0x5C,
+  0x48, 0x41, 0x88, 0x74, 0x21, 0xA3, 0xE8, 0xE8,
+  0xE8, 0xE8, 0x73, 0x8C, 0x8A, 0x20, 0x20, 0x20,
+  0xDB, 0x33, 0x20, 0x20, 0x20, 0x20, 0xE6, 0xD9,
+  0xD9, 0xAC, 0xAC, 0xAF, 0xAC, 0xAF, 0xAC, 0xAF,
+  0xAF, 0xAC, 0xD9, 0xAF, 0xD9, 0xAC, 0xAC, 0xAF,
+  0x85, 0xD9, 0x95, 0xD9, 0x95, 0xD9, 0xD9, 0xAC,
+  0xAF, 0xAC, 0xAF, 0xAF, 0x2C, 0xAF, 0x2C, 0x2C,
+  0xAF, 0xAF, 0xAF, 0xAC, 0xAC, 0x2C, 0x20, 0x5B,
+  0x33, 0x20, 0xD6, 0xE8, 0xE8, 0xE8, 0xE8, 0x73,
+  0xAF, 0x2D, 0xD9, 0xDA, 0xB2, 0x81, 0x81, 0xE4,
+  0xA1, 0x91, 0x2B, 0x88, 0x33, 0x80, 0xAF, 0x73,
+  0xE8, 0xE8, 0xE8, 0x5C, 0xA3, 0x80, 0x41, 0xCC,
+  0x2B, 0xCC, 0x20, 0x20, 0x20, 0x20, 0x88, 0xDA,
+  0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC, 0xAF,
+  0xAF, 0xAF, 0xAF, 0xAC, 0xAF, 0xAF, 0xAF, 0x2C,
+  0x85, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC, 0xAC, 0xD9,
+  0xD9, 0xD9, 0xAC, 0x2C, 0x2C, 0x2C, 0x85, 0x85,
+  0x85, 0x2C, 0x2C, 0xAF, 0x2C, 0x91, 0x20, 0xAE,
+  0x20, 0xDB, 0x3D, 0xE8, 0xE8, 0x5C, 0xB2, 0x80,
+  0xB2, 0xAF, 0x48, 0xB2, 0x48, 0x89, 0x89, 0x3D,
+  0x21, 0x48, 0x6C, 0x2D, 0x2B, 0x41, 0xE3, 0xAE,
+  0xD9, 0x5C, 0xE8, 0xE8, 0xE8, 0x95, 0x33, 0x80,
+  0xAE, 0x33, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x95,
+  0x85, 0x2C, 0x85, 0x2C, 0x2C, 0xAF, 0x2C, 0x2C,
+  0x2C, 0xAF, 0xAC, 0xAF, 0xAF, 0x2C, 0x2C, 0x2C,
+  0xDA, 0xAF, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C,
+  0xAC, 0xD9, 0xAC, 0xAF, 0x2C, 0x85, 0x2C, 0x85,
+  0x85, 0x2C, 0x2C, 0x2C, 0x8A, 0x41, 0xDB, 0x33,
+  0x20, 0x95, 0xE8, 0xE8, 0xE8, 0xA3, 0xDB, 0x88,
+  0xDB, 0x80, 0xD6, 0x7E, 0x85, 0x2D, 0xE6, 0x5C,
+  0x21, 0x48, 0xD9, 0x7E, 0xD6, 0x2B, 0xCC, 0xAC,
+  0x85, 0xBC, 0xE8, 0xE8, 0xE8, 0xCD, 0x88, 0x5B,
+  0x41, 0x20, 0xAE, 0x20, 0x20, 0x20, 0x20, 0x74,
+  0xDA, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0x2C, 0x2C,
+  0xAF, 0xAC, 0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9,
+  0x8A, 0xAF, 0xAC, 0xAC, 0x2C, 0x85, 0x2C, 0xAF,
+  0xD9, 0xD9, 0xAF, 0xAF, 0xAF, 0x2C, 0xAF, 0x2C,
+  0x2C, 0x2C, 0x2C, 0xAF, 0x95, 0x20, 0x74, 0x20,
+  0x33, 0xA3, 0xE8, 0xE8, 0xE8, 0xE4, 0x7D, 0xCC,
+  0x6B, 0x33, 0xAE, 0x2C, 0x85, 0x2D, 0x9F, 0x73,
+  0xA1, 0x2D, 0x2C, 0xDA, 0x89, 0x48, 0xD3, 0xD9,
+  0x21, 0xA3, 0xE8, 0xE8, 0xE8, 0xE8, 0xE3, 0x20,
+  0x20, 0x20, 0xDB, 0x41, 0x20, 0x20, 0x20, 0x20,
+  0xDA, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF, 0xAC, 0xAC,
+  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0x95, 0x95, 0xD9,
+  0x2C, 0xD9, 0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0xAF,
+  0xAF, 0xAF, 0xAC, 0xAC, 0xD9, 0xAC, 0xAF, 0xAC,
+  0xAC, 0x95, 0xD6, 0x7D, 0xAE, 0x88, 0x2B, 0x20,
+  0x6C, 0xE8, 0xE8, 0xE8, 0x73, 0xEE, 0x73, 0x2C,
+  0x89, 0x2B, 0x41, 0x33, 0xCC, 0xCC, 0x80, 0x3D,
+  0x2D, 0x74, 0x80, 0x48, 0x8D, 0x95, 0x48, 0x95,
+  0xEE, 0x5C, 0x5C, 0xE8, 0xE8, 0xE8, 0x24, 0x20,
+  0x20, 0x20, 0x5B, 0xDB, 0x20, 0x20, 0x20, 0x20,
+  0xAF, 0xAC, 0xD9, 0x95, 0xD6, 0xD6, 0xD6, 0x7D,
+  0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0xD9, 0xAC,
+  0xAC, 0xD9, 0xD9, 0xAC, 0x2C, 0x2C, 0x2C, 0xAF,
+  0xAC, 0xAC, 0xAC, 0xAC, 0xD9, 0xAC, 0xAC, 0xD9,
+  0xD6, 0x48, 0xE9, 0x95, 0x20, 0x2B, 0x41, 0x6B,
+  0x8D, 0xE8, 0xE8, 0xCD, 0x2B, 0x2B, 0x2C, 0x73,
+  0xCD, 0x48, 0xCA, 0x5B, 0x41, 0x5B, 0x74, 0xDA,
+  0x80, 0xE6, 0xC8, 0x85, 0xA1, 0x7D, 0x8D, 0x3D,
+  0x7E, 0xE9, 0x7D, 0xEE, 0xE8, 0xE8, 0x81, 0x20,
+  0x20, 0x20, 0xE3, 0xE3, 0x20, 0x20, 0x20, 0x20,
+  0x2D, 0xD9, 0xD6, 0x48, 0x6C, 0xE9, 0xA1, 0xD6,
+  0xD9, 0xD9, 0xAC, 0xD9, 0xD9, 0x95, 0xAC, 0x2C,
+  0x2C, 0x2C, 0x2C, 0xD9, 0xAC, 0x2C, 0x2C, 0x2C,
+  0xAF, 0x2C, 0xAF, 0xD9, 0xAC, 0xAF, 0xAF, 0x95,
+  0xB2, 0xE9, 0x21, 0x2B, 0x41, 0x2B, 0x20, 0x5B,
+  0x3D, 0xE8, 0xE8, 0x8D, 0x2B, 0x88, 0x5B, 0xE6,
+  0xBC, 0x73, 0x85, 0x89, 0x80, 0x5B, 0xE3, 0xAE,
+  0x2C, 0x8A, 0xD6, 0xB2, 0x2C, 0xA3, 0xA3, 0xD9,
+  0xA1, 0x2C, 0x85, 0x8D, 0xE8, 0xE8, 0x48, 0x20,
+  0x20, 0x20, 0xE3, 0x88, 0x20, 0x20, 0x20, 0x20,
+  0xAE, 0xD9, 0xB2, 0xE9, 0x6C, 0x48, 0xD6, 0xD9,
+  0x2C, 0x85, 0x2C, 0xD9, 0x7D, 0xD9, 0x2C, 0x85,
+  0x8D, 0x85, 0x2C, 0xAC, 0xAF, 0x2C, 0x2C, 0x85,
+  0x2C, 0x2C, 0xAF, 0xAC, 0xAC, 0xAF, 0xAF, 0xD9,
+  0xB2, 0x48, 0xB2, 0x20, 0x20, 0xCC, 0x20, 0x9F,
+  0xE8, 0xE8, 0xE8, 0xCD, 0x48, 0x89, 0xDB, 0x88,
+  0x2B, 0xE9, 0xCD, 0x2A, 0x48, 0x80, 0xAE, 0xAE,
+  0x7D, 0x48, 0x21, 0xEE, 0x3D, 0x2C, 0x48, 0x85,
+  0x2C, 0x95, 0x7D, 0x8C, 0xE8, 0xE8, 0xB2, 0x20,
+  0x20, 0x20, 0xDB, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0xDB, 0x2C, 0xB2, 0x48, 0x48, 0x7D, 0xD9, 0xAF,
+  0x85, 0x8A, 0x85, 0x7D, 0xB2, 0x95, 0x85, 0xDA,
+  0xD3, 0x85, 0xAF, 0xAC, 0x2C, 0x85, 0x85, 0x2C,
+  0xAC, 0xAC, 0xAC, 0xD9, 0xD9, 0xAC, 0x2C, 0x2C,
+  0xD9, 0xAC, 0x5B, 0x20, 0x20, 0xAE, 0x20, 0x2D,
+  0xE8, 0xE8, 0xE8, 0x7E, 0xD6, 0x48, 0xE9, 0xAE,
+  0x88, 0x5B, 0x80, 0x6C, 0xAE, 0xCA, 0x91, 0xE9,
+  0x43, 0x9F, 0xE6, 0x2C, 0x48, 0x21, 0xBC, 0x95,
+  0x95, 0xD6, 0x21, 0x7E, 0xE8, 0xE8, 0x7D, 0x20,
+  0x20, 0x20, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x6B, 0xDA, 0xD9, 0x48, 0xB2, 0xD9, 0x2C, 0x85,
+  0xDA, 0xDA, 0x2C, 0xA1, 0x48, 0xAC, 0xDA, 0x8D,
+  0x2A, 0xAC, 0x7D, 0x95, 0xAF, 0x85, 0x2C, 0x2C,
+  0xAC, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0x2C, 0xAF,
+  0x7D, 0xD6, 0x20, 0x20, 0x88, 0x9F, 0x20, 0xA1,
+  0xE8, 0xE8, 0xE8, 0xA3, 0xD6, 0x6C, 0xB2, 0x2C,
+  0x89, 0xE3, 0x88, 0xDB, 0xCC, 0x24, 0x7D, 0xEE,
+  0xB2, 0xCC, 0xAE, 0x2D, 0xDA, 0x2C, 0xD6, 0x2C,
+  0xB2, 0x2D, 0xD6, 0xEE, 0xE8, 0xE8, 0x95, 0x20,
+  0x20, 0x20, 0xDB, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x6B, 0xDA, 0x95, 0xA1, 0xB2, 0xAC, 0x85, 0x85,
+  0xDA, 0x2C, 0x95, 0xA1, 0x21, 0x2C, 0x8A, 0x2A,
+  0xAF, 0xA1, 0x48, 0xD6, 0xAF, 0x2C, 0x2C, 0xAC,
+  0xD9, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0xD9, 0x7D,
+  0x48, 0xE6, 0x20, 0x20, 0x33, 0x89, 0x6B, 0x95,
+  0xE8, 0xE8, 0xE8, 0xA3, 0x21, 0x48, 0xAF, 0xAF,
+  0x9F, 0xE9, 0x43, 0x33, 0x33, 0x2D, 0xDA, 0xCD,
+  0xD6, 0xAE, 0x85, 0x2C, 0x7D, 0xD6, 0x91, 0xB8,
+  0xD4, 0x48, 0x7D, 0xA3, 0xE8, 0xE8, 0x95, 0x20,
+  0x20, 0x33, 0xE3, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x2C, 0x48, 0x6C, 0xB2, 0xAF, 0xDA, 0xDA,
+  0x85, 0xAF, 0xD9, 0x95, 0xAC, 0xDA, 0x8A, 0xDA,
+  0x7D, 0x48, 0x48, 0x7D, 0x2C, 0x85, 0x2C, 0xAF,
+  0xD9, 0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0x95, 0xD6,
+  0x21, 0x24, 0x20, 0x20, 0x20, 0x5B, 0xDB, 0xAC,
+  0xE8, 0xE8, 0xE8, 0x3D, 0x7D, 0x48, 0xE6, 0x2D,
+  0x85, 0x81, 0x81, 0x48, 0xAE, 0xCA, 0x89, 0xCC,
+  0xAE, 0xDB, 0x2D, 0x95, 0x21, 0xCC, 0xDB, 0xAE,
+  0x91, 0xE9, 0x7D, 0x73, 0xE8, 0xE8, 0x48, 0x20,
+  0x6B, 0x74, 0x41, 0x88, 0x6B, 0x20, 0x20, 0x20,
+  0x6B, 0x95, 0xB2, 0xD6, 0xD9, 0x85, 0xDA, 0xDA,
+  0xDA, 0x2C, 0xAF, 0xAF, 0x2C, 0xDA, 0xDA, 0x85,
+  0xA1, 0xE9, 0x48, 0x95, 0x85, 0xDA, 0x85, 0xAC,
+  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0x95,
+  0x95, 0x6C, 0x41, 0x93, 0x93, 0x41, 0xDB, 0x95,
+  0xE8, 0xE8, 0xE8, 0x3D, 0x95, 0xD4, 0x6C, 0x21,
+  0x2D, 0x95, 0xCD, 0x2C, 0xD6, 0xD9, 0x6C, 0x91,
+  0x89, 0x7D, 0xAC, 0x2A, 0x8D, 0xE6, 0xCC, 0x88,
+  0x74, 0x48, 0xD9, 0xE4, 0xE8, 0xE8, 0xE6, 0x88,
+  0x2B, 0x88, 0x20, 0x33, 0xDB, 0x2B, 0xDB, 0x20,
+  0x91, 0x7D, 0xD9, 0xD9, 0x85, 0x85, 0xDA, 0xDA,
+  0x85, 0xAF, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C,
+  0xA1, 0xA1, 0xD6, 0xAF, 0x85, 0xDA, 0x85, 0x2C,
+  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xAC,
+  0x2C, 0x47, 0x87, 0x3E, 0x3E, 0xA4, 0x7B, 0x80,
+  0xA3, 0xE8, 0xE8, 0x5C, 0x7D, 0x48, 0xE6, 0xD9,
+  0xBC, 0xEE, 0x7D, 0x43, 0xD6, 0x21, 0x43, 0x6C,
+  0x43, 0x7D, 0x7D, 0xB2, 0x8A, 0xEE, 0x2C, 0xCA,
+  0xAE, 0x48, 0x2C, 0xE4, 0xE8, 0x5C, 0xCC, 0x88,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x91, 0xE3,
+  0x21, 0xD9, 0x2C, 0x2C, 0xDA, 0xDA, 0xDA, 0x85,
+  0x2C, 0xAC, 0xD9, 0xD9, 0xAC, 0xAF, 0xAF, 0xAF,
+  0xD6, 0x7D, 0xD9, 0x2C, 0xDA, 0xDA, 0x85, 0xAC,
+  0xD9, 0x7D, 0x7D, 0xD9, 0xD9, 0xD9, 0x2C, 0x2C,
+  0xB8, 0x9C, 0xEC, 0x62, 0x6F, 0x62, 0x70, 0x3C,
+  0xAE, 0xCD, 0xE8, 0xE8, 0x8C, 0x7D, 0xC8, 0x3D,
+  0x8A, 0xE9, 0x2D, 0x9E, 0xA1, 0xD6, 0x48, 0x73,
+  0x81, 0xD6, 0xD6, 0xAE, 0x5B, 0x2D, 0xA3, 0xA3,
+  0x21, 0x21, 0xCD, 0xE8, 0xC0, 0x56, 0x31, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0xCC, 0xDB,
+  0x42, 0x85, 0x85, 0x85, 0x85, 0x85, 0x2C, 0x2C,
+  0xAC, 0xD9, 0xD9, 0xD9, 0xAC, 0xAF, 0xAF, 0xAF,
+  0xD9, 0x95, 0xAC, 0x2C, 0x85, 0x85, 0x2C, 0xD9,
+  0x7D, 0xD6, 0xD6, 0xD9, 0xAC, 0xAF, 0x8A, 0xBC,
+  0xC2, 0x68, 0x2E, 0x4B, 0xC9, 0x8B, 0x62, 0x87,
+  0x3C, 0x74, 0xBC, 0xE8, 0xE8, 0xE4, 0xEE, 0xA1,
+  0xE9, 0x21, 0xE6, 0x89, 0x48, 0x7D, 0xB2, 0x5C,
+  0x6C, 0x7D, 0x21, 0x80, 0xE3, 0x33, 0xCC, 0x2C,
+  0x3D, 0x3D, 0xE8, 0xE8, 0xEC, 0xCB, 0x5A, 0x6B,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x88, 0x41, 0x51,
+  0x49, 0x28, 0x85, 0x85, 0x85, 0x85, 0x2C, 0xAF,
+  0xAC, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
+  0xD9, 0x95, 0xD9, 0x2C, 0x85, 0x85, 0x2C, 0xD9,
+  0xB2, 0xB2, 0x2C, 0x2A, 0x79, 0x79, 0x97, 0x44,
+  0xED, 0x29, 0x32, 0x62, 0x4B, 0x62, 0x6F, 0x22,
+  0xF3, 0x6B, 0x33, 0x85, 0x73, 0xE4, 0x2D, 0x2B,
+  0xCC, 0x9F, 0xDA, 0xBC, 0x48, 0xD6, 0xA1, 0xE4,
+  0xE9, 0xD6, 0xD9, 0x2A, 0xB2, 0x2B, 0x2B, 0xA1,
+  0xB8, 0xE8, 0xE8, 0xE8, 0xEC, 0x3E, 0x30, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x6B, 0x54, 0xDC,
+  0xC9, 0x53, 0xBC, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF,
+  0xAF, 0xAC, 0xAF, 0xAC, 0xAC, 0x2C, 0xAF, 0xAC,
+  0x2C, 0x7D, 0xD9, 0x2C, 0x85, 0xDA, 0xAF, 0x7D,
+  0xB2, 0xAC, 0xC6, 0xBA, 0x4C, 0xEF, 0xA7, 0xEF,
+  0xEC, 0x7A, 0x62, 0x4B, 0x62, 0x4B, 0x8B, 0x4B,
+  0x3A, 0x52, 0x20, 0x6B, 0x21, 0x73, 0xAC, 0x2B,
+  0x41, 0x33, 0x48, 0x67, 0xA1, 0xD6, 0xD6, 0x5C,
+  0xE9, 0xD6, 0x2C, 0xEE, 0xB2, 0x9F, 0x8A, 0x95,
+  0x4D, 0xE8, 0xE8, 0x3D, 0x7A, 0x57, 0xD1, 0x7B,
+  0x20, 0x20, 0x20, 0x20, 0x6B, 0xCF, 0xBA, 0x3E,
+  0x3E, 0xD0, 0xBC, 0xAC, 0xAC, 0x2C, 0x2C, 0xAC,
+  0xD9, 0xD9, 0x95, 0x95, 0x7D, 0x95, 0x95, 0xD9,
+  0x85, 0xD9, 0xAF, 0xDA, 0xDA, 0x85, 0xAC, 0x21,
+  0xB2, 0x2A, 0xBA, 0x57, 0x2E, 0x2E, 0x2E, 0x7A,
+  0x32, 0x62, 0x8B, 0x4B, 0x8B, 0x4B, 0x4B, 0x4B,
+  0xC9, 0x4A, 0x5F, 0x20, 0x20, 0x2D, 0xA3, 0xD9,
+  0xCA, 0x88, 0xDB, 0x24, 0x48, 0x7D, 0xB2, 0xE4,
+  0x2D, 0x7D, 0x7D, 0x81, 0xA1, 0xDA, 0x21, 0xDA,
+  0xE4, 0xE8, 0xEE, 0xF1, 0x2E, 0x57, 0x82, 0x76,
+  0x52, 0x4F, 0x4F, 0x98, 0xDE, 0xB5, 0xEC, 0x2E,
+  0x3E, 0x6D, 0x85, 0x2C, 0xAC, 0xAC, 0xD9, 0xD9,
+  0x95, 0xD6, 0x7D, 0x7D, 0x95, 0xD9, 0xD9, 0xD9,
+  0xDA, 0x2C, 0x85, 0xDA, 0xDA, 0x2C, 0x95, 0xB2,
+  0x21, 0xB8, 0xED, 0x2E, 0x3E, 0x4B, 0xC9, 0x4B,
+  0x8B, 0x62, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
+  0x22, 0x6F, 0xCE, 0x20, 0x20, 0x20, 0x80, 0xCD,
+  0xDA, 0x2D, 0x2B, 0xDB, 0xE9, 0xD6, 0x95, 0x5C,
+  0x2D, 0x7D, 0x7D, 0xAF, 0xAF, 0xAC, 0xEE, 0x5C,
+  0xE8, 0xE8, 0xEB, 0x25, 0x7A, 0x57, 0x39, 0xE1,
+  0x83, 0xA8, 0x55, 0x83, 0x82, 0x57, 0x32, 0x8B,
+  0x62, 0x6D, 0xEB, 0x95, 0xD9, 0xD9, 0xD9, 0xD9,
+  0xD9, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C,
+  0xDA, 0x2C, 0x85, 0x85, 0x85, 0xAC, 0xD6, 0x21,
+  0x95, 0x6E, 0xED, 0x57, 0x62, 0x4B, 0x8B, 0x4B,
+  0x4B, 0x62, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x62,
+  0x62, 0x62, 0x25, 0x3C, 0x20, 0x20, 0x20, 0xE3,
+  0x2A, 0xBC, 0x7D, 0xCA, 0x6C, 0xD6, 0x95, 0x3D,
+  0x81, 0x7D, 0xD6, 0xD6, 0xDA, 0x73, 0xE8, 0xE8,
+  0xE8, 0x4D, 0x94, 0xED, 0x72, 0x3A, 0xF1, 0xA7,
+  0x39, 0xED, 0x39, 0xEF, 0x57, 0x32, 0x8B, 0x4B,
+  0x62, 0x62, 0xA6, 0x2A, 0xD9, 0xD9, 0xD9, 0xD9,
+  0x2C, 0x2C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+  0x85, 0x2C, 0x2C, 0xAF, 0xAC, 0x95, 0x21, 0x7D,
+  0xAC, 0x8C, 0x46, 0xC4, 0x62, 0x8B, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x62, 0xC9, 0x30, 0x7B, 0x20, 0x20, 0x20,
+  0x41, 0x4D, 0x3D, 0x85, 0x48, 0x21, 0xDA, 0x3D,
+  0xE9, 0xD6, 0xD9, 0xCD, 0x5C, 0xE8, 0xE8, 0xE8,
+  0xE8, 0x4D, 0x71, 0x46, 0xEC, 0x2E, 0x72, 0xEC,
+  0x29, 0x29, 0x7C, 0x29, 0x2E, 0x4B, 0x4B, 0x62,
+  0x62, 0x4B, 0x3A, 0xAD, 0xE2, 0xAF, 0xD9, 0xD9,
+  0x2C, 0xDA, 0xDA, 0xDA, 0xDA, 0x85, 0x2C, 0x2C,
+  0x2C, 0xAF, 0xAC, 0xD9, 0x95, 0xD6, 0xD6, 0xD9,
+  0x2C, 0x8C, 0xBA, 0x7C, 0x2E, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x62, 0xC9, 0xDC, 0x34, 0x20, 0x20, 0x20,
+  0x20, 0xAC, 0xE8, 0x5C, 0x8C, 0xBC, 0xE4, 0xE8,
+  0xEE, 0x2A, 0xA3, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+  0xE4, 0x7E, 0x65, 0x46, 0x29, 0x62, 0x62, 0x2E,
+  0x2E, 0x72, 0x2E, 0x2E, 0x32, 0x4B, 0x4B, 0x62,
+  0x4B, 0x4B, 0x4B, 0x32, 0x61, 0x9D, 0x2C, 0xD9,
+  0x2C, 0x85, 0xDA, 0x85, 0x2C, 0xAF, 0xAF, 0xAF,
+  0x2C, 0xAC, 0xD9, 0x95, 0xD6, 0x7D, 0x95, 0xAC,
+  0x2C, 0xDA, 0x40, 0x7C, 0x2E, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x62, 0x62, 0x22, 0xB7, 0xCE, 0x20, 0x20,
+  0x20, 0x95, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0x5C,
+  0x3D, 0xE9, 0x9A, 0x46, 0x7C, 0x32, 0x8B, 0x62,
+  0x4B, 0x8B, 0x8B, 0x4B, 0x4B, 0x4B, 0x4B, 0x62,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x62, 0x61, 0x4E, 0xDA,
+  0x85, 0x85, 0x85, 0x2C, 0xD9, 0xD9, 0xD9, 0xD9,
+  0x85, 0xD9, 0x7D, 0x21, 0x21, 0xD6, 0xAC, 0x2C,
+  0x2C, 0xDA, 0xDD, 0x77, 0x8B, 0x62, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
+  0x3E, 0x8B, 0x32, 0xC9, 0x22, 0x68, 0x88, 0x33,
+  0xA1, 0x73, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+  0xE8, 0xE8, 0xE8, 0x5C, 0x5C, 0x5C, 0x5C, 0x3D,
+  0x89, 0x20, 0x54, 0x23, 0x29, 0x2E, 0x4B, 0x62,
+  0x4B, 0x3E, 0x4B, 0x62, 0x4B, 0x4B, 0x4B, 0x8B,
+  0x8B, 0xC9, 0x6F, 0x4B, 0x8B, 0x4B, 0x78, 0xE2,
+  0x8A, 0x8A, 0x85, 0xAC, 0xD9, 0x7D, 0xD9, 0xAC,
+  0x2C, 0xD9, 0xD6, 0xB2, 0x21, 0x7D, 0xAF, 0x85,
+  0x2C, 0xDA, 0x40, 0xEF, 0x62, 0x62, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x8B, 0x4B, 0xC9, 0x63, 0xB4, 0x5C,
+  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+  0xE8, 0xE8, 0xE8, 0xE8, 0x5C, 0x5C, 0xCD, 0xAE,
+  0x20, 0x20, 0xCE, 0xE1, 0x57, 0x32, 0x4B, 0x4B,
+  0x8B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
+  0x8B, 0x4B, 0x62, 0x4B, 0x62, 0x2E, 0x61, 0x28,
+  0x8D, 0xDA, 0xAF, 0xD9, 0x95, 0x95, 0xD9, 0xAF,
+  0xAF, 0xD9, 0xD6, 0xB2, 0x21, 0xD9, 0x2C, 0x85,
+  0xAF, 0xEB, 0xE1, 0x57, 0x2E, 0x62, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x3E, 0x9B, 0x31, 0x6E,
+  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+  0x5C, 0xE8, 0xE8, 0xE8, 0x3D, 0x7D, 0x33, 0x6B,
+  0x20, 0x20, 0x34, 0x23, 0x29, 0x3E, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x3E, 0x62, 0x62, 0x2E, 0xC4, 0x49, 0xD5,
+  0xDA, 0xD9, 0xD6, 0xA1, 0xA1, 0x21, 0xD9, 0xD9,
+  0xD9, 0x95, 0x21, 0x48, 0xD6, 0xAC, 0x85, 0x85,
+  0xAF, 0xB6, 0x5D, 0x2E, 0x32, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x62, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x62, 0x2E, 0x45, 0xDE,
+  0xDA, 0x5C, 0xE8, 0x5C, 0xE8, 0xE8, 0x5C, 0xE8,
+  0x5C, 0x5C, 0xA3, 0xAC, 0x2B, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x34, 0x23, 0x29, 0x62, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x62, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x3E, 0x3E, 0x63, 0x40, 0x97, 0x28, 0xDA,
+  0xD9, 0xA1, 0x48, 0xE9, 0x48, 0x21, 0xD9, 0xD9,
+  0xA1, 0xB2, 0xB2, 0xA1, 0x21, 0xAC, 0x85, 0x2C,
+  0xDA, 0x36, 0x77, 0x72, 0x62, 0x8B, 0x62, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x3E, 0xEC, 0x2F, 0x51,
+  0xE3, 0xAE, 0x48, 0x2C, 0xDA, 0xDA, 0x85, 0xAC,
+  0x48, 0x9E, 0x88, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x41, 0xA0, 0x23, 0x72, 0x2E, 0x4B, 0x4B,
+  0x4B, 0x62, 0x62, 0x4B, 0x4B, 0x4B, 0x2E, 0x8B,
+  0xF0, 0x4C, 0x40, 0xC2, 0x90, 0x8D, 0x85, 0xD9,
+  0xA1, 0x6C, 0x6C, 0x48, 0xD6, 0xD9, 0xAF, 0xAC,
+  0xA1, 0xD6, 0xD6, 0xB2, 0xD6, 0xAC, 0x85, 0x85,
+  0x4D, 0xBE, 0x39, 0x4C, 0x57, 0x2E, 0x2E, 0x2E,
+  0x3E, 0x3E, 0x62, 0x3E, 0x4B, 0x4B, 0x4B, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x8B, 0x8B, 0x57, 0x60, 0x76,
+  0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x3C, 0xA0, 0x23, 0x7C, 0x2E, 0x4B, 0x4B,
+  0x8B, 0x62, 0x4B, 0x4B, 0x3E, 0x7A, 0xF0, 0x29,
+  0x36, 0x97, 0xBC, 0x8A, 0x8D, 0xDA, 0xD9, 0x48,
+  0x81, 0x2D, 0x48, 0xD6, 0xD9, 0xAF, 0x2C, 0x2C,
+  0xAC, 0xAF, 0xD9, 0x7D, 0x7D, 0x2C, 0x85, 0x85,
+  0x85, 0xB4, 0x66, 0x23, 0x46, 0x2F, 0x60, 0x68,
+  0x77, 0x29, 0x29, 0xF0, 0x2E, 0x2E, 0x62, 0x4B,
+  0x4B, 0x4B, 0x4B, 0x4B, 0x32, 0x7C, 0x83, 0xB3,
+  0x54, 0x6B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x6B, 0x7B, 0xC3, 0xE7, 0x39, 0x72, 0x62, 0x62,
+  0x62, 0x62, 0x62, 0x2E, 0x29, 0x77, 0xA7, 0x36,
+  0xB8, 0x85, 0x85, 0x8D, 0x8D, 0x85, 0xB2, 0x2D,
+  0x2D, 0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
+  0x2A, 0x85, 0xAC, 0x95, 0x95, 0xAF, 0x85, 0x85,
+  0xAF, 0x8C, 0xDF, 0xC6, 0xB1, 0xD1, 0xE5, 0xE7,
+  0x83, 0x23, 0x5D, 0x60, 0x39, 0x77, 0xEC, 0x2E,
+  0x2E, 0x32, 0x32, 0x2E, 0x7C, 0x5D, 0x35, 0xA2,
+  0x54, 0x6B, 0x6B, 0x20, 0x6B, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x6B, 0x88, 0xC1, 0x35, 0xE1, 0x77, 0x57, 0x2E,
+  0x2E, 0x72, 0x29, 0x77, 0x60, 0xB5, 0x44, 0xE2,
+  0x2C, 0x2C, 0xDA, 0x8A, 0xDA, 0xAF, 0xA1, 0x2D,
+  0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85, 0x85,
+  0xEE, 0xAF, 0xD9, 0x7D, 0xD9, 0x2C, 0xDA, 0x85,
+  0xAC, 0xAF, 0x85, 0xDA, 0x8A, 0x2A, 0xE2, 0x50,
+  0x86, 0xD7, 0x75, 0x35, 0xA8, 0xE7, 0xE1, 0x5D,
+  0x68, 0x7C, 0xF1, 0x68, 0xE1, 0xBF, 0xA2, 0xC1,
+  0x52, 0x2B, 0x7D, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C,
+  0x2C, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0x2C, 0x95,
+  0xE9, 0x74, 0xCE, 0xE0, 0xE7, 0x60, 0x77, 0x77,
+  0x7C, 0xEF, 0x5D, 0x23, 0x3F, 0xB6, 0x8A, 0x2C,
+  0xAC, 0xAF, 0x85, 0x8A, 0x85, 0xD9, 0x48, 0x48,
+  0xB2, 0x95, 0x95, 0xD9, 0x85, 0xDA, 0x85, 0x85,
+  0xD3, 0xB2, 0x21, 0x7D, 0xAC, 0x2C, 0xDA, 0x85,
+  0xAC, 0xAC, 0x85, 0x85, 0x85, 0x2C, 0xAF, 0x2C,
+  0xDA, 0x8C, 0x79, 0xC7, 0xB0, 0x51, 0xB3, 0x35,
+  0xBF, 0xE5, 0xE7, 0xA8, 0xE0, 0xA2, 0xC1, 0x34,
+  0x7D, 0x85, 0xAC, 0xD9, 0xAC, 0xAF, 0xAC, 0xAC,
+  0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0x85,
+  0xC8, 0xCD, 0x6A, 0x26, 0x35, 0x3F, 0x83, 0x23,
+  0x23, 0xE7, 0xBF, 0x96, 0xEB, 0xDA, 0xDA, 0x2C,
+  0x2C, 0x2C, 0x85, 0xDA, 0x2C, 0x7D, 0xA1, 0x48,
+  0xB2, 0x21, 0xD6, 0xD9, 0x2C, 0xDA, 0x85, 0xAF,
+  0xAF, 0x2D, 0xE9, 0x7D, 0xAC, 0x2C, 0x85, 0x2C,
+  0xD9, 0xD9, 0xAF, 0x85, 0x85, 0x85, 0x2C, 0x2C,
+  0x2C, 0x85, 0xD9, 0x21, 0xAC, 0x2C, 0xBD, 0xA5,
+  0xC3, 0xA2, 0xA2, 0xA2, 0x26, 0xC1, 0xCE, 0x2A,
+  0xAF, 0x95, 0xD9, 0x2C, 0x2C, 0x85, 0x2C, 0xAF,
+  0xAC, 0x2C, 0x85, 0x2C, 0xAF, 0x2C, 0x85, 0xDA,
+  0x8D, 0x2A, 0x85, 0x34, 0xC1, 0xB3, 0x76, 0x35,
+  0xE0, 0x30, 0xA5, 0xB6, 0x2C, 0x85, 0x85, 0x85,
+  0xAF, 0x2C, 0x85, 0x85, 0xD9, 0xD6, 0xA1, 0xA1,
+  0x48, 0xA1, 0xD6, 0xAF, 0xDA, 0x8A, 0x2C, 0xD9,
+  0xB2, 0x2D, 0x48, 0xD9, 0xAF, 0x2C, 0x2C, 0x85,
+  0xAF, 0xAC, 0x2C, 0x85, 0x85, 0x85, 0xAF, 0xAC,
+  0xAC, 0x2C, 0xD9, 0xD6, 0xD6, 0x21, 0xB2, 0x2C,
+  0xC8, 0x3B, 0x65, 0xC5, 0xCE, 0x8E, 0xC8, 0x2C,
+  0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0x2C, 0xAF, 0xAC,
+  0xAC, 0xAF, 0x2C, 0x85, 0x2C, 0x2C, 0x2C, 0x85,
+  0xDA, 0x2C, 0xD6, 0xAF, 0x59, 0x65, 0xDE, 0xF3,
+  0xF3, 0x59, 0xBC, 0xAC, 0xAF, 0x85, 0x85, 0x85,
+  0xAF, 0xD9, 0xAF, 0x2C, 0xD9, 0xD6, 0xD6, 0xD6,
+  0x21, 0xD6, 0xD9, 0xDA, 0x8D, 0x8A, 0x2C, 0xD9,
+  0xB2, 0xA1, 0xD6, 0xAC, 0x2C, 0x2C, 0x2C, 0x85,
+  0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85, 0xAF, 0xD9,
+  0xD9, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC,
+  0x85, 0x2A, 0x4D, 0xBC, 0x85, 0xAC, 0xAF, 0xAF,
+  0xAC, 0xD9, 0xAF, 0x2C, 0xAF, 0xD9, 0xD9, 0xAC,
+  0xAC, 0xAF, 0x85, 0x2C, 0x85, 0x2C, 0x2C, 0x2C,
+  0x2C, 0xD9, 0xB2, 0xD4, 0xD6, 0x2C, 0x8A, 0xDA,
+  0xC8, 0x85, 0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85,
+  0xAF, 0xAC, 0xD9, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
+  0xD9, 0xAC, 0xDA, 0x8D, 0xBC, 0xDA, 0xD9, 0x95,
+  0x95, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C, 0x85,
+  0x2C, 0xAF, 0xAF, 0x85, 0x85, 0x85, 0x2C, 0xAC,
+  0xD9, 0xAF, 0xAF, 0xAF, 0x2C, 0x2C, 0x2C, 0x85,
+  0x8A, 0x2A, 0x8D, 0x2C, 0xD9, 0x95, 0xAC, 0xAC,
+  0xD9, 0xD9, 0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xAF,
+  0xAF, 0x2C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x2C,
+  0x85, 0x2C, 0xD9, 0xD9, 0xD9, 0x2C, 0x2C, 0x2C,
+  0x2C, 0x85, 0x85, 0xAF, 0xAF, 0x85, 0x85, 0x85,
+  0xAF, 0xD9, 0xD9, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C,
+  0x2C, 0x85, 0x8A, 0x2A, 0x8D, 0x2C, 0xD9, 0xD9,
+  0x2C, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
+  0x85, 0xAF, 0xAC, 0x2C, 0x2C, 0x2C, 0x2C, 0xAC,
+  0xD9, 0xD9, 0xAF, 0x85, 0x85, 0x85, 0xDA, 0xDA,
+  0x8A, 0x8A, 0x85, 0xAC, 0xD9, 0xD9, 0xAC, 0xD9,
+  0xD6, 0xD6, 0x7D, 0x95, 0x7D, 0xD9, 0xAF, 0xAF,
+  0xAF, 0x2C, 0x85, 0x85, 0xDA, 0x85, 0x2C, 0x85,
+  0x85, 0x2C, 0xAF, 0xAC, 0xAF, 0xAF, 0x2C, 0x2C,
+  0x2C, 0x2C, 0x2C, 0xAF, 0xAC, 0x2C, 0x2C, 0x2C,
+  0x2C, 0xAF, 0xD9, 0xAC, 0xAF, 0x2C, 0x85, 0x85,
+  0x85, 0xDA, 0x8D, 0x8A, 0x85, 0xAC, 0x95, 0xD9
+};
+
+#define INCLUDE_LINUX_LOGOBW
+#define INCLUDE_LINUX_LOGO16
+#include <linux/linux_logo.h>
+
+#else
+
+/* prototypes only */
+extern unsigned char linux_logo_red[];
+extern unsigned char linux_logo_green[];
+extern unsigned char linux_logo_blue[];
+extern unsigned char linux_logo[];
+extern unsigned char linux_logo_bw[];
+extern unsigned char linux_logo16_red[];
+extern unsigned char linux_logo16_green[];
+extern unsigned char linux_logo16_blue[];
+extern unsigned char linux_logo16[];
+
+#endif
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/m48t35.h linux/include/asm-mips64/m48t35.h
--- v2.3.47/linux/include/asm-mips64/m48t35.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/m48t35.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,32 @@
+/*
+ *  Registers for the SGS-Thomson M48T35 Timekeeper RAM chip
+ */
+
+#ifndef _ASM_M48T35_H
+#define _ASM_M48T35_H
+
+struct m48t35_rtc {
+        volatile u8         pad[0x7ff8];    /* starts at 0x7ff8 */
+        volatile u8         control;
+        volatile u8         sec;
+        volatile u8         min;
+        volatile u8         hour;
+        volatile u8         day;
+        volatile u8         date;
+        volatile u8         month;
+        volatile u8         year;
+};
+
+#define M48T35_RTC_SET      0x80
+#define M48T35_RTC_STOPPED  0x80
+#define M48T35_RTC_READ     0x40
+
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(x)   ((x)=((x)&15) + ((x)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(x)   ((x)=(((x)/10)<<4) + (x)%10)
+#endif
+
+#endif
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/mc146818rtc.h linux/include/asm-mips64/mc146818rtc.h
--- v2.3.47/linux/include/asm-mips64/mc146818rtc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/mc146818rtc.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,46 @@
+/* $Id: mc146818rtc.h,v 1.1 1999/08/19 22:56:34 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Machine dependent access functions for RTC registers.
+ *
+ * Copyright (C) 1996, 1997, 1998 Ralf Baechle
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x)	(0x70 + (x))
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+rtc_ops->rtc_read_data(addr); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+rtc_ops->rtc_write_data(val, addr); \
+})
+#define RTC_ALWAYS_BCD \
+rtc_ops->rtc_bcd_mode()
+
+/*
+ * This structure defines how to access various features of
+ * different machine types and how to access them.
+ */
+struct rtc_ops {
+	/* How to access the RTC register in a DS1287.  */
+	unsigned char (*rtc_read_data)(unsigned long addr);
+	void (*rtc_write_data)(unsigned char data, unsigned long addr);
+	int (*rtc_bcd_mode)(void);
+};
+
+extern struct rtc_ops *rtc_ops;
+
+#endif /* _ASM_MC146818RTC_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/mipsregs.h linux/include/asm-mips64/mipsregs.h
--- v2.3.47/linux/include/asm-mips64/mipsregs.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/mipsregs.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,365 @@
+/* $Id: mipsregs.h,v 1.2 2000/01/17 23:32:47 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1997, 1999 by Ralf Baechle
+ * Modified for further R[236]000 support by Paul M. Antoine, 1996.
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_MIPSREGS_H
+#define _ASM_MIPSREGS_H
+
+#include <linux/linkage.h>
+
+/*
+ * The following macros are especially useful for __asm__
+ * inline assembler.
+ */
+#ifndef __STR
+#define __STR(x) #x
+#endif
+#ifndef STR
+#define STR(x) __STR(x)
+#endif
+
+/*
+ * Coprocessor 0 register names
+ */
+#define CP0_INDEX $0
+#define CP0_RANDOM $1
+#define CP0_ENTRYLO0 $2
+#define CP0_ENTRYLO1 $3
+#define CP0_CONTEXT $4
+#define CP0_PAGEMASK $5
+#define CP0_WIRED $6
+#define CP0_BADVADDR $8
+#define CP0_COUNT $9
+#define CP0_ENTRYHI $10
+#define CP0_COMPARE $11
+#define CP0_STATUS $12
+#define CP0_CAUSE $13
+#define CP0_EPC $14
+#define CP0_PRID $15
+#define CP0_CONFIG $16
+#define CP0_LLADDR $17
+#define CP0_WATCHLO $18
+#define CP0_WATCHHI $19
+#define CP0_XCONTEXT $20
+#define CP0_FRAMEMASK $21
+#define CP0_DIAGNOSTIC $22
+#define CP0_PERFORMANCE $25
+#define CP0_ECC $26
+#define CP0_CACHEERR $27
+#define CP0_TAGLO $28
+#define CP0_TAGHI $29
+#define CP0_ERROREPC $30
+
+/*
+ * Coprocessor 1 (FPU) register names
+ */
+#define CP1_REVISION   $0
+#define CP1_STATUS     $31
+
+/*
+ * Values for PageMask register
+ */
+#define PM_4K   0x00000000
+#define PM_16K  0x00006000
+#define PM_64K  0x0001e000
+#define PM_256K 0x0007e000
+#define PM_1M   0x001fe000
+#define PM_4M   0x007fe000
+#define PM_16M  0x01ffe000
+
+/*
+ * Values used for computation of new tlb entries
+ */
+#define PL_4K   12
+#define PL_16K  14
+#define PL_64K  16
+#define PL_256K 18
+#define PL_1M   20
+#define PL_4M   22
+#define PL_16M  24
+
+/*
+ * Macros to access the system control coprocessor
+ */
+#define read_32bit_cp0_register(source)                         \
+({ int __res;                                                   \
+        __asm__ __volatile__(                                   \
+        "mfc0\t%0,"STR(source)                                  \
+        : "=r" (__res));                                        \
+        __res;})
+
+#define read_64bit_cp0_register(source)                         \
+({ int __res;                                                   \
+        __asm__ __volatile__(                                   \
+        ".set\tmips3\n\t"                                       \
+        "dmfc0\t%0,"STR(source)"\n\t"                           \
+        ".set\tmips0"                                           \
+        : "=r" (__res));                                        \
+        __res;})
+
+#define write_32bit_cp0_register(register,value)                \
+        __asm__ __volatile__(                                   \
+        "mtc0\t%0,"STR(register)                                \
+        : : "r" (value));
+
+#define write_64bit_cp0_register(register,value)                \
+        __asm__ __volatile__(                                   \
+        ".set\tmips3\n\t"                                       \
+        "dmtc0\t%0,"STR(register)"\n\t"                         \
+        ".set\tmips0"                                           \
+        : : "r" (value))
+
+/*
+ * R4x00 interrupt enable / cause bits
+ */
+#define IE_SW0          (1<< 8)
+#define IE_SW1          (1<< 9)
+#define IE_IRQ0         (1<<10)
+#define IE_IRQ1         (1<<11)
+#define IE_IRQ2         (1<<12)
+#define IE_IRQ3         (1<<13)
+#define IE_IRQ4         (1<<14)
+#define IE_IRQ5         (1<<15)
+
+/*
+ * R4x00 interrupt cause bits
+ */
+#define C_SW0           (1<< 8)
+#define C_SW1           (1<< 9)
+#define C_IRQ0          (1<<10)
+#define C_IRQ1          (1<<11)
+#define C_IRQ2          (1<<12)
+#define C_IRQ3          (1<<13)
+#define C_IRQ4          (1<<14)
+#define C_IRQ5          (1<<15)
+
+#ifndef _LANGUAGE_ASSEMBLY
+/*
+ * Manipulate the status register.
+ * Mostly used to access the interrupt bits.
+ */
+#define __BUILD_SET_CP0(name,register)                          \
+extern __inline__ unsigned int                                  \
+set_cp0_##name(unsigned int change, unsigned int new)           \
+{                                                               \
+	unsigned int res;                                       \
+                                                                \
+	res = read_32bit_cp0_register(register);                \
+	res &= ~change;                                         \
+	res |= (new & change);                                  \
+	write_32bit_cp0_register(register, res);                \
+                                                                \
+	return res;                                             \
+}
+
+__BUILD_SET_CP0(status,CP0_STATUS)
+__BUILD_SET_CP0(cause,CP0_CAUSE)
+__BUILD_SET_CP0(config,CP0_CONFIG)
+
+#endif /* defined (_LANGUAGE_ASSEMBLY) */
+
+/*
+ * Inline code for use of the ll and sc instructions
+ *
+ * FIXME: This instruction is only available on MIPS ISA >=2.
+ * Since these operations are only being used for atomic operations
+ * the easiest workaround for the R[23]00 is to disable interrupts.
+ * This fails for R3000 SMP machines which use that many different
+ * technologies as replacement that it is difficult to create even
+ * just a hook for for all machines to hook into.  The only good
+ * thing is that there is currently no R3000 SMP machine on the
+ * Linux/MIPS target list ...
+ */
+#define load_linked(addr)                                       \
+({                                                              \
+	unsigned int __res;                                     \
+                                                                \
+	__asm__ __volatile__(                                   \
+	"ll\t%0,(%1)"                                           \
+	: "=r" (__res)                                          \
+	: "r" ((unsigned long) (addr)));                        \
+                                                                \
+	__res;                                                  \
+})
+
+#define store_conditional(addr,value)                           \
+({                                                              \
+	int	__res;                                          \
+                                                                \
+	__asm__ __volatile__(                                   \
+	"sc\t%0,(%2)"                                           \
+	: "=r" (__res)                                          \
+	: "0" (value), "r" (addr));                             \
+                                                                \
+	__res;                                                  \
+})
+
+/*
+ * Bitfields in the R4xx0 cp0 status register
+ */
+#define ST0_IE			0x00000001
+#define ST0_EXL			0x00000002
+#define ST0_ERL			0x00000004
+#define ST0_KSU			0x00000018
+#  define KSU_USER		0x00000010
+#  define KSU_SUPERVISOR	0x00000008
+#  define KSU_KERNEL		0x00000000
+#define ST0_UX			0x00000020
+#define ST0_SX			0x00000040
+#define ST0_KX 			0x00000080
+
+/*
+ * Status register bits available in all MIPS CPUs.
+ */
+#define ST0_IM			0x0000ff00
+#define  STATUSB_IP0		8
+#define  STATUSF_IP0		(1   <<  8)
+#define  STATUSB_IP1		9
+#define  STATUSF_IP1		(1   <<  9)
+#define  STATUSB_IP2		10
+#define  STATUSF_IP2		(1   << 10)
+#define  STATUSB_IP3		11
+#define  STATUSF_IP3		(1   << 11)
+#define  STATUSB_IP4		12
+#define  STATUSF_IP4		(1   << 12)
+#define  STATUSB_IP5		13
+#define  STATUSF_IP5		(1   << 13)
+#define  STATUSB_IP6		14
+#define  STATUSF_IP6		(1   << 14)
+#define  STATUSB_IP7		15
+#define  STATUSF_IP7		(1   << 15)
+#define ST0_DE			0x00010000
+#define ST0_CE			0x00020000
+#define ST0_CH			0x00040000
+#define ST0_SR			0x00100000
+#define ST0_BEV			0x00400000
+#define ST0_RE			0x02000000
+#define ST0_FR			0x04000000
+#define ST0_CU			0xf0000000
+#define ST0_CU0			0x10000000
+#define ST0_CU1			0x20000000
+#define ST0_CU2			0x40000000
+#define ST0_CU3			0x80000000
+#define ST0_XX			0x80000000	/* MIPS IV naming */
+
+/*
+ * Bitfields and bit numbers in the coprocessor 0 cause register.
+ *
+ * Refer to to your MIPS R4xx0 manual, chapter 5 for explanation.
+ */
+#define  CAUSEB_EXCCODE		2
+#define  CAUSEF_EXCCODE		(31  <<  2)
+#define  CAUSEB_IP		8
+#define  CAUSEF_IP		(255 <<  8)
+#define  CAUSEB_IP0		8
+#define  CAUSEF_IP0		(1   <<  8)
+#define  CAUSEB_IP1		9
+#define  CAUSEF_IP1		(1   <<  9)
+#define  CAUSEB_IP2		10
+#define  CAUSEF_IP2		(1   << 10)
+#define  CAUSEB_IP3		11
+#define  CAUSEF_IP3		(1   << 11)
+#define  CAUSEB_IP4		12
+#define  CAUSEF_IP4		(1   << 12)
+#define  CAUSEB_IP5		13
+#define  CAUSEF_IP5		(1   << 13)
+#define  CAUSEB_IP6		14
+#define  CAUSEF_IP6		(1   << 14)
+#define  CAUSEB_IP7		15
+#define  CAUSEF_IP7		(1   << 15)
+#define  CAUSEB_IV		23
+#define  CAUSEF_IV		(1   << 23)
+#define  CAUSEB_CE		28
+#define  CAUSEF_CE		(3   << 28)
+#define  CAUSEB_BD		31
+#define  CAUSEF_BD		(1   << 31)
+
+/*
+ * Bits in the coprozessor 0 config register.
+ */
+#define CONF_CM_CACHABLE_NO_WA		0
+#define CONF_CM_CACHABLE_WA		1
+#define CONF_CM_UNCACHED		2
+#define CONF_CM_CACHABLE_NONCOHERENT	3
+#define CONF_CM_CACHABLE_CE		4
+#define CONF_CM_CACHABLE_COW		5
+#define CONF_CM_CACHABLE_CUW		6
+#define CONF_CM_CACHABLE_ACCELERATED	7
+#define CONF_CM_CMASK			7
+#define CONF_DB				(1 <<  4)
+#define CONF_IB				(1 <<  5)
+#define CONF_SC				(1 << 17)
+
+/*
+ * R10000 performance counter definitions.
+ *
+ * FIXME: The R10000 performance counter opens a nice way to implement CPU
+ *        time accounting with a precission of one cycle.  I don't have
+ *        R10000 silicon but just a manual, so ...
+ */
+
+/*
+ * Events counted by counter #0
+ */
+#define CE0_CYCLES			0
+#define CE0_INSN_ISSUED			1
+#define CE0_LPSC_ISSUED			2
+#define CE0_S_ISSUED			3
+#define CE0_SC_ISSUED			4
+#define CE0_SC_FAILED			5
+#define CE0_BRANCH_DECODED		6
+#define CE0_QW_WB_SECONDARY		7
+#define CE0_CORRECTED_ECC_ERRORS	8
+#define CE0_ICACHE_MISSES		9
+#define CE0_SCACHE_I_MISSES		10
+#define CE0_SCACHE_I_WAY_MISSPREDICTED	11
+#define CE0_EXT_INTERVENTIONS_REQ	12
+#define CE0_EXT_INVALIDATE_REQ		13
+#define CE0_VIRTUAL_COHERENCY_COND	14
+#define CE0_INSN_GRADUATED		15
+
+/*
+ * Events counted by counter #1
+ */
+#define CE1_CYCLES			0
+#define CE1_INSN_GRADUATED		1
+#define CE1_LPSC_GRADUATED		2
+#define CE1_S_GRADUATED			3
+#define CE1_SC_GRADUATED		4
+#define CE1_FP_INSN_GRADUATED		5
+#define CE1_QW_WB_PRIMARY		6
+#define CE1_TLB_REFILL			7
+#define CE1_BRANCH_MISSPREDICTED	8
+#define CE1_DCACHE_MISS			9
+#define CE1_SCACHE_D_MISSES		10
+#define CE1_SCACHE_D_WAY_MISSPREDICTED	11
+#define CE1_EXT_INTERVENTION_HITS	12
+#define CE1_EXT_INVALIDATE_REQ		13
+#define CE1_SP_HINT_TO_CEXCL_SC_BLOCKS	14
+#define CE1_SP_HINT_TO_SHARED_SC_BLOCKS	15
+
+/*
+ * These flags define in which priviledge mode the counters count events
+ */
+#define CEB_USER	8	/* Count events in user mode, EXL = ERL = 0 */
+#define CEB_SUPERVISOR	4	/* Count events in supvervisor mode EXL = ERL = 0 */
+#define CEB_KERNEL	2	/* Count events in kernel mode EXL = ERL = 0 */
+#define CEB_EXL		1	/* Count events with EXL = 1, ERL = 0 */
+
+#ifndef _LANGUAGE_ASSEMBLY
+/*
+ * Functions to access the performance counter and control registers
+ */
+extern asmlinkage unsigned int read_perf_cntr(unsigned int counter);
+extern asmlinkage void write_perf_cntr(unsigned int counter, unsigned int val);
+extern asmlinkage unsigned int read_perf_cntl(unsigned int counter);
+extern asmlinkage void write_perf_cntl(unsigned int counter, unsigned int val);
+#endif
+
+#endif /* _ASM_MIPSREGS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/mman.h linux/include/asm-mips64/mman.h
--- v2.3.47/linux/include/asm-mips64/mman.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/mman.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,62 @@
+/* $Id: mman.h,v 1.3 2000/02/04 23:12:27 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_MMAN_H
+#define _ASM_MMAN_H
+
+/*
+ * Protections are chosen from these bits, OR'd together.  The
+ * implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ * without PROT_READ.  The only guarantees are that no writing will be
+ * allowed without PROT_WRITE and no access will be allowed for PROT_NONE.
+ */
+#define PROT_NONE	0x0		/* page can not be accessed */
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+
+/*
+ * Flags for mmap
+ */
+#define MAP_SHARED	0x001		/* Share changes */
+#define MAP_PRIVATE	0x002		/* Changes are private */
+#define MAP_TYPE	0x00f		/* Mask for type of mapping */
+#define MAP_FIXED	0x010		/* Interpret addr exactly */
+
+/* not used by linux, but here to make sure we don't clash with ABI defines */
+#define MAP_RENAME	0x020		/* Assign page to file */
+#define MAP_AUTOGROW	0x040		/* File may grow by writing */
+#define MAP_LOCAL	0x080		/* Copy on fork/sproc */
+#define MAP_AUTORSRV	0x100		/* Logical swap reserved on demand */
+
+/* These are linux-specific */
+#define MAP_NORESERVE	0x0400		/* don't check for reservations */
+#define MAP_ANONYMOUS	0x0800		/* don't use a file */
+#define MAP_GROWSDOWN	0x1000		/* stack-like segment */
+#define MAP_DENYWRITE	0x2000		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x4000		/* mark it as an executable */
+#define MAP_LOCKED	0x8000		/* pages are locked */
+
+/*
+ * Flags for msync
+ */
+#define MS_ASYNC	0x0001		/* sync memory asynchronously */
+#define MS_INVALIDATE	0x0002		/* invalidate mappings & caches */
+#define MS_SYNC		0x0004		/* synchronous memory sync */
+
+/*
+ * Flags for mlockall
+ */
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+/* compatibility flags */
+#define MAP_ANON       MAP_ANONYMOUS
+#define MAP_FILE       0
+
+#endif /* _ASM_MMAN_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/mmu_context.h linux/include/asm-mips64/mmu_context.h
--- v2.3.47/linux/include/asm-mips64/mmu_context.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/mmu_context.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,93 @@
+/* $Id: mmu_context.h,v 1.4 2000/02/23 00:41:38 ralf Exp $
+ *
+ * Switch a MMU context.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_MMU_CONTEXT_H
+#define _ASM_MMU_CONTEXT_H
+
+#include <linux/config.h>
+#include <asm/pgalloc.h>
+
+/* Fuck.  The f-word is here so you can grep for it :-)  */
+extern unsigned long asid_cache;
+extern pgd_t *current_pgd;
+
+#define ASID_INC	0x1
+#define ASID_MASK	0xff
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+/*
+ *  All unused by hardware upper bits will be considered
+ *  as a software asid extension.
+ */
+#define ASID_VERSION_MASK  ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
+#define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)
+
+extern inline void
+get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
+{
+	if (! ((asid += ASID_INC) & ASID_MASK) ) {
+		flush_tlb_all(); /* start new asid cycle */
+		if (!asid)      /* fix version if needed */
+			asid = ASID_FIRST_VERSION;
+	}
+	mm->context = asid_cache = asid;
+}
+
+/*
+ * Initialize the context related info for a new mm_struct
+ * instance.
+ */
+extern inline void
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	mm->context = 0;
+}
+
+extern inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+                             struct task_struct *tsk, unsigned cpu)
+{
+	unsigned long asid = asid_cache;
+
+	/* Check if our ASID is of an older version and thus invalid */
+	if ((next->context ^ asid) & ASID_VERSION_MASK)
+		get_new_mmu_context(next, asid);
+
+	current_pgd = next->pgd;
+	set_entryhi(next->context);
+}
+
+/*
+ * Destroy context related info for an mm_struct that is about
+ * to be put to rest.
+ */
+extern inline void destroy_context(struct mm_struct *mm)
+{
+	/* Nothing to do.  */
+}
+
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+extern inline void
+activate_mm(struct mm_struct *prev, struct mm_struct *next)
+{
+	/* Unconditionally get a new ASID.  */
+	get_new_mmu_context(next, asid_cache);
+
+	current_pgd = next->pgd;
+	set_entryhi(next->context);
+}
+
+#endif /* _ASM_MMU_CONTEXT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/mmzone.h linux/include/asm-mips64/mmzone.h
--- v2.3.47/linux/include/asm-mips64/mmzone.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/mmzone.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,82 @@
+/*
+ * Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99
+ */
+#ifndef _ASM_MMZONE_H_
+#define _ASM_MMZONE_H_
+
+#include <asm/sn/types.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+
+typedef struct plat_pglist_data {
+	pg_data_t	gendata;
+	unsigned long	physstart;
+	unsigned long	size;
+	unsigned long	start_mapnr;
+} plat_pg_data_t;
+
+/*
+ * Following are macros that are specific to this numa platform.
+ */
+
+extern int numa_debug(void);
+extern plat_pg_data_t *plat_node_data[];
+
+#define PHYSADDR_TO_NID(pa)		NASID_TO_COMPACT_NODEID(NASID_GET(pa))
+#define PLAT_NODE_DATA(n)		(plat_node_data[n])
+#define PLAT_NODE_DATA_STARTNR(n)	(PLAT_NODE_DATA(n)->start_mapnr)
+#define PLAT_NODE_DATA_LOCALNR(p, n) \
+			(((p) - PLAT_NODE_DATA(n)->physstart) >> PAGE_SHIFT)
+#define PAGE_TO_PLAT_NODE(p)		(plat_pg_data_t *)((p)->zone->zone_pgdat)
+
+#ifdef CONFIG_DISCONTIGMEM
+
+/*
+ * Following are macros that each numa implmentation must define.
+ */
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ * For production kern_addr_valid, change to return "numnodes" instead
+ * of panicing.
+ */
+#define KVADDR_TO_NID(kaddr) \
+	((NASID_TO_COMPACT_NODEID(NASID_GET(__pa(kaddr))) != -1) ? \
+	(NASID_TO_COMPACT_NODEID(NASID_GET(__pa(kaddr)))) : \
+	(printk("NUMABUG: %s line %d addr 0x%lx", __FILE__, __LINE__, kaddr), \
+	numa_debug(), -1))
+
+/*
+ * Return a pointer to the node data for node n.
+ */
+#define NODE_DATA(n)	(&((PLAT_NODE_DATA(n))->gendata))
+
+/*
+ * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
+ */
+#define NODE_MEM_MAP(nid)	(NODE_DATA(nid)->node_mem_map)
+
+/*
+ * Given a mem_map_t, LOCAL_MAP_BASE finds the owning node for the
+ * physical page and returns the kaddr for the mem_map of that node.
+ */
+#define LOCAL_MAP_BASE(page) \
+			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(page)))
+
+/*
+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
+ * and returns the the mem_map of that node.
+ */
+#define ADDR_TO_MAPBASE(kaddr) \
+			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
+
+/*
+ * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
+ * and returns the kaddr corresponding to first physical page in the
+ * node's mem_map.
+ */
+#define LOCAL_BASE_ADDR(kaddr)	((unsigned long)(kaddr) & ~(NODE_MAX_MEM_SIZE-1))
+
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif /* _ASM_MMZONE_H_ */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/msgbuf.h linux/include/asm-mips64/msgbuf.h
--- v2.3.47/linux/include/asm-mips64/msgbuf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/msgbuf.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,27 @@
+#ifndef _ASM_MSGBUF_H
+#define _ASM_MSGBUF_H
+
+/* 
+ * The msqid64_ds structure for alpha architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 2 miscellaneous 64-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused1;
+	unsigned long  __unused2;
+};
+
+#endif /* _ASM_MSGBUF_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/namei.h linux/include/asm-mips64/namei.h
--- v2.3.47/linux/include/asm-mips64/namei.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/namei.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,19 @@
+/* $Id: namei.h,v 1.1 1999/08/20 21:59:08 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_NAMEI_H
+#define _ASM_NAMEI_H
+
+/*
+ * This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __prefix_lookup_dentry(name, lookup_flags) \
+	do {} while (0)
+
+#endif /* _ASM_NAMEI_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/ng1.h linux/include/asm-mips64/ng1.h
--- v2.3.47/linux/include/asm-mips64/ng1.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/ng1.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,56 @@
+/* $Id: ng1.h,v 1.1 1999/08/19 22:56:34 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SGI/Newport video card ioctl definitions
+ */
+#ifndef _ASM_NG1_H
+#define _ASM_NG1_H
+
+typedef struct {
+        int flags;
+        __u16 w, h;
+        __u16 fields_sec;
+} ng1_vof_info_t;
+
+struct ng1_info {
+	struct gfx_info gfx_info;
+	__u8 boardrev;
+        __u8 rex3rev;
+        __u8 vc2rev;
+        __u8 monitortype;
+        __u8 videoinstalled;
+        __u8 mcrev;
+        __u8 bitplanes;
+        __u8 xmap9rev;
+        __u8 cmaprev;
+        ng1_vof_info_t ng1_vof_info;
+        __u8 bt445rev;
+        __u8 paneltype;
+};
+
+#define GFX_NAME_NEWPORT "NG1"
+
+/* ioctls */
+#define NG1_SET_CURSOR_HOTSPOT 21001
+struct ng1_set_cursor_hotspot {
+	unsigned short xhot;
+        unsigned short yhot;
+};
+
+#define NG1_SETDISPLAYMODE     21006
+struct ng1_setdisplaymode_args {
+        int wid;
+        unsigned int mode;
+};
+
+#define NG1_SETGAMMARAMP0      21007
+struct ng1_setgammaramp_args {
+        unsigned char red   [256];
+        unsigned char green [256];
+        unsigned char blue  [256];
+};
+
+#endif /* _ASM_NG1_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/offset.h linux/include/asm-mips64/offset.h
--- v2.3.47/linux/include/asm-mips64/offset.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/offset.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,98 @@
+/* DO NOT TOUCH, AUTOGENERATED BY OFFSET.C */
+
+#ifndef _MIPS_OFFSET_H
+#define _MIPS_OFFSET_H
+
+/* MIPS pt_regs offsets. */
+#define PT_R0     0
+#define PT_R1     8
+#define PT_R2     16
+#define PT_R3     24
+#define PT_R4     32
+#define PT_R5     40
+#define PT_R6     48
+#define PT_R7     56
+#define PT_R8     64
+#define PT_R9     72
+#define PT_R10    80
+#define PT_R11    88
+#define PT_R12    96
+#define PT_R13    104
+#define PT_R14    112
+#define PT_R15    120
+#define PT_R16    128
+#define PT_R17    136
+#define PT_R18    144
+#define PT_R19    152
+#define PT_R20    160
+#define PT_R21    168
+#define PT_R22    176
+#define PT_R23    184
+#define PT_R24    192
+#define PT_R25    200
+#define PT_R26    208
+#define PT_R27    216
+#define PT_R28    224
+#define PT_R29    232
+#define PT_R30    240
+#define PT_R31    248
+#define PT_LO     256
+#define PT_HI     264
+#define PT_EPC    272
+#define PT_BVADDR 280
+#define PT_STATUS 288
+#define PT_CAUSE  296
+#define PT_SIZE   304
+
+/* MIPS task_struct offsets. */
+#define TASK_STATE         0
+#define TASK_FLAGS         8
+#define TASK_SIGPENDING    16
+#define TASK_NEED_RESCHED  40
+#define TASK_COUNTER       56
+#define TASK_PRIORITY      64
+#define TASK_MM            80
+#define TASK_STRUCT_SIZE   1480
+
+/* MIPS specific thread_struct offsets. */
+#define THREAD_REG16   896
+#define THREAD_REG17   904
+#define THREAD_REG18   912
+#define THREAD_REG19   920
+#define THREAD_REG20   928
+#define THREAD_REG21   936
+#define THREAD_REG22   944
+#define THREAD_REG23   952
+#define THREAD_REG29   960
+#define THREAD_REG30   968
+#define THREAD_REG31   976
+#define THREAD_STATUS  984
+#define THREAD_FPU     992
+#define THREAD_BVADDR  1256
+#define THREAD_BUADDR  1264
+#define THREAD_ECODE   1272
+#define THREAD_TRAPNO  1280
+#define THREAD_MFLAGS  1288
+#define THREAD_CURDS   1296
+#define THREAD_TRAMP   1304
+#define THREAD_OLDCTX  1312
+
+/* Linux mm_struct offsets. */
+#define MM_USERS      32
+#define MM_PGD        24
+#define MM_CONTEXT    112
+
+/* Linux sigcontext offsets. */
+#define SC_REGS       0
+#define SC_FPREGS     256
+#define SC_MDHI       512
+#define SC_MDLO       520
+#define SC_PC         528
+#define SC_STATUS     536
+#define SC_OWNEDFP    540
+#define SC_FPC_CSR    544
+#define SC_FPC_EIR    548
+#define SC_CAUSE      552
+#define SC_BADVADDR   556
+
+#endif /* !(_MIPS_OFFSET_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/paccess.h linux/include/asm-mips64/paccess.h
--- v2.3.47/linux/include/asm-mips64/paccess.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/paccess.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,92 @@
+/* $Id: paccess.h,v 1.3 2000/02/04 07:40:53 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ *
+ * Protected memory access.  Used for everything that might take revenge
+ * by sending a DBE error like accessing possibly non-existant memory or
+ * devices.
+ */
+#ifndef _ASM_PACCESS_H
+#define _ASM_PACCESS_H
+
+#include <linux/errno.h>
+
+#define put_dbe(x,ptr) __put_dbe((x),(ptr),sizeof(*(ptr)))
+#define get_dbe(x,ptr) __get_dbe((x),(ptr),sizeof(*(ptr)))
+
+struct __large_pstruct { unsigned long buf[100]; };
+#define __mp(x) (*(struct __large_pstruct *)(x))
+
+#define __get_dbe(x,ptr,size) ({ \
+long __gu_err; \
+__typeof(*(ptr)) __gu_val; \
+long __gu_addr; \
+__asm__("":"=r" (__gu_val)); \
+__gu_addr = (long) (ptr); \
+__asm__("":"=r" (__gu_err)); \
+switch (size) { \
+case 1: __get_dbe_asm("lb"); break; \
+case 2: __get_dbe_asm("lh"); break; \
+case 4: __get_dbe_asm("lw"); break; \
+case 8:  __get_dbe_asm("ld"); break; \
+default: __get_dbe_unknown(); break; \
+} x = (__typeof__(*(ptr))) __gu_val; __gu_err; })
+
+#define __get_dbe_asm(insn) \
+({ \
+__asm__ __volatile__( \
+	"1:\t" insn "\t%1,%2\n\t" \
+	"move\t%0,$0\n" \
+	"2:\n\t" \
+	".section\t.fixup,\"ax\"\n" \
+	"3:\tli\t%0,%3\n\t" \
+	"move\t%1,$0\n\t" \
+	"j\t2b\n\t" \
+	".previous\n\t" \
+	".section\t__dbe_table,\"a\"\n\t" \
+	".dword\t1b,3b\n\t" \
+	".previous" \
+	:"=r" (__gu_err), "=r" (__gu_val) \
+	:"o" (__mp(__gu_addr)), "i" (-EFAULT)); })
+
+extern void __get_dbe_unknown(void);
+
+#define __put_dbe(x,ptr,size) ({ \
+long __pu_err; \
+__typeof__(*(ptr)) __pu_val; \
+long __pu_addr; \
+__pu_val = (x); \
+__pu_addr = (long) (ptr); \
+__asm__("":"=r" (__pu_err)); \
+switch (size) { \
+case 1: __put_dbe_asm("sb"); break; \
+case 2: __put_dbe_asm("sh"); break; \
+case 4: __put_dbe_asm("sw"); break; \
+case 8: __put_dbe_asm("sd"); break; \
+default: __put_dbe_unknown(); break; \
+} __pu_err; })
+
+#define __put_dbe_asm(insn) \
+({ \
+__asm__ __volatile__( \
+	"1:\t" insn "\t%1,%2\n\t" \
+	"move\t%0,$0\n" \
+	"2:\n\t" \
+	".section\t.fixup,\"ax\"\n" \
+	"3:\tli\t%0,%3\n\t" \
+	"j\t2b\n\t" \
+	".previous\n\t" \
+	".section\t__dbe_table,\"a\"\n\t" \
+	".dword\t1b,3b\n\t" \
+	".previous" \
+	:"=r" (__pu_err) \
+	:"r" (__pu_val), "o" (__mp(__pu_addr)), "i" (-EFAULT)); })
+
+extern void __put_dbe_unknown(void);
+
+#endif /* _ASM_PACCESS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/page.h linux/include/asm-mips64/page.h
--- v2.3.47/linux/include/asm-mips64/page.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/page.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,76 @@
+/* $Id: page.h,v 1.6 2000/02/24 00:13:20 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PAGE_H
+#define _ASM_PAGE_H
+
+#include <linux/config.h>
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	12
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
+#define PAGE_BUG(page) do {  BUG(); } while (0)
+
+extern void (*_clear_page)(void * page);
+extern void (*_copy_page)(void * to, void * from);
+
+#define clear_page(page)	_clear_page(page)
+#define copy_page(to, from)	_copy_page(to, from)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((x).pmd)
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pme(x)	((pme_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+/*
+ * This handles the memory map.
+ * We handle pages at KSEG0 for kernels with upto 512mb of memory,
+ * at XKPHYS for kernels with more than that.
+ */
+#ifdef CONFIG_SGI_IP22
+#define PAGE_OFFSET	0xffffffff80000000UL
+#endif
+#ifdef CONFIG_SGI_IP27
+#define PAGE_OFFSET	0xa800000000000000UL
+#endif
+
+#define __pa(x)		((unsigned long) (x) - PAGE_OFFSET)
+#define __va(x)		((void *)((unsigned long) (x) + PAGE_OFFSET))
+#ifndef CONFIG_DISCONTIGMEM
+#define MAP_NR(addr)	(__pa(addr) >> PAGE_SHIFT)
+#endif
+
+#endif /* defined (__KERNEL__) */
+
+#endif /* _ASM_PAGE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/param.h linux/include/asm-mips64/param.h
--- v2.3.47/linux/include/asm-mips64/param.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/param.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,30 @@
+/* $Id: param.h,v 1.2 2000/01/19 02:08:47 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1994 - 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_PARAM_H
+#define _ASM_PARAM_H
+
+#ifndef HZ
+#define HZ 100
+#  define HZ 100
+#  define HZ_TO_STD(a) (a)
+#endif
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#endif /* _ASM_PARAM_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/parport.h linux/include/asm-mips64/parport.h
--- v2.3.47/linux/include/asm-mips64/parport.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/parport.h	Sat Feb 26 20:34:34 2000
@@ -0,0 +1,61 @@
+/* $Id: parport.h,v 1.2 2000/02/18 00:24:48 ralf Exp $
+ *
+ * parport.h: ia32-specific parport initialisation
+ *
+ * Copyright (C) 1999  Tim Waugh <tim@cyberelk.demon.co.uk>
+ *
+ * This file should only be included by drivers/parport/parport_pc.c.
+ */
+#ifndef _ASM_PARPORT_H
+#define _ASM_PARPORT_H 1
+
+#include <linux/config.h>
+
+/* Maximum number of ports to support.  It is useless to set this greater
+   than PARPORT_MAX (in <linux/parport.h>).  */
+#define PARPORT_PC_MAX_PORTS  8
+
+/* If parport_cs (PCMCIA) is managing ports for us, we'll need the
+ * probing routines forever; otherwise we can lose them at boot time. */
+#ifdef CONFIG_PARPORT_PC_PCMCIA
+#define __maybe_initdata
+#define __maybe_init
+#else
+#define __maybe_initdata __initdata
+#define __maybe_init __init
+#endif
+
+static int __maybe_init parport_pc_init_pci(int irq, int dma);
+
+static int user_specified __maybe_initdata = 0;
+int __init
+parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
+{
+	int count = 0, i = 0;
+
+	if (io && *io) {
+		/* Only probe the ports we were given. */
+		user_specified = 1;
+		do {
+			if (!*io_hi) *io_hi = 0x400 + *io;
+			if (parport_pc_probe_port(*(io++), *(io_hi++),
+						  *(irq++), *(dma++), NULL))
+				count++;
+		} while (*io && (++i < PARPORT_PC_MAX_PORTS));
+	} else {
+		count += parport_pc_init_superio ();
+
+		/* Probe all the likely ports. */
+		if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL))
+			count++;
+		if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0], NULL))
+			count++;
+		if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0], NULL))
+			count++;
+		count += parport_pc_init_pci (irq[0], dma[0]);
+	}
+
+        return count;
+}
+
+#endif /* !(_ASM_PARPORT_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/pci/bridge.h linux/include/asm-mips64/pci/bridge.h
--- v2.3.47/linux/include/asm-mips64/pci/bridge.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/pci/bridge.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,831 @@
+/* $Id: bridge.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * bridge.h - bridge chip header file, derived from IRIX <sys/PCI/bridge.h>,
+ * revision 1.76.
+ *
+ * Copyright (C) 1996, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_PCI_BRIDGE_H
+#define _ASM_PCI_BRIDGE_H
+
+#include <linux/types.h>
+#include <asm/xtalk/xwidget.h>		/* generic widget header */
+
+/* I/O page size */
+
+#define IOPFNSHIFT		12	/* 4K per mapped page */
+
+#define IOPGSIZE		(1 << IOPFNSHIFT)
+#define IOPG(x)			((x) >> IOPFNSHIFT)
+#define IOPGOFF(x)		((x) & (IOPGSIZE-1))
+
+/* Bridge RAM sizes */
+
+#define BRIDGE_ATE_RAM_SIZE	0x00000400	/* 1kB ATE RAM */
+
+#define BRIDGE_CONFIG_BASE	0x20000
+#define BRIDGE_CONFIG1_BASE	0x28000
+#define BRIDGE_CONFIG_END	0x30000
+#define BRIDGE_CONFIG_SLOT_SIZE 0x1000
+
+#define BRIDGE_SSRAM_512K	0x00080000	/* 512kB */
+#define BRIDGE_SSRAM_128K	0x00020000	/* 128kB */
+#define BRIDGE_SSRAM_64K	0x00010000	/* 64kB */
+#define BRIDGE_SSRAM_0K		0x00000000	/* 0kB */
+
+/* ========================================================================
+ *    Bridge address map
+ */
+
+#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+
+/*
+ * All accesses to bridge hardware registers must be done
+ * using 32-bit loads and stores.
+ */
+typedef u32	bridgereg_t;
+
+typedef u64	bridge_ate_t;
+
+/* pointers to bridge ATEs
+ * are always "pointer to volatile"
+ */
+typedef volatile bridge_ate_t  *bridge_ate_p;
+
+/*
+ * It is generally preferred that hardware registers on the bridge
+ * are located from C code via this structure.
+ *
+ * Generated from Bridge spec dated 04oct95
+ */
+
+typedef volatile struct bridge_s {
+	/* Local Registers			       0x000000-0x00FFFF */
+
+	/* standard widget configuration	       0x000000-0x000057 */
+	widget_cfg_t	    b_widget;			/* 0x000000 */
+
+	/* helper fieldnames for accessing bridge widget */
+
+#define b_wid_id			b_widget.w_id
+#define b_wid_stat			b_widget.w_status
+#define b_wid_err_upper			b_widget.w_err_upper_addr
+#define b_wid_err_lower			b_widget.w_err_lower_addr
+#define b_wid_control			b_widget.w_control
+#define b_wid_req_timeout		b_widget.w_req_timeout
+#define b_wid_int_upper			b_widget.w_intdest_upper_addr
+#define b_wid_int_lower			b_widget.w_intdest_lower_addr
+#define b_wid_err_cmdword		b_widget.w_err_cmd_word
+#define b_wid_llp			b_widget.w_llp_cfg
+#define b_wid_tflush			b_widget.w_tflush
+
+	/* bridge-specific widget configuration	0x000058-0x00007F */
+	bridgereg_t	    _pad_000058;
+	bridgereg_t	    b_wid_aux_err;		/* 0x00005C */
+	bridgereg_t	    _pad_000060;
+	bridgereg_t	    b_wid_resp_upper;		/* 0x000064 */
+	bridgereg_t	    _pad_000068;
+	bridgereg_t	    b_wid_resp_lower;		/* 0x00006C */
+	bridgereg_t	    _pad_000070;
+	bridgereg_t	    b_wid_tst_pin_ctrl;		/* 0x000074 */
+	bridgereg_t	_pad_000078[2];
+
+	/* PMU & Map 0x000080-0x00008F */
+	bridgereg_t	_pad_000080;
+	bridgereg_t	b_dir_map;			/* 0x000084 */
+	bridgereg_t	_pad_000088[2];
+
+	/* SSRAM 0x000090-0x00009F */
+	bridgereg_t	_pad_000090;
+	bridgereg_t	b_ram_perr;			/* 0x000094 */
+	bridgereg_t	_pad_000098[2];
+
+	/* Arbitration 0x0000A0-0x0000AF */
+	bridgereg_t	_pad_0000A0;
+	bridgereg_t	b_arb;				/* 0x0000A4 */
+	bridgereg_t	_pad_0000A8[2];
+
+	/* Number In A Can 0x0000B0-0x0000BF */
+	bridgereg_t	_pad_0000B0;
+	bridgereg_t	b_nic;				/* 0x0000B4 */
+	bridgereg_t	_pad_0000B8[2];
+
+	/* PCI/GIO 0x0000C0-0x0000FF */
+	bridgereg_t	_pad_0000C0;
+	bridgereg_t	b_bus_timeout;			/* 0x0000C4 */
+#define b_pci_bus_timeout b_bus_timeout
+
+	bridgereg_t	_pad_0000C8;
+	bridgereg_t	b_pci_cfg;			/* 0x0000CC */
+	bridgereg_t	_pad_0000D0;
+	bridgereg_t	b_pci_err_upper;		/* 0x0000D4 */
+	bridgereg_t	_pad_0000D8;
+	bridgereg_t	b_pci_err_lower;		/* 0x0000DC */
+	bridgereg_t	_pad_0000E0[8];
+#define b_gio_err_lower b_pci_err_lower
+#define b_gio_err_upper b_pci_err_upper
+
+	/* Interrupt 0x000100-0x0001FF */
+	bridgereg_t	_pad_000100;
+	bridgereg_t	b_int_status;			/* 0x000104 */
+	bridgereg_t	_pad_000108;
+	bridgereg_t	b_int_enable;			/* 0x00010C */
+	bridgereg_t	_pad_000110;
+	bridgereg_t	b_int_rst_stat;			/* 0x000114 */
+	bridgereg_t	_pad_000118;
+	bridgereg_t	b_int_mode;			/* 0x00011C */
+	bridgereg_t	_pad_000120;
+	bridgereg_t	b_int_device;			/* 0x000124 */
+	bridgereg_t	_pad_000128;
+	bridgereg_t	b_int_host_err;			/* 0x00012C */
+
+	struct {
+		bridgereg_t	__pad;			/* 0x0001{30,,,68} */
+		bridgereg_t	addr;			/* 0x0001{34,,,6C} */
+	} b_int_addr[8];				/* 0x000130 */
+
+	bridgereg_t	_pad_000170[36];
+
+	/* Device 0x000200-0x0003FF */
+	struct {
+		bridgereg_t	__pad;			/* 0x0002{00,,,38} */
+		bridgereg_t	reg;			/* 0x0002{04,,,3C} */
+	} b_device[8];					/* 0x000200 */
+
+	struct {
+		bridgereg_t	__pad;			/* 0x0002{40,,,78} */
+		bridgereg_t	reg;			/* 0x0002{44,,,7C} */
+	} b_wr_req_buf[8];				/* 0x000240 */
+
+	struct {
+		bridgereg_t	__pad;			/* 0x0002{80,,,88} */
+		bridgereg_t	reg;			/* 0x0002{84,,,8C} */
+	} b_rrb_map[2];					/* 0x000280 */
+#define	b_even_resp	b_rrb_map[0].reg		/* 0x000284 */
+#define	b_odd_resp	b_rrb_map[1].reg		/* 0x00028C */
+
+	bridgereg_t	_pad_000290;
+	bridgereg_t	b_resp_status;			/* 0x000294 */
+	bridgereg_t	_pad_000298;
+	bridgereg_t	b_resp_clear;			/* 0x00029C */
+
+	bridgereg_t	_pad_0002A0[24];
+
+	char		_pad_000300[0x10000 - 0x000300];
+
+	/* Internal Address Translation Entry RAM 0x010000-0x0103FF */
+	union {
+		bridge_ate_t	wr;			/* write-only */
+		struct {
+			bridgereg_t	_p_pad;
+			bridgereg_t	rd;		/* read-only */
+		}			hi;
+	}			    b_int_ate_ram[128];
+
+	char	_pad_010400[0x11000 - 0x010400];
+
+	/* Internal Address Translation Entry RAM LOW 0x011000-0x0113FF */
+	struct {
+		bridgereg_t	_p_pad;
+		bridgereg_t	rd;		/* read-only */
+	} b_int_ate_ram_lo[128];
+
+	char	_pad_011400[0x20000 - 0x011400];
+
+	/* PCI Device Configuration Spaces 0x020000-0x027FFF */
+	union {				/* make all access sizes available. */
+		u8	c[0x1000 / 1];
+		u16	s[0x1000 / 2];
+		u32	l[0x1000 / 4];
+		u64	d[0x1000 / 8];
+		union {
+			u8	c[0x100 / 1];
+			u16	s[0x100 / 2];
+			u32	l[0x100 / 4];
+			u64	d[0x100 / 8];
+		} f[8];
+	} b_type0_cfg_dev[8];					/* 0x020000 */
+
+    /* PCI Type 1 Configuration Space 0x028000-0x028FFF */
+	union {				/* make all access sizes available. */
+		u8	c[0x1000 / 1];
+		u16	s[0x1000 / 2];
+		u32	l[0x1000 / 4];
+		u64	d[0x1000 / 8];
+	} b_type1_cfg;					/* 0x028000-0x029000 */
+
+	char	_pad_029000[0x007000];			/* 0x029000-0x030000 */
+
+	/* PCI Interrupt Acknowledge Cycle 0x030000 */
+	union {
+		u8	c[8 / 1];
+		u16	s[8 / 2];
+		u32	l[8 / 4];
+		u64	d[8 / 8];
+	} b_pci_iack;						/* 0x030000 */
+
+	u8	_pad_030007[0x04fff8];			/* 0x030008-0x07FFFF */
+
+	/* External Address Translation Entry RAM 0x080000-0x0FFFFF */
+	bridge_ate_t    b_ext_ate_ram[0x10000];
+
+	/* Reserved 0x100000-0x1FFFFF */
+	char	_pad_100000[0x200000-0x100000];
+
+	/* PCI/GIO Device Spaces 0x200000-0xBFFFFF */
+	union {				/* make all access sizes available. */
+		u8	c[0x100000 / 1];
+		u16	s[0x100000 / 2];
+		u32	l[0x100000 / 4];
+		u64	d[0x100000 / 8];
+	} b_devio_raw[10];				/* 0x200000 */
+
+	/* b_devio macro is a bit strange; it reflects the
+	 * fact that the Bridge ASIC provides 2M for the
+	 * first two DevIO windows and 1M for the other six.
+	 */
+#define b_devio(n)	b_devio_raw[((n)<2)?(n*2):(n+2)]
+
+	/* External Flash Proms 1,0 0xC00000-0xFFFFFF */
+	union {		/* make all access sizes available. */
+		u8	c[0x400000 / 1];	/* read-only */
+		u16	s[0x400000 / 2];	/* read-write */
+		u32	l[0x400000 / 4];	/* read-only */
+		u64	d[0x400000 / 8];	/* read-only */
+	} b_external_flash;			/* 0xC00000 */
+} bridge_t;
+
+/*
+ * Field formats for Error Command Word and Auxillary Error Command Word
+ * of bridge.
+ */
+typedef struct bridge_err_cmdword_s {
+	union {
+		u32		cmd_word;
+		struct {
+			u32	didn:4,		/* Destination ID */
+				sidn:4,		/* Source ID	  */
+				pactyp:4,	/* Packet type	  */
+				tnum:5,		/* Trans Number	  */
+				coh:1,		/* Coh Transacti  */
+				ds:2,		/* Data size	  */
+				gbr:1,		/* GBR enable	  */
+				vbpm:1,		/* VBPM message	  */
+				error:1,	/* Error occured  */
+				barr:1,		/* Barrier op	  */
+				rsvd:8;
+		} berr_st;
+	} berr_un;
+} bridge_err_cmdword_t;
+
+#define berr_field	berr_un.berr_st
+#endif	/* LANGUAGE_C */
+
+/*
+ * The values of these macros can and should be crosschecked
+ * regularly against the offsets of the like-named fields
+ * within the "bridge_t" structure above.
+ */
+
+/* Byte offset macros for Bridge internal registers */
+
+#define BRIDGE_WID_ID		WIDGET_ID
+#define BRIDGE_WID_STAT		WIDGET_STATUS
+#define BRIDGE_WID_ERR_UPPER	WIDGET_ERR_UPPER_ADDR
+#define BRIDGE_WID_ERR_LOWER	WIDGET_ERR_LOWER_ADDR
+#define BRIDGE_WID_CONTROL	WIDGET_CONTROL
+#define BRIDGE_WID_REQ_TIMEOUT	WIDGET_REQ_TIMEOUT
+#define BRIDGE_WID_INT_UPPER	WIDGET_INTDEST_UPPER_ADDR
+#define BRIDGE_WID_INT_LOWER	WIDGET_INTDEST_LOWER_ADDR
+#define BRIDGE_WID_ERR_CMDWORD	WIDGET_ERR_CMD_WORD
+#define BRIDGE_WID_LLP		WIDGET_LLP_CFG
+#define BRIDGE_WID_TFLUSH	WIDGET_TFLUSH
+
+#define BRIDGE_WID_AUX_ERR	0x00005C	/* Aux Error Command Word */
+#define BRIDGE_WID_RESP_UPPER	0x000064	/* Response Buf Upper Addr */
+#define BRIDGE_WID_RESP_LOWER	0x00006C	/* Response Buf Lower Addr */
+#define BRIDGE_WID_TST_PIN_CTRL 0x000074	/* Test pin control */
+
+#define BRIDGE_DIR_MAP		0x000084	/* Direct Map reg */
+
+#define BRIDGE_RAM_PERR		0x000094	/* SSRAM Parity Error */
+
+#define BRIDGE_ARB		0x0000A4	/* Arbitration Priority reg */
+
+#define BRIDGE_NIC		0x0000B4	/* Number In A Can */
+
+#define BRIDGE_BUS_TIMEOUT	0x0000C4	/* Bus Timeout Register */
+#define BRIDGE_PCI_BUS_TIMEOUT	BRIDGE_BUS_TIMEOUT
+#define BRIDGE_PCI_CFG		0x0000CC	/* PCI Type 1 Config reg */
+#define BRIDGE_PCI_ERR_UPPER	0x0000D4	/* PCI error Upper Addr */
+#define BRIDGE_PCI_ERR_LOWER	0x0000DC	/* PCI error Lower Addr */
+
+#define BRIDGE_INT_STATUS	0x000104	/* Interrupt Status */
+#define BRIDGE_INT_ENABLE	0x00010C	/* Interrupt Enables */
+#define BRIDGE_INT_RST_STAT	0x000114	/* Reset Intr Status */
+#define BRIDGE_INT_MODE		0x00011C	/* Interrupt Mode */
+#define BRIDGE_INT_DEVICE	0x000124	/* Interrupt Device */
+#define BRIDGE_INT_HOST_ERR	0x00012C	/* Host Error Field */
+
+#define BRIDGE_INT_ADDR0	0x000134	/* Host Address Reg */
+#define BRIDGE_INT_ADDR_OFF	0x000008	/* Host Addr offset (1..7) */
+#define BRIDGE_INT_ADDR(x)	(BRIDGE_INT_ADDR0+(x)*BRIDGE_INT_ADDR_OFF)
+
+#define BRIDGE_DEVICE0		0x000204	/* Device 0 */
+#define BRIDGE_DEVICE_OFF	0x000008	/* Device offset (1..7) */
+#define BRIDGE_DEVICE(x)	(BRIDGE_DEVICE0+(x)*BRIDGE_DEVICE_OFF)
+
+#define BRIDGE_WR_REQ_BUF0	0x000244	/* Write Request Buffer 0 */
+#define BRIDGE_WR_REQ_BUF_OFF	0x000008	/* Buffer Offset (1..7) */
+#define BRIDGE_WR_REQ_BUF(x)	(BRIDGE_WR_REQ_BUF0+(x)*BRIDGE_WR_REQ_BUF_OFF)
+
+#define BRIDGE_EVEN_RESP	0x000284	/* Even Device Response Buf */
+#define BRIDGE_ODD_RESP		0x00028C	/* Odd Device Response Buf */
+
+#define BRIDGE_RESP_STATUS	0x000294	/* Read Response Status reg */
+#define BRIDGE_RESP_CLEAR	0x00029C	/* Read Response Clear reg */
+
+/* Byte offset macros for Bridge I/O space */
+
+#define BRIDGE_ATE_RAM		0x00010000	/* Internal Addr Xlat Ram */
+
+#define BRIDGE_TYPE0_CFG_DEV0	0x00020000	/* Type 0 Cfg, Device 0 */
+#define BRIDGE_TYPE0_CFG_SLOT_OFF	0x00001000	/* Type 0 Cfg Slot Offset (1..7) */
+#define BRIDGE_TYPE0_CFG_FUNC_OFF	0x00000100	/* Type 0 Cfg Func Offset (1..7) */
+#define BRIDGE_TYPE0_CFG_DEV(s)		(BRIDGE_TYPE0_CFG_DEV0+\
+					 (s)*BRIDGE_TYPE0_CFG_SLOT_OFF)
+#define BRIDGE_TYPE0_CFG_DEVF(s,f)	(BRIDGE_TYPE0_CFG_DEV0+\
+					 (s)*BRIDGE_TYPE0_CFG_SLOT_OFF+\
+					 (f)*BRIDGE_TYPE0_CFG_FUNC_OFF)
+
+#define BRIDGE_TYPE1_CFG	0x00028000	/* Type 1 Cfg space */
+
+#define BRIDGE_PCI_IACK		0x00030000	/* PCI Interrupt Ack */
+#define BRIDGE_EXT_SSRAM	0x00080000	/* Extern SSRAM (ATE) */
+
+/* Byte offset macros for Bridge device IO spaces */
+
+#define BRIDGE_DEV_CNT		8	/* Up to 8 devices per bridge */
+#define BRIDGE_DEVIO0		0x00200000	/* Device IO 0 Addr */
+#define BRIDGE_DEVIO1		0x00400000	/* Device IO 1 Addr */
+#define BRIDGE_DEVIO2		0x00600000	/* Device IO 2 Addr */
+#define BRIDGE_DEVIO_OFF	0x00100000	/* Device IO Offset (3..7) */
+
+#define BRIDGE_DEVIO_2MB	0x00200000	/* Device IO Offset (0..1) */
+#define BRIDGE_DEVIO_1MB	0x00100000	/* Device IO Offset (2..7) */
+
+#define BRIDGE_DEVIO(x)		((x)<=1 ? BRIDGE_DEVIO0+(x)*BRIDGE_DEVIO_2MB : BRIDGE_DEVIO2+((x)-2)*BRIDGE_DEVIO_1MB)
+
+#define BRIDGE_EXTERNAL_FLASH	0x00C00000	/* External Flash PROMS */
+
+/* ========================================================================
+ *    Bridge register bit field definitions
+ */
+
+/* Widget part number of bridge */
+#define BRIDGE_WIDGET_PART_NUM		0xc002
+
+/* Manufacturer of bridge */
+#define BRIDGE_WIDGET_MFGR_NUM		0x036
+
+/* Revision numbers for known Bridge revisions */
+#define BRIDGE_REV_A			0x1
+#define BRIDGE_REV_B			0x2
+#define BRIDGE_REV_C			0x3
+#define	BRIDGE_REV_D			0x4
+
+/* Bridge widget status register bits definition */
+
+#define BRIDGE_STAT_LLP_REC_CNT		(0xFFu << 24)
+#define BRIDGE_STAT_LLP_TX_CNT		(0xFF << 16)
+#define BRIDGE_STAT_FLASH_SELECT	(0x1 << 6)
+#define BRIDGE_STAT_PCI_GIO_N		(0x1 << 5)
+#define BRIDGE_STAT_PENDING		(0x1F << 0)
+
+/* Bridge widget control register bits definition */
+#define BRIDGE_CTRL_FLASH_WR_EN		(0x1ul << 31)
+#define BRIDGE_CTRL_EN_CLK50		(0x1 << 30)
+#define BRIDGE_CTRL_EN_CLK40		(0x1 << 29)
+#define BRIDGE_CTRL_EN_CLK33		(0x1 << 28)
+#define BRIDGE_CTRL_RST(n)		((n) << 24)
+#define BRIDGE_CTRL_RST_MASK		(BRIDGE_CTRL_RST(0xF))
+#define BRIDGE_CTRL_RST_PIN(x)		(BRIDGE_CTRL_RST(0x1 << (x)))
+#define BRIDGE_CTRL_IO_SWAP		(0x1 << 23)
+#define BRIDGE_CTRL_MEM_SWAP		(0x1 << 22)
+#define BRIDGE_CTRL_PAGE_SIZE		(0x1 << 21)
+#define BRIDGE_CTRL_SS_PAR_BAD		(0x1 << 20)
+#define BRIDGE_CTRL_SS_PAR_EN		(0x1 << 19)
+#define BRIDGE_CTRL_SSRAM_SIZE(n)	((n) << 17)
+#define BRIDGE_CTRL_SSRAM_SIZE_MASK	(BRIDGE_CTRL_SSRAM_SIZE(0x3))
+#define BRIDGE_CTRL_SSRAM_512K		(BRIDGE_CTRL_SSRAM_SIZE(0x3))
+#define BRIDGE_CTRL_SSRAM_128K		(BRIDGE_CTRL_SSRAM_SIZE(0x2))
+#define BRIDGE_CTRL_SSRAM_64K		(BRIDGE_CTRL_SSRAM_SIZE(0x1))
+#define BRIDGE_CTRL_SSRAM_1K		(BRIDGE_CTRL_SSRAM_SIZE(0x0))
+#define BRIDGE_CTRL_F_BAD_PKT		(0x1 << 16)
+#define BRIDGE_CTRL_LLP_XBAR_CRD(n)	((n) << 12)
+#define BRIDGE_CTRL_LLP_XBAR_CRD_MASK	(BRIDGE_CTRL_LLP_XBAR_CRD(0xf))
+#define BRIDGE_CTRL_CLR_RLLP_CNT	(0x1 << 11)
+#define BRIDGE_CTRL_CLR_TLLP_CNT	(0x1 << 10)
+#define BRIDGE_CTRL_SYS_END		(0x1 << 9)
+#define BRIDGE_CTRL_MAX_TRANS(n)	((n) << 4)
+#define BRIDGE_CTRL_MAX_TRANS_MASK	(BRIDGE_CTRL_MAX_TRANS(0x1f))
+#define BRIDGE_CTRL_WIDGET_ID(n)	((n) << 0)
+#define BRIDGE_CTRL_WIDGET_ID_MASK	(BRIDGE_CTRL_WIDGET_ID(0xf))
+
+/* Bridge Response buffer Error Upper Register bit fields definition */
+#define BRIDGE_RESP_ERRUPPR_DEVNUM_SHFT (20)
+#define BRIDGE_RESP_ERRUPPR_DEVNUM_MASK (0x7 << BRIDGE_RESP_ERRUPPR_DEVNUM_SHFT)
+#define BRIDGE_RESP_ERRUPPR_BUFNUM_SHFT (16)
+#define BRIDGE_RESP_ERRUPPR_BUFNUM_MASK (0xF << BRIDGE_RESP_ERRUPPR_BUFNUM_SHFT)
+#define BRIDGE_RESP_ERRRUPPR_BUFMASK	(0xFFFF)
+
+#define BRIDGE_RESP_ERRUPPR_BUFNUM(x)	\
+			(((x) & BRIDGE_RESP_ERRUPPR_BUFNUM_MASK) >> \
+				BRIDGE_RESP_ERRUPPR_BUFNUM_SHFT)
+
+#define BRIDGE_RESP_ERRUPPR_DEVICE(x)	\
+			(((x) &	 BRIDGE_RESP_ERRUPPR_DEVNUM_MASK) >> \
+				 BRIDGE_RESP_ERRUPPR_DEVNUM_SHFT)
+
+/* Bridge direct mapping register bits definition */
+#define BRIDGE_DIRMAP_W_ID_SHFT		20
+#define BRIDGE_DIRMAP_W_ID		(0xf << BRIDGE_DIRMAP_W_ID_SHFT)
+#define BRIDGE_DIRMAP_RMF_64		(0x1 << 18)
+#define BRIDGE_DIRMAP_ADD512		(0x1 << 17)
+#define BRIDGE_DIRMAP_OFF		(0x1ffff << 0)
+#define BRIDGE_DIRMAP_OFF_ADDRSHFT	(31)	/* lsbit of DIRMAP_OFF is xtalk address bit 31 */
+
+/* Bridge Arbitration register bits definition */
+#define BRIDGE_ARB_REQ_WAIT_TICK(x)	((x) << 16)
+#define BRIDGE_ARB_REQ_WAIT_TICK_MASK	BRIDGE_ARB_REQ_WAIT_TICK(0x3)
+#define BRIDGE_ARB_REQ_WAIT_EN(x)	((x) << 8)
+#define BRIDGE_ARB_REQ_WAIT_EN_MASK	BRIDGE_ARB_REQ_WAIT_EN(0xff)
+#define BRIDGE_ARB_FREEZE_GNT		(1 << 6)
+#define BRIDGE_ARB_HPRI_RING_B2		(1 << 5)
+#define BRIDGE_ARB_HPRI_RING_B1		(1 << 4)
+#define BRIDGE_ARB_HPRI_RING_B0		(1 << 3)
+#define BRIDGE_ARB_LPRI_RING_B2		(1 << 2)
+#define BRIDGE_ARB_LPRI_RING_B1		(1 << 1)
+#define BRIDGE_ARB_LPRI_RING_B0		(1 << 0)
+
+/* Bridge Bus time-out register bits definition */
+#define BRIDGE_BUS_PCI_RETRY_HLD(x)	((x) << 16)
+#define BRIDGE_BUS_PCI_RETRY_HLD_MASK	BRIDGE_BUS_PCI_RETRY_HLD(0x1f)
+#define BRIDGE_BUS_GIO_TIMEOUT		(1 << 12)
+#define BRIDGE_BUS_PCI_RETRY_CNT(x)	((x) << 0)
+#define BRIDGE_BUS_PCI_RETRY_MASK	BRIDGE_BUS_PCI_RETRY_CNT(0x3ff)
+
+/* Bridge interrupt status register bits definition */
+#define BRIDGE_ISR_MULTI_ERR		(0x1u << 31)
+#define BRIDGE_ISR_PMU_ESIZE_FAULT	(0x1 << 30)
+#define BRIDGE_ISR_UNEXP_RESP		(0x1 << 29)
+#define BRIDGE_ISR_BAD_XRESP_PKT	(0x1 << 28)
+#define BRIDGE_ISR_BAD_XREQ_PKT		(0x1 << 27)
+#define BRIDGE_ISR_RESP_XTLK_ERR	(0x1 << 26)
+#define BRIDGE_ISR_REQ_XTLK_ERR		(0x1 << 25)
+#define BRIDGE_ISR_INVLD_ADDR		(0x1 << 24)
+#define BRIDGE_ISR_UNSUPPORTED_XOP	(0x1 << 23)
+#define BRIDGE_ISR_XREQ_FIFO_OFLOW	(0x1 << 22)
+#define BRIDGE_ISR_LLP_REC_SNERR	(0x1 << 21)
+#define BRIDGE_ISR_LLP_REC_CBERR	(0x1 << 20)
+#define BRIDGE_ISR_LLP_RCTY		(0x1 << 19)
+#define BRIDGE_ISR_LLP_TX_RETRY		(0x1 << 18)
+#define BRIDGE_ISR_LLP_TCTY		(0x1 << 17)
+#define BRIDGE_ISR_SSRAM_PERR		(0x1 << 16)
+#define BRIDGE_ISR_PCI_ABORT		(0x1 << 15)
+#define BRIDGE_ISR_PCI_PARITY		(0x1 << 14)
+#define BRIDGE_ISR_PCI_SERR		(0x1 << 13)
+#define BRIDGE_ISR_PCI_PERR		(0x1 << 12)
+#define BRIDGE_ISR_PCI_MST_TIMEOUT	(0x1 << 11)
+#define BRIDGE_ISR_GIO_MST_TIMEOUT	BRIDGE_ISR_PCI_MST_TIMEOUT
+#define BRIDGE_ISR_PCI_RETRY_CNT	(0x1 << 10)
+#define BRIDGE_ISR_XREAD_REQ_TIMEOUT	(0x1 << 9)
+#define BRIDGE_ISR_GIO_B_ENBL_ERR	(0x1 << 8)
+#define BRIDGE_ISR_INT_MSK		(0xff << 0)
+#define BRIDGE_ISR_INT(x)		(0x1 << (x))
+
+#define BRIDGE_ISR_LINK_ERROR		\
+		(BRIDGE_ISR_LLP_REC_SNERR|BRIDGE_ISR_LLP_REC_CBERR|	\
+		 BRIDGE_ISR_LLP_RCTY|BRIDGE_ISR_LLP_TX_RETRY|		\
+		 BRIDGE_ISR_LLP_TCTY)
+
+#define BRIDGE_ISR_PCIBUS_PIOERR	\
+		(BRIDGE_ISR_PCI_MST_TIMEOUT|BRIDGE_ISR_PCI_ABORT)
+
+#define BRIDGE_ISR_PCIBUS_ERROR		\
+		(BRIDGE_ISR_PCIBUS_PIOERR|BRIDGE_ISR_PCI_PERR|		\
+		 BRIDGE_ISR_PCI_SERR|BRIDGE_ISR_PCI_RETRY_CNT|		\
+		 BRIDGE_ISR_PCI_PARITY)
+
+#define BRIDGE_ISR_XTALK_ERROR		\
+		(BRIDGE_ISR_XREAD_REQ_TIMEOUT|BRIDGE_ISR_XREQ_FIFO_OFLOW|\
+		 BRIDGE_ISR_UNSUPPORTED_XOP|BRIDGE_ISR_INVLD_ADDR|	\
+		 BRIDGE_ISR_REQ_XTLK_ERR|BRIDGE_ISR_RESP_XTLK_ERR|	\
+		 BRIDGE_ISR_BAD_XREQ_PKT|BRIDGE_ISR_BAD_XRESP_PKT|	\
+		 BRIDGE_ISR_UNEXP_RESP)
+
+#define BRIDGE_ISR_ERRORS		\
+		(BRIDGE_ISR_LINK_ERROR|BRIDGE_ISR_PCIBUS_ERROR|		\
+		 BRIDGE_ISR_XTALK_ERROR|BRIDGE_ISR_SSRAM_PERR|		\
+		 BRIDGE_ISR_PMU_ESIZE_FAULT)
+
+/*
+ * List of Errors which are fatal and kill the sytem
+ */
+#define BRIDGE_ISR_ERROR_FATAL		\
+		((BRIDGE_ISR_XTALK_ERROR & ~BRIDGE_ISR_XREAD_REQ_TIMEOUT)|\
+		 BRIDGE_ISR_PCI_SERR|BRIDGE_ISR_PCI_PARITY )
+
+#define BRIDGE_ISR_ERROR_DUMP		\
+		(BRIDGE_ISR_PCIBUS_ERROR|BRIDGE_ISR_PMU_ESIZE_FAULT|	\
+		 BRIDGE_ISR_XTALK_ERROR|BRIDGE_ISR_SSRAM_PERR)
+
+/* Bridge interrupt enable register bits definition */
+#define BRIDGE_IMR_UNEXP_RESP		BRIDGE_ISR_UNEXP_RESP
+#define BRIDGE_IMR_PMU_ESIZE_FAULT	BRIDGE_ISR_PMU_ESIZE_FAULT
+#define BRIDGE_IMR_BAD_XRESP_PKT	BRIDGE_ISR_BAD_XRESP_PKT
+#define BRIDGE_IMR_BAD_XREQ_PKT		BRIDGE_ISR_BAD_XREQ_PKT
+#define BRIDGE_IMR_RESP_XTLK_ERR	BRIDGE_ISR_RESP_XTLK_ERR
+#define BRIDGE_IMR_REQ_XTLK_ERR		BRIDGE_ISR_REQ_XTLK_ERR
+#define BRIDGE_IMR_INVLD_ADDR		BRIDGE_ISR_INVLD_ADDR
+#define BRIDGE_IMR_UNSUPPORTED_XOP	BRIDGE_ISR_UNSUPPORTED_XOP
+#define BRIDGE_IMR_XREQ_FIFO_OFLOW	BRIDGE_ISR_XREQ_FIFO_OFLOW
+#define BRIDGE_IMR_LLP_REC_SNERR	BRIDGE_ISR_LLP_REC_SNERR
+#define BRIDGE_IMR_LLP_REC_CBERR	BRIDGE_ISR_LLP_REC_CBERR
+#define BRIDGE_IMR_LLP_RCTY		BRIDGE_ISR_LLP_RCTY
+#define BRIDGE_IMR_LLP_TX_RETRY		BRIDGE_ISR_LLP_TX_RETRY
+#define BRIDGE_IMR_LLP_TCTY		BRIDGE_ISR_LLP_TCTY
+#define BRIDGE_IMR_SSRAM_PERR		BRIDGE_ISR_SSRAM_PERR
+#define BRIDGE_IMR_PCI_ABORT		BRIDGE_ISR_PCI_ABORT
+#define BRIDGE_IMR_PCI_PARITY		BRIDGE_ISR_PCI_PARITY
+#define BRIDGE_IMR_PCI_SERR		BRIDGE_ISR_PCI_SERR
+#define BRIDGE_IMR_PCI_PERR		BRIDGE_ISR_PCI_PERR
+#define BRIDGE_IMR_PCI_MST_TIMEOUT	BRIDGE_ISR_PCI_MST_TIMEOUT
+#define BRIDGE_IMR_GIO_MST_TIMEOUT	BRIDGE_ISR_GIO_MST_TIMEOUT
+#define BRIDGE_IMR_PCI_RETRY_CNT	BRIDGE_ISR_PCI_RETRY_CNT
+#define BRIDGE_IMR_XREAD_REQ_TIMEOUT	BRIDGE_ISR_XREAD_REQ_TIMEOUT
+#define BRIDGE_IMR_GIO_B_ENBL_ERR	BRIDGE_ISR_GIO_B_ENBL_ERR
+#define BRIDGE_IMR_INT_MSK		BRIDGE_ISR_INT_MSK
+#define BRIDGE_IMR_INT(x)		BRIDGE_ISR_INT(x)
+
+/* Bridge interrupt reset register bits definition */
+#define BRIDGE_IRR_MULTI_CLR		(0x1 << 6)
+#define BRIDGE_IRR_CRP_GRP_CLR		(0x1 << 5)
+#define BRIDGE_IRR_RESP_BUF_GRP_CLR	(0x1 << 4)
+#define BRIDGE_IRR_REQ_DSP_GRP_CLR	(0x1 << 3)
+#define BRIDGE_IRR_LLP_GRP_CLR		(0x1 << 2)
+#define BRIDGE_IRR_SSRAM_GRP_CLR	(0x1 << 1)
+#define BRIDGE_IRR_PCI_GRP_CLR		(0x1 << 0)
+#define BRIDGE_IRR_GIO_GRP_CLR		(0x1 << 0)
+#define BRIDGE_IRR_ALL_CLR		0x7f
+
+#define BRIDGE_IRR_CRP_GRP		(BRIDGE_ISR_UNEXP_RESP | \
+					 BRIDGE_ISR_XREQ_FIFO_OFLOW)
+#define BRIDGE_IRR_RESP_BUF_GRP		(BRIDGE_ISR_BAD_XRESP_PKT | \
+					 BRIDGE_ISR_RESP_XTLK_ERR | \
+					 BRIDGE_ISR_XREAD_REQ_TIMEOUT)
+#define BRIDGE_IRR_REQ_DSP_GRP		(BRIDGE_ISR_UNSUPPORTED_XOP | \
+					 BRIDGE_ISR_BAD_XREQ_PKT | \
+					 BRIDGE_ISR_REQ_XTLK_ERR | \
+					 BRIDGE_ISR_INVLD_ADDR)
+#define BRIDGE_IRR_LLP_GRP		(BRIDGE_ISR_LLP_REC_SNERR | \
+					 BRIDGE_ISR_LLP_REC_CBERR | \
+					 BRIDGE_ISR_LLP_RCTY | \
+					 BRIDGE_ISR_LLP_TX_RETRY | \
+					 BRIDGE_ISR_LLP_TCTY)
+#define BRIDGE_IRR_SSRAM_GRP		(BRIDGE_ISR_SSRAM_PERR | \
+					 BRIDGE_ISR_PMU_ESIZE_FAULT)
+#define BRIDGE_IRR_PCI_GRP		(BRIDGE_ISR_PCI_ABORT | \
+					 BRIDGE_ISR_PCI_PARITY | \
+					 BRIDGE_ISR_PCI_SERR | \
+					 BRIDGE_ISR_PCI_PERR | \
+					 BRIDGE_ISR_PCI_MST_TIMEOUT | \
+					 BRIDGE_ISR_PCI_RETRY_CNT)
+
+#define BRIDGE_IRR_GIO_GRP		(BRIDGE_ISR_GIO_B_ENBL_ERR | \
+					 BRIDGE_ISR_GIO_MST_TIMEOUT)
+
+/* Bridge INT_DEV register bits definition */
+#define BRIDGE_INT_DEV_SHFT(n)		((n)*3)
+#define BRIDGE_INT_DEV_MASK(n)		(0x7 << BRIDGE_INT_DEV_SHFT(n))
+#define BRIDGE_INT_DEV_SET(_dev, _line) (_dev << BRIDGE_INT_DEV_SHFT(_line))	
+
+/* Bridge interrupt(x) register bits definition */
+#define BRIDGE_INT_ADDR_HOST		0x0003FF00
+#define BRIDGE_INT_ADDR_FLD		0x000000FF
+
+#define BRIDGE_TMO_PCI_RETRY_HLD_MASK	0x1f0000
+#define BRIDGE_TMO_GIO_TIMEOUT_MASK	0x001000
+#define BRIDGE_TMO_PCI_RETRY_CNT_MASK	0x0003ff
+
+#define BRIDGE_TMO_PCI_RETRY_CNT_MAX	0x3ff
+
+/*
+ * The NASID should be shifted by this amount and stored into the
+ * interrupt(x) register.
+ */
+#define BRIDGE_INT_ADDR_NASID_SHFT	8
+
+/*
+ * The BRIDGE_INT_ADDR_DEST_IO bit should be set to send an interrupt to
+ * memory.
+ */
+#define BRIDGE_INT_ADDR_DEST_IO		(1 << 17)
+#define BRIDGE_INT_ADDR_DEST_MEM	0
+#define BRIDGE_INT_ADDR_MASK		(1 << 17)
+
+/* Bridge device(x) register bits definition */
+#define BRIDGE_DEV_ERR_LOCK_EN		0x10000000
+#define BRIDGE_DEV_PAGE_CHK_DIS		0x08000000
+#define BRIDGE_DEV_FORCE_PCI_PAR	0x04000000
+#define BRIDGE_DEV_VIRTUAL_EN		0x02000000
+#define BRIDGE_DEV_PMU_WRGA_EN		0x01000000
+#define BRIDGE_DEV_DIR_WRGA_EN		0x00800000
+#define BRIDGE_DEV_DEV_SIZE		0x00400000
+#define BRIDGE_DEV_RT			0x00200000
+#define BRIDGE_DEV_SWAP_PMU		0x00100000
+#define BRIDGE_DEV_SWAP_DIR		0x00080000
+#define BRIDGE_DEV_PREF			0x00040000
+#define BRIDGE_DEV_PRECISE		0x00020000
+#define BRIDGE_DEV_COH			0x00010000
+#define BRIDGE_DEV_BARRIER		0x00008000
+#define BRIDGE_DEV_GBR			0x00004000
+#define BRIDGE_DEV_DEV_SWAP		0x00002000
+#define BRIDGE_DEV_DEV_IO_MEM		0x00001000
+#define BRIDGE_DEV_OFF_MASK		0x00000fff
+#define BRIDGE_DEV_OFF_ADDR_SHFT	20
+
+#define BRIDGE_DEV_PMU_BITS		(BRIDGE_DEV_PMU_WRGA_EN		| \
+					 BRIDGE_DEV_SWAP_PMU)
+#define BRIDGE_DEV_D32_BITS		(BRIDGE_DEV_DIR_WRGA_EN		| \
+					 BRIDGE_DEV_SWAP_DIR		| \
+					 BRIDGE_DEV_PREF		| \
+					 BRIDGE_DEV_PRECISE		| \
+					 BRIDGE_DEV_COH			| \
+					 BRIDGE_DEV_BARRIER)
+#define BRIDGE_DEV_D64_BITS		(BRIDGE_DEV_DIR_WRGA_EN		| \
+					 BRIDGE_DEV_SWAP_DIR		| \
+					 BRIDGE_DEV_COH			| \
+					 BRIDGE_DEV_BARRIER)
+
+/* Bridge Error Upper register bit field definition */
+#define BRIDGE_ERRUPPR_DEVMASTER	(0x1 << 20)	/* Device was master */
+#define BRIDGE_ERRUPPR_PCIVDEV		(0x1 << 19)	/* Virtual Req value */
+#define BRIDGE_ERRUPPR_DEVNUM_SHFT	(16)
+#define BRIDGE_ERRUPPR_DEVNUM_MASK	(0x7 << BRIDGE_ERRUPPR_DEVNUM_SHFT)
+#define BRIDGE_ERRUPPR_DEVICE(err)	(((err) >> BRIDGE_ERRUPPR_DEVNUM_SHFT) & 0x7)
+#define BRIDGE_ERRUPPR_ADDRMASK		(0xFFFF)
+
+/* Bridge interrupt mode register bits definition */
+#define BRIDGE_INTMODE_CLR_PKT_EN(x)	(0x1 << (x))
+
+/* this should be written to the xbow's link_control(x) register */
+#define BRIDGE_CREDIT	3
+
+/* RRB assignment register */
+#define	BRIDGE_RRB_EN	0x8	/* after shifting down */
+#define	BRIDGE_RRB_DEV	0x7	/* after shifting down */
+#define	BRIDGE_RRB_VDEV	0x4	/* after shifting down */
+#define	BRIDGE_RRB_PDEV	0x3	/* after shifting down */
+
+/* RRB status register */
+#define	BRIDGE_RRB_VALID(r)	(0x00010000<<(r))
+#define	BRIDGE_RRB_INUSE(r)	(0x00000001<<(r))
+
+/* RRB clear register */
+#define	BRIDGE_RRB_CLEAR(r)	(0x00000001<<(r))
+
+/* xbox system controller declarations */
+#define XBOX_BRIDGE_WID         8
+#define FLASH_PROM1_BASE        0xE00000 /* To read the xbox sysctlr status */
+#define XBOX_RPS_EXISTS		1 << 6	 /* RPS bit in status register */
+#define XBOX_RPS_FAIL		1 << 4	 /* RPS status bit in register */
+
+/* ========================================================================
+ */
+/*
+ * Macros for Xtalk to Bridge bus (PCI/GIO) PIO
+ * refer to section 4.2.1 of Bridge Spec for xtalk to PCI/GIO PIO mappings
+ */
+/* XTALK addresses that map into Bridge Bus addr space */
+#define BRIDGE_PIO32_XTALK_ALIAS_BASE	0x000040000000L
+#define BRIDGE_PIO32_XTALK_ALIAS_LIMIT	0x00007FFFFFFFL
+#define BRIDGE_PIO64_XTALK_ALIAS_BASE	0x000080000000L
+#define BRIDGE_PIO64_XTALK_ALIAS_LIMIT	0x0000BFFFFFFFL
+#define BRIDGE_PCIIO_XTALK_ALIAS_BASE	0x000100000000L
+#define BRIDGE_PCIIO_XTALK_ALIAS_LIMIT	0x0001FFFFFFFFL
+
+/* Ranges of PCI bus space that can be accessed via PIO from xtalk */
+#define BRIDGE_MIN_PIO_ADDR_MEM		0x00000000	/* 1G PCI memory space */
+#define BRIDGE_MAX_PIO_ADDR_MEM		0x3fffffff
+#define BRIDGE_MIN_PIO_ADDR_IO		0x00000000	/* 4G PCI IO space */
+#define BRIDGE_MAX_PIO_ADDR_IO		0xffffffff
+
+/* XTALK addresses that map into PCI addresses */
+#define BRIDGE_PCI_MEM32_BASE		BRIDGE_PIO32_XTALK_ALIAS_BASE
+#define BRIDGE_PCI_MEM32_LIMIT		BRIDGE_PIO32_XTALK_ALIAS_LIMIT
+#define BRIDGE_PCI_MEM64_BASE		BRIDGE_PIO64_XTALK_ALIAS_BASE
+#define BRIDGE_PCI_MEM64_LIMIT		BRIDGE_PIO64_XTALK_ALIAS_LIMIT
+#define BRIDGE_PCI_IO_BASE		BRIDGE_PCIIO_XTALK_ALIAS_BASE
+#define BRIDGE_PCI_IO_LIMIT		BRIDGE_PCIIO_XTALK_ALIAS_LIMIT
+
+/*
+ * Macros for Bridge bus (PCI/GIO) to Xtalk DMA
+ */
+/* Bridge Bus DMA addresses */
+#define BRIDGE_LOCAL_BASE		0
+#define BRIDGE_DMA_MAPPED_BASE		0x40000000
+#define BRIDGE_DMA_MAPPED_SIZE		0x40000000	/* 1G Bytes */
+#define BRIDGE_DMA_DIRECT_BASE		0x80000000
+#define BRIDGE_DMA_DIRECT_SIZE		0x80000000	/* 2G Bytes */
+
+#define PCI32_LOCAL_BASE		BRIDGE_LOCAL_BASE
+
+/* PCI addresses of regions decoded by Bridge for DMA */
+#define PCI32_MAPPED_BASE		BRIDGE_DMA_MAPPED_BASE
+#define PCI32_DIRECT_BASE		BRIDGE_DMA_DIRECT_BASE
+
+#define IS_PCI32_LOCAL(x)	((ulong_t)(x) < PCI32_MAPPED_BASE)
+#define IS_PCI32_MAPPED(x)	((ulong_t)(x) < PCI32_DIRECT_BASE && \
+					(ulong_t)(x) >= PCI32_MAPPED_BASE)
+#define IS_PCI32_DIRECT(x)	((ulong_t)(x) >= PCI32_MAPPED_BASE)
+#define IS_PCI64(x)		((ulong_t)(x) >= PCI64_BASE)
+
+/*
+ * The GIO address space.
+ */
+/* Xtalk to GIO PIO */
+#define BRIDGE_GIO_MEM32_BASE		BRIDGE_PIO32_XTALK_ALIAS_BASE
+#define BRIDGE_GIO_MEM32_LIMIT		BRIDGE_PIO32_XTALK_ALIAS_LIMIT
+
+#define GIO_LOCAL_BASE			BRIDGE_LOCAL_BASE
+
+/* GIO addresses of regions decoded by Bridge for DMA */
+#define GIO_MAPPED_BASE			BRIDGE_DMA_MAPPED_BASE
+#define GIO_DIRECT_BASE			BRIDGE_DMA_DIRECT_BASE
+
+#define IS_GIO_LOCAL(x)		((ulong_t)(x) < GIO_MAPPED_BASE)
+#define IS_GIO_MAPPED(x)	((ulong_t)(x) < GIO_DIRECT_BASE && \
+					(ulong_t)(x) >= GIO_MAPPED_BASE)
+#define IS_GIO_DIRECT(x)	((ulong_t)(x) >= GIO_MAPPED_BASE)
+
+/* PCI to xtalk mapping */
+
+/* given a DIR_OFF value and a pci/gio 32 bits direct address, determine
+ * which xtalk address is accessed
+ */
+#define BRIDGE_DIRECT_32_SEG_SIZE	BRIDGE_DMA_DIRECT_SIZE
+#define BRIDGE_DIRECT_32_TO_XTALK(dir_off,adr)		\
+	((dir_off) * BRIDGE_DIRECT_32_SEG_SIZE +	\
+		((adr) & (BRIDGE_DIRECT_32_SEG_SIZE - 1)) + PHYS_RAMBASE)
+
+/* 64-bit address attribute masks */
+#define PCI64_ATTR_TARG_MASK	0xf000000000000000
+#define PCI64_ATTR_TARG_SHFT	60
+#define PCI64_ATTR_PREF		0x0800000000000000
+#define PCI64_ATTR_PREC		0x0400000000000000
+#define PCI64_ATTR_VIRTUAL	0x0200000000000000
+#define PCI64_ATTR_BAR		0x0100000000000000
+#define PCI64_ATTR_RMF_MASK	0x00ff000000000000
+#define PCI64_ATTR_RMF_SHFT	48
+
+#if LANGUAGE_C
+/* Address translation entry for mapped pci32 accesses */
+typedef union ate_u {
+	u64	ent;
+	struct ate_s {
+		u64	rmf:16;
+		u64	addr:36;
+		u64	targ:4;
+		u64	reserved:3;
+		u64	barrier:1;
+		u64	prefetch:1;
+		u64	precise:1;
+		u64	coherent:1;
+		u64	valid:1;
+	} field;
+} ate_t;
+#endif /* LANGUAGE_C */
+
+#define ATE_V		0x01
+#define ATE_CO		0x02
+#define ATE_PREC	0x04
+#define ATE_PREF	0x08
+#define ATE_BAR		0x10
+
+#define ATE_PFNSHIFT		12
+#define ATE_TIDSHIFT		8
+#define ATE_RMFSHIFT		48
+
+#define mkate(xaddr, xid, attr) ((xaddr) & 0x0000fffffffff000ULL) | \
+				((xid)<<ATE_TIDSHIFT) | \
+				(attr)
+
+#define BRIDGE_INTERNAL_ATES	128
+
+#endif /* _ASM_PCI_BRIDGE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/pci.h linux/include/asm-mips64/pci.h
--- v2.3.47/linux/include/asm-mips64/pci.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/pci.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,199 @@
+/* $Id: pci.h,v 1.4 2000/02/24 00:13:20 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_PCI_H
+#define _ASM_PCI_H
+
+/* Can be used to override the logic in pci_scan_bus for skipping
+   already-configured bus numbers - to be used for buggy BIOSes
+   or architectures with incomplete PCI setup by the loader */
+
+#define pcibios_assign_all_busses()	0
+
+#define PCIBIOS_MIN_IO		0x1000
+#define PCIBIOS_MIN_MEM		0x10000000
+
+#ifdef __KERNEL__
+
+/*
+ * Dynamic DMA mapping stuff.
+ * MIPS has everything mapped statically.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include <asm/io.h>
+
+struct pci_dev;
+
+/*
+ * Allocate and map kernel buffer using consistent mode DMA for a device.
+ * hwdev should be valid struct pci_dev pointer for PCI devices,
+ * NULL for PCI-like buses (ISA, EISA).
+ * Returns non-NULL cpu-view pointer to the buffer if successful and
+ * sets *dma_addrp to the pci side dma address as well, else *dma_addrp
+ * is undefined.
+ */
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+				  dma_addr_t *dma_handle);
+
+/*
+ * Free and unmap a consistent DMA buffer.
+ * cpu_addr is what was returned from pci_alloc_consistent,
+ * size must be the same as what as passed into pci_alloc_consistent,
+ * and likewise dma_addr must be the same as what *dma_addrp was set to.
+ *
+ * References to the memory and mappings associated with cpu_addr/dma_addr
+ * past this call are illegal.
+ */
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+				void *vaddr, dma_addr_t dma_handle);
+
+/*
+ * Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+					size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	dma_cache_wback_inv((unsigned long)ptr, size);
+
+	return virt_to_bus(ptr);
+}
+
+/*
+ * Unmap a single streaming mode DMA translation.  The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call.  All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
+ */
+extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+				    size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/* Nothing to do */
+}
+
+/*
+ * Map a set of buffers described by scatterlist in streaming
+ * mode for DMA.  This is the scather-gather version of the
+ * above pci_map_single interface.  Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length.  They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ *       DMA address/length pairs than there are SG table elements.
+ *       (for example via virtual mapping capabilities)
+ *       The routine returns the number of addr/length pairs actually
+ *       used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+			     int nents, int direction)
+{
+#ifndef CONFIG_COHERENT_IO
+	int i;
+#endif
+
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+#ifndef CONFIG_COHERENT_IO
+	for (i = 0; i < nents; i++, sg++)
+		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
+#endif
+
+	return nents;
+}
+
+/*
+ * Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+				int nents, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/* Nothing to do */
+}
+
+/*
+ * Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so.  At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+extern inline void pci_dma_sync_single(struct pci_dev *hwdev,
+				       dma_addr_t dma_handle,
+				       size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	dma_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), size);
+}
+
+/*
+ * Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+extern inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+				   struct scatterlist *sg,
+				   int nelems, int direction)
+{
+#ifndef CONFIG_COHERENT_IO
+	int i;
+#endif
+
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/*  Make sure that gcc doesn't leave the empty loop body.  */
+#ifndef CONFIG_COHERENT_IO
+	for (i = 0; i < nelems; i++, sg++)
+		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
+#endif
+}
+
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg)	(virt_to_bus((sg)->address))
+#define sg_dma_len(sg)		((sg)->length)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_PCI_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/pgalloc.h linux/include/asm-mips64/pgalloc.h
--- v2.3.47/linux/include/asm-mips64/pgalloc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/pgalloc.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,232 @@
+/* $Id: pgalloc.h,v 1.3 2000/02/24 00:13:20 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 2000 by Ralf Baechle at alii
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PGALLOC_H
+#define _ASM_PGALLOC_H
+
+/* TLB flushing:
+ *
+ *  - flush_tlb_all() flushes all processes TLB entries
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB entries
+ *  - flush_tlb_page(mm, vmaddr) flushes a single page
+ *  - flush_tlb_range(mm, start, end) flushes a range of pages
+ */
+extern void (*_flush_tlb_all)(void);
+extern void (*_flush_tlb_mm)(struct mm_struct *mm);
+extern void (*_flush_tlb_range)(struct mm_struct *mm, unsigned long start,
+			       unsigned long end);
+extern void (*_flush_tlb_page)(struct vm_area_struct *vma, unsigned long page);
+
+#define flush_tlb_all()			_flush_tlb_all()
+#define flush_tlb_mm(mm)		_flush_tlb_mm(mm)
+#define flush_tlb_range(mm,vmaddr,end)	_flush_tlb_range(mm, vmaddr, end)
+#define flush_tlb_page(vma,page)	_flush_tlb_page(vma, page)
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+                                      unsigned long start, unsigned long end)
+{
+	/* Nothing to do on MIPS.  */
+}
+
+
+/*
+ * Allocate and free page tables. The xxx_kernel() versions are
+ * used to allocate a kernel page table - this turns on ASN bits
+ * if any.
+ */
+
+#define pgd_quicklist (current_cpu_data.pgd_quick)
+#define pmd_quicklist (current_cpu_data.pmd_quick)
+#define pte_quicklist (current_cpu_data.pte_quick)
+#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
+
+extern pgd_t *get_pgd_slow(void);
+
+extern inline pgd_t *get_pgd_fast(void)
+{
+	unsigned long *ret;
+
+	if((ret = pgd_quicklist) != NULL) {
+		pgd_quicklist = (unsigned long *)(*ret);
+		ret[0] = ret[1];
+		pgtable_cache_size--;
+		return (pgd_t *)ret;
+	}
+
+	ret = (unsigned long *) get_pgd_slow();
+	return (pgd_t *)ret;
+}
+
+extern inline void free_pgd_fast(pgd_t *pgd)
+{
+	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
+	pgd_quicklist = (unsigned long *) pgd;
+	pgtable_cache_size++;
+}
+
+extern inline void free_pgd_slow(pgd_t *pgd)
+{
+	free_pages((unsigned long)pgd, 1);
+}
+
+extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
+extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long address_preadjusted);
+
+extern inline pte_t *get_pte_fast(void)
+{
+	unsigned long *ret;
+
+	if((ret = (unsigned long *)pte_quicklist) != NULL) {
+		pte_quicklist = (unsigned long *)(*ret);
+		ret[0] = ret[1];
+		pgtable_cache_size--;
+	}
+	return (pte_t *)ret;
+}
+
+extern inline void free_pte_fast(pte_t *pte)
+{
+	*(unsigned long *)pte = (unsigned long) pte_quicklist;
+	pte_quicklist = (unsigned long *) pte;
+	pgtable_cache_size++;
+}
+
+extern inline void free_pte_slow(pte_t *pte)
+{
+	free_pages((unsigned long)pte, 0);
+}
+
+extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_preadjusted);
+extern pmd_t *get_pmd_kernel_slow(pgd_t *pgd, unsigned long address_preadjusted);
+
+extern inline pmd_t *get_pmd_fast(void)
+{
+	unsigned long *ret;
+
+	if ((ret = (unsigned long *)pte_quicklist) != NULL) {
+		pte_quicklist = (unsigned long *)(*ret);
+		ret[0] = ret[1];
+		pgtable_cache_size--;
+		return (pmd_t *)ret;
+	}
+
+	return (pmd_t *)ret;
+}
+
+extern inline void free_pmd_fast(pmd_t *pmd)
+{
+	*(unsigned long *)pmd = (unsigned long) pte_quicklist;
+	pte_quicklist = (unsigned long *) pmd;
+	pgtable_cache_size++;
+}
+
+extern inline void free_pmd_slow(pmd_t *pmd)
+{
+	free_pages((unsigned long)pmd, 1);
+}
+
+extern void __bad_pte(pmd_t *pmd);
+extern void __bad_pte_kernel(pmd_t *pmd);
+extern void __bad_pmd(pgd_t *pgd);
+
+#define pte_free_kernel(pte)    free_pte_fast(pte)
+#define pte_free(pte)           free_pte_fast(pte)
+#define pmd_free_kernel(pte)    free_pmd_fast(pte)
+#define pmd_free(pte)           free_pmd_fast(pte)
+#define pgd_free(pgd)           free_pgd_fast(pgd)
+#define pgd_alloc()             get_pgd_fast()
+
+extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
+{
+	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+
+	if (pmd_none(*pmd)) {
+		pte_t *page = get_pte_fast();
+		if (page) {
+			pmd_val(*pmd) = (unsigned long) page;
+			return page + address;
+		}
+		return get_pte_kernel_slow(pmd, address);
+	}
+	if (pmd_bad(*pmd)) {
+		__bad_pte_kernel(pmd);
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + address;
+}
+
+extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
+{
+	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+
+	if (pmd_none(*pmd)) {
+		pte_t *page = get_pte_fast();
+		if (page) {
+			pmd_val(*pmd) = (unsigned long) page;
+			return page + address;
+		}
+		return get_pte_slow(pmd, address);
+	}
+	if (pmd_bad(*pmd)) {
+		__bad_pte(pmd);
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + address;
+}
+
+extern inline pmd_t *pmd_alloc(pgd_t * pgd, unsigned long address)
+{
+	address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
+	if (pgd_none(*pgd)) {
+		pmd_t *page = get_pmd_fast();
+
+		if (!page)
+			return get_pmd_slow(pgd, address);
+		pgd_set(pgd, page);
+		return page + address;
+	}
+	if (pgd_bad(*pgd)) {
+		__bad_pmd(pgd);
+		return NULL;
+	}
+	return (pmd_t *) pgd_page(*pgd) + address;
+}
+
+#define pmd_alloc_kernel	pmd_alloc
+
+extern int do_check_pgt_cache(int, int);
+
+extern inline void set_pgdir(unsigned long address, pgd_t entry)
+{
+	struct task_struct * p;
+	pgd_t *pgd;
+#ifdef __SMP__
+	int i;
+#endif	
+        
+	read_lock(&tasklist_lock);
+	for_each_task(p) {
+		if (!p->mm)
+			continue;
+		*pgd_offset(p->mm, address) = entry;
+	}
+	read_unlock(&tasklist_lock);
+#ifndef __SMP__
+	for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+		pgd[address >> PGDIR_SHIFT] = entry;
+#else
+	/* To pgd_alloc/pgd_free, one holds master kernel lock and so does our
+	   callee, so we can modify pgd caches of other CPUs as well. -jj */
+	for (i = 0; i < NR_CPUS; i++)
+		for (pgd = (pgd_t *)cpu_data[i].pgd_quick; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+			pgd[address >> PGDIR_SHIFT] = entry;
+#endif
+}
+
+#endif /* _ASM_PGALLOC_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/pgtable.h linux/include/asm-mips64/pgtable.h
--- v2.3.47/linux/include/asm-mips64/pgtable.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/pgtable.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,733 @@
+/* $Id: pgtable.h,v 1.12 2000/02/24 00:13:20 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999 by Ralf Baechle at alii
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PGTABLE_H
+#define _ASM_PGTABLE_H
+
+#include <asm/addrspace.h>
+#include <asm/page.h>
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <linux/mmzone.h>
+#include <asm/cachectl.h>
+
+/* Cache flushing:
+ *
+ *  - flush_cache_all() flushes entire cache
+ *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ *  - flush_cache_page(mm, vmaddr) flushes a single page
+ *  - flush_cache_range(mm, start, end) flushes a range of pages
+ *  - flush_page_to_ram(page) write back kernel page to ram
+ */
+extern void (*_flush_cache_all)(void);
+extern void (*_flush_cache_mm)(struct mm_struct *mm);
+extern void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
+                                 unsigned long end);
+extern void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
+extern void (*_flush_cache_sigtramp)(unsigned long addr);
+extern void (*_flush_page_to_ram)(struct page * page);
+
+#define flush_cache_all()		_flush_cache_all()
+#define flush_cache_mm(mm)		_flush_cache_mm(mm)
+#define flush_cache_range(mm,start,end)	_flush_cache_range(mm,start,end)
+#define flush_cache_page(vma,page)	_flush_cache_page(vma, page)
+#define flush_cache_sigtramp(addr)	_flush_cache_sigtramp(addr)
+#define flush_page_to_ram(page)		_flush_page_to_ram(page)
+
+#define flush_icache_range(start, end)	flush_cache_all()
+#define flush_icache_page(start, page)	do { } while(0)
+
+
+/* Basically we have the same two-level (which is the logical three level
+ * Linux page table layout folded) page tables as the i386.  Some day
+ * when we have proper page coloring support we can have a 1% quicker
+ * tlb refill handling mechanism, but for now it is a bit slower but
+ * works even with the cache aliasing problem the R4k and above have.
+ */
+
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+
+/* PMD_SHIFT determines the size of the area a second-level page table can map */
+#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT - 3))
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PMD_MASK	(~(PMD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT	(PMD_SHIFT + (PAGE_SHIFT + 1 - 3))
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+
+/* Entries per page directory level: we use two-level, so we don't really
+   have any PMD directory physically.  */
+#define PTRS_PER_PGD	1024
+#define PTRS_PER_PMD	1024
+#define PTRS_PER_PTE	512
+#define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
+
+#define VMALLOC_START     XKSEG
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (KSEG3 + (1UL << 40))	/* 1 TB */
+
+/* Note that we shift the lower 32bits of each EntryLo[01] entry
+ * 6 bits to the left. That way we can convert the PFN into the
+ * physical address by a single 'and' operation and gain 6 additional
+ * bits for storing information which isn't present in a normal
+ * MIPS page table.
+ *
+ * Similar to the Alpha port, we need to keep track of the ref
+ * and mod bits in software.  We have a software "yeah you can read
+ * from this page" bit, and a hardware one which actually lets the
+ * process read from the page.  On the same token we have a software
+ * writable bit and the real hardware one which actually lets the
+ * process write to the page, this keeps a mod bit via the hardware
+ * dirty bit.
+ *
+ * Certain revisions of the R4000 and R5000 have a bug where if a
+ * certain sequence occurs in the last 3 instructions of an executable
+ * page, and the following page is not mapped, the cpu can do
+ * unpredictable things.  The code (when it is written) to deal with
+ * this problem will be in the update_mmu_cache() code for the r4k.
+ */
+#define _PAGE_PRESENT               (1<<0)  /* implemented in software */
+#define _PAGE_READ                  (1<<1)  /* implemented in software */
+#define _PAGE_WRITE                 (1<<2)  /* implemented in software */
+#define _PAGE_ACCESSED              (1<<3)  /* implemented in software */
+#define _PAGE_MODIFIED              (1<<4)  /* implemented in software */
+#define _PAGE_R4KBUG                (1<<5)  /* workaround for r4k bug  */
+#define _PAGE_GLOBAL                (1<<6)
+#define _PAGE_VALID                 (1<<7)
+#define _PAGE_SILENT_READ           (1<<7)  /* synonym                 */
+#define _PAGE_DIRTY                 (1<<8)  /* The MIPS dirty bit      */
+#define _PAGE_SILENT_WRITE          (1<<8)
+#define _CACHE_CACHABLE_NO_WA       (0<<9)  /* R4600 only              */
+#define _CACHE_CACHABLE_WA          (1<<9)  /* R4600 only              */
+#define _CACHE_UNCACHED             (2<<9)  /* R4[0246]00              */
+#define _CACHE_CACHABLE_NONCOHERENT (3<<9)  /* R4[0246]00              */
+#define _CACHE_CACHABLE_CE          (4<<9)  /* R4[04]00 only           */
+#define _CACHE_CACHABLE_COW         (5<<9)  /* R4[04]00 only           */
+#define _CACHE_CACHABLE_CUW         (6<<9)  /* R4[04]00 only           */
+#define _CACHE_CACHABLE_ACCELERATED (7<<9)  /* R10000 only             */
+#define _CACHE_MASK                 (7<<9)
+
+#define __READABLE	(_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
+#define __WRITEABLE	(_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
+
+#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
+
+#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
+#define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
+			_CACHE_CACHABLE_NONCOHERENT)
+#define PAGE_COPY       __pgprot(_PAGE_PRESENT | _PAGE_READ | \
+			_CACHE_CACHABLE_NONCOHERENT)
+#define PAGE_READONLY   __pgprot(_PAGE_PRESENT | _PAGE_READ | \
+			_CACHE_CACHABLE_NONCOHERENT)
+#define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
+			_CACHE_CACHABLE_NONCOHERENT)
+#define PAGE_USERIO     __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
+			_CACHE_UNCACHED)
+#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
+			_CACHE_UNCACHED)
+
+/*
+ * MIPS can't do page protection for execute, and considers that the same like
+ * read. Also, write permissions imply read permissions. This is the closest
+ * we can get by reasonable means..
+ */
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY
+#define __P100	PAGE_READONLY
+#define __P101	PAGE_READONLY
+#define __P110	PAGE_COPY
+#define __P111	PAGE_COPY
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY
+#define __S101	PAGE_READONLY
+#define __S110	PAGE_SHARED
+#define __S111	PAGE_SHARED
+
+#if !defined (_LANGUAGE_ASSEMBLY)
+
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pmd_ERROR(e) \
+	printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+	printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+/*
+ * BAD_PAGETABLE is used when we need a bogus page-table, while
+ * BAD_PAGE is used for a bogus page.
+ *
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern pte_t __bad_page(void);
+extern pte_t *__bad_pagetable(void);
+extern pmd_t *__bad_pmd_table(void);
+
+extern unsigned long empty_zero_page;
+extern unsigned long zero_page_mask;
+
+#define BAD_PAGETABLE __bad_pagetable()
+#define BAD_PMDTABLE __bad_pmd_table()
+#define BAD_PAGE __bad_page()
+#define ZERO_PAGE(vaddr) \
+	(mem_map + MAP_NR(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))
+
+/* number of bits that fit into a memory pointer */
+#define BITS_PER_PTR			(8*sizeof(unsigned long))
+
+/* to align the pointer to a pointer address */
+#define PTR_MASK			(~(sizeof(void*)-1))
+
+/*
+ * sizeof(void*) == (1 << SIZEOF_PTR_LOG2)
+ */
+#define SIZEOF_PTR_LOG2			3
+
+/* to find an entry in a page-table */
+#define PAGE_PTR(address) \
+((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
+
+extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
+extern pmd_t invalid_pmd_table[2*PAGE_SIZE/sizeof(pmd_t)];
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+extern inline unsigned long pte_page(pte_t pte)
+{
+	return PAGE_OFFSET + (pte_val(pte) & PAGE_MASK);
+}
+
+extern inline unsigned long pmd_page(pmd_t pmd)
+{
+	return pmd_val(pmd);
+}
+
+extern inline unsigned long pgd_page(pgd_t pgd)
+{
+	return pgd_val(pgd);
+}
+
+extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
+{
+	pmd_val(*pmdp) = (((unsigned long) ptep) & PAGE_MASK);
+}
+
+extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
+{
+	pgd_val(*pgdp) = (((unsigned long) pmdp) & PAGE_MASK);
+}
+
+extern inline int pte_none(pte_t pte)
+{
+	return !pte_val(pte);
+}
+
+extern inline int pte_present(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_PRESENT;
+}
+
+/* Certain architectures need to do special things when pte's
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+extern inline void set_pte(pte_t *ptep, pte_t pteval)
+{
+	*ptep = pteval;
+}
+
+extern inline void pte_clear(pte_t *ptep)
+{
+	set_pte(ptep, __pte(0));
+}
+
+/*
+ * Empty pmd entries point to the invalid_pte_table.
+ */
+extern inline int pmd_none(pmd_t pmd)
+{
+	return pmd_val(pmd) == (unsigned long) invalid_pte_table;
+}
+
+extern inline int pmd_bad(pmd_t pmd)
+{
+	return ((pmd_page(pmd) > (unsigned long) high_memory) ||
+	        (pmd_page(pmd) < PAGE_OFFSET));
+}
+
+extern inline int pmd_present(pmd_t pmd)
+{
+	return pmd_val(pmd) != (unsigned long) invalid_pte_table;
+}
+
+extern inline void pmd_clear(pmd_t *pmdp)
+{
+	pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
+}
+
+/*
+ * Empty pgd entries point to the invalid_pmd_table.
+ */
+extern inline int pgd_none(pgd_t pgd)
+{
+	return pgd_val(pgd) == (unsigned long) invalid_pmd_table;
+}
+
+extern inline int pgd_bad(pgd_t pgd)
+{
+	return ((pgd_page(pgd) > (unsigned long) high_memory) ||
+	        (pgd_page(pgd) < PAGE_OFFSET));
+}
+
+extern inline int pgd_present(pgd_t pgd)
+{
+	return pgd_val(pgd) != (unsigned long) invalid_pmd_table;
+}
+
+extern inline void pgd_clear(pgd_t *pgdp)
+{
+	pgd_val(*pgdp) = ((unsigned long) invalid_pmd_table);
+}
+
+/*
+ * Permanent address of a page.  On MIPS64 we never have highmem, so this
+ * is simple.
+ * called on a highmem page.
+ */
+#define page_address(page)	((page)->virtual)
+#ifndef CONFIG_DISCONTIGMEM
+#define pte_pagenr(x)		((unsigned long)((pte_val(x) >> PAGE_SHIFT)))
+#else
+#define pte_pagenr(x) \
+	(PLAT_NODE_DATA_STARTNR(PHYSADDR_TO_NID(pte_val(x))) + \
+	PLAT_NODE_DATA_LOCALNR(pte_val(x), PHYSADDR_TO_NID(pte_val(x))))
+#endif
+#define pte_page(x)		(mem_map+pte_pagenr(x))
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+extern inline int pte_read(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_READ;
+}
+
+extern inline int pte_write(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_WRITE;
+}
+
+extern inline int pte_dirty(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_MODIFIED;
+}
+
+extern inline int pte_young(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_ACCESSED;
+}
+
+extern inline pte_t pte_wrprotect(pte_t pte)
+{
+	pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
+	return pte;
+}
+
+extern inline pte_t pte_rdprotect(pte_t pte)
+{
+	pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
+	return pte;
+}
+
+extern inline pte_t pte_mkclean(pte_t pte)
+{
+	pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
+	return pte;
+}
+
+extern inline pte_t pte_mkold(pte_t pte)
+{
+	pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
+	return pte;
+}
+
+extern inline pte_t pte_mkwrite(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_WRITE;
+	if (pte_val(pte) & _PAGE_MODIFIED)
+		pte_val(pte) |= _PAGE_SILENT_WRITE;
+	return pte;
+}
+
+extern inline pte_t pte_mkread(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_READ;
+	if (pte_val(pte) & _PAGE_ACCESSED)
+		pte_val(pte) |= _PAGE_SILENT_READ;
+	return pte;
+}
+
+extern inline pte_t pte_mkdirty(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_MODIFIED;
+	if (pte_val(pte) & _PAGE_WRITE)
+		pte_val(pte) |= _PAGE_SILENT_WRITE;
+	return pte;
+}
+
+extern inline pte_t pte_mkyoung(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_ACCESSED;
+	if (pte_val(pte) & _PAGE_READ)
+		pte_val(pte) |= _PAGE_SILENT_READ;
+	return pte;
+}
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+#ifndef CONFIG_DISCONTIGMEM
+#define PAGE_TO_PA(page)	((page - mem_map) << PAGE_SHIFT)
+#else
+#define PAGE_TO_PA(page) \
+		((((page)-(page)->zone->zone_pgdat->node_mem_map) << PAGE_SHIFT) \
+		+ ((PAGE_TO_PLAT_NODE(page))->physstart))
+#endif
+#define mk_pte(page, pgprot)						\
+({									\
+	pte_t	__pte;							\
+									\
+	pte_val(__pte) = ((unsigned long)(PAGE_TO_PA(page))) |		\
+						pgprot_val(pgprot);	\
+									\
+	__pte;								\
+})
+
+extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
+{
+	return __pte(physpage | pgprot_val(pgprot));
+}
+
+extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
+}
+
+#define page_pte(page) page_pte_prot(page, __pgprot(0))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+#define pgd_index(address)	((address >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+
+/* to find an entry in a page-table-directory */
+extern inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address)
+{
+	return mm->pgd + pgd_index(address);
+}
+
+/* Find an entry in the second-level page table.. */
+extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+{
+	return (pmd_t *) pgd_page(*dir) +
+	       ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
+}
+
+/* Find an entry in the third-level page table.. */ 
+extern inline pte_t *pte_offset(pmd_t * dir, unsigned long address)
+{
+	return (pte_t *) (pmd_page(*dir)) +
+	       ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
+}
+
+/*
+ * Initialize a new pgd / pmd table with invalid pointers.
+ */
+extern void pte_init(unsigned long page);
+extern void pgd_init(unsigned long page);
+extern void pmd_init(unsigned long page);
+
+extern pgd_t swapper_pg_dir[1024];
+
+extern void (*update_mmu_cache)(struct vm_area_struct *vma,
+				unsigned long address, pte_t pte);
+
+/*
+ * Non-present pages:  high 24 bits are offset, next 8 bits type,
+ * low 32 bits zero.
+ */
+extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
+{ pte_t pte; pte_val(pte) = (type << 32) | (offset << 40); return pte; }
+
+#define SWP_TYPE(x)		(((x).val >> 32) & 0xff)
+#define SWP_OFFSET(x)		((x).val >> 40)
+#define SWP_ENTRY(type,offset)	((swp_entry_t) { pte_val(mk_swap_pte((type),(offset))) })
+#define pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
+#define swp_entry_to_pte(x)	((pte_t) { (x).val })
+
+#define module_map      vmalloc
+#define module_unmap    vfree
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define PageSkip(page)		test_bit(PG_skip, &(page)->flags)
+#ifndef CONFIG_DISCONTIGMEM
+#define kern_addr_valid(addr)	(1)
+#endif
+
+/* TLB operations. */
+extern inline void tlb_probe(void)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"tlbp\n\t"
+		".set reorder");
+}
+
+extern inline void tlb_read(void)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"tlbr\n\t"
+		".set reorder");
+}
+
+extern inline void tlb_write_indexed(void)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"tlbwi\n\t"
+		".set reorder");
+}
+
+extern inline void tlb_write_random(void)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"tlbwr\n\t"
+		".set reorder");
+}
+
+/* Dealing with various CP0 mmu/cache related registers. */
+
+/* CP0_PAGEMASK register */
+extern inline unsigned long get_pagemask(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mfc0 %0, $5\n\t"
+		".set reorder"
+		: "=r" (val));
+	return val;
+}
+
+extern inline void set_pagemask(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mtc0 %0, $5\n\t"
+		".set reorder"
+		: : "r" (val));
+}
+
+/* CP0_ENTRYLO0 and CP0_ENTRYLO1 registers */
+extern inline unsigned long get_entrylo0(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(	
+		".set noreorder\n\t"
+		"dmfc0 %0, $2\n\t"
+		".set reorder"
+		: "=r" (val));
+	return val;
+}
+
+extern inline void set_entrylo0(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmtc0 %0, $2\n\t"
+		".set reorder"
+		: : "r" (val));
+}
+
+extern inline unsigned long get_entrylo1(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmfc0 %0, $3\n\t"
+		".set reorder" : "=r" (val));
+
+	return val;
+}
+
+extern inline void set_entrylo1(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmtc0 %0, $3\n\t"
+		".set reorder"
+		: : "r" (val));
+}
+
+/* CP0_ENTRYHI register */
+extern inline unsigned long get_entryhi(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmfc0 %0, $10\n\t"
+		".set reorder"
+		: "=r" (val));
+
+	return val;
+}
+
+extern inline void set_entryhi(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmtc0 %0, $10\n\t"
+		".set reorder"
+		: : "r" (val));
+}
+
+/* CP0_INDEX register */
+extern inline unsigned int get_index(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mfc0 %0, $0\n\t"
+		".set reorder"
+		: "=r" (val));
+	return val;
+}
+
+extern inline void set_index(unsigned int val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mtc0 %0, $0\n\t"
+		".set reorder\n\t"
+		: : "r" (val));
+}
+
+/* CP0_WIRED register */
+extern inline unsigned long get_wired(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mfc0 %0, $6\n\t"
+		".set reorder\n\t"
+		: "=r" (val));
+	return val;
+}
+
+extern inline void set_wired(unsigned long val)
+{
+	__asm__ __volatile__(
+		"\n\t.set noreorder\n\t"
+		"mtc0 %0, $6\n\t"
+		".set reorder"
+		: : "r" (val));
+}
+
+/* CP0_TAGLO and CP0_TAGHI registers */
+extern inline unsigned long get_taglo(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mfc0 %0, $28\n\t"
+		".set reorder"
+		: "=r" (val));
+	return val;
+}
+
+extern inline void set_taglo(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mtc0 %0, $28\n\t"
+		".set reorder"
+		: : "r" (val));
+}
+
+extern inline unsigned long get_taghi(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mfc0 %0, $29\n\t"
+		".set reorder"
+		: "=r" (val));
+	return val;
+}
+
+extern inline void set_taghi(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mtc0 %0, $29\n\t"
+		".set reorder"
+		: : "r" (val));
+}
+
+/* CP0_CONTEXT register */
+extern inline unsigned long get_context(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mfc0 %0, $4\n\t"
+		".set reorder"
+		: "=r" (val));
+
+	return val;
+}
+
+extern inline void set_context(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mtc0 %0, $4\n\t"
+		".set reorder"
+		: : "r" (val));
+}
+
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+
+#endif /* _ASM_PGTABLE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/poll.h linux/include/asm-mips64/poll.h
--- v2.3.47/linux/include/asm-mips64/poll.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/poll.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,34 @@
+/* $Id: poll.h,v 1.1 1999/08/19 22:56:34 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_POLL_H
+#define _ASM_POLL_H
+
+#define POLLIN		0x0001
+#define POLLPRI		0x0002
+#define POLLOUT		0x0004
+
+#define POLLERR		0x0008
+#define POLLHUP		0x0010
+#define POLLNVAL	0x0020
+
+#define POLLRDNORM	0x0040
+#define POLLRDBAND	0x0080
+#define POLLWRNORM	POLLOUT
+#define POLLWRBAND	0x0100
+
+/* XXX This one seems to be more-or-less nonstandard.  */
+#define POLLMSG		0x0400
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif /* _ASM_POLL_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/posix_types.h linux/include/asm-mips64/posix_types.h
--- v2.3.47/linux/include/asm-mips64/posix_types.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/posix_types.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,124 @@
+/* $Id: posix_types.h,v 1.4 2000/02/16 01:07:49 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_POSIX_TYPES_H
+#define _ASM_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned int	__kernel_dev_t;
+typedef unsigned int	__kernel_ino_t;
+typedef unsigned int	__kernel_mode_t;
+typedef unsigned int	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef int		__kernel_ipc_pid_t;
+typedef int		__kernel_uid_t;
+typedef int		__kernel_gid_t;
+typedef unsigned long	__kernel_size_t;
+typedef long		__kernel_ssize_t;
+typedef long		 __kernel_ptrdiff_t;
+typedef int		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef int		__kernel_clock_t;
+typedef long		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef int		__kernel_uid32_t;
+typedef int		__kernel_gid32_t;
+typedef __kernel_uid_t	__kernel_old_uid_t;
+typedef __kernel_gid_t	__kernel_old_gid_t;
+
+#ifdef __GNUC__
+typedef long long      __kernel_loff_t;
+#endif
+
+typedef struct {
+        int    val[2];
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	__fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	__fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
+{ 
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set *__p)
+{
+	unsigned long *__tmp = __p->fds_bits;
+	int __i;
+
+	if (__builtin_constant_p(__FDSET_LONGS)) {
+		switch (__FDSET_LONGS) {
+		case 16:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			__tmp[ 4] = 0; __tmp[ 5] = 0;
+			__tmp[ 6] = 0; __tmp[ 7] = 0;
+			__tmp[ 8] = 0; __tmp[ 9] = 0;
+			__tmp[10] = 0; __tmp[11] = 0;
+			__tmp[12] = 0; __tmp[13] = 0;
+			__tmp[14] = 0; __tmp[15] = 0;
+			return;
+
+		case 8:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			__tmp[ 4] = 0; __tmp[ 5] = 0;
+			__tmp[ 6] = 0; __tmp[ 7] = 0;
+			return;
+
+		case 4:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			return;
+		}
+	}
+	__i = __FDSET_LONGS;
+	while (__i) {
+		__i--;
+		*__tmp = 0;
+		__tmp++;
+	}
+}
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif /* _ASM_POSIX_TYPES_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/processor.h linux/include/asm-mips64/processor.h
--- v2.3.47/linux/include/asm-mips64/processor.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/processor.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,262 @@
+/* $Id: processor.h,v 1.10 2000/02/24 00:13:20 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 Waldorf GMBH
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 Ralf Baechle
+ * Modified further for R[236]000 compatibility by Paul M. Antoine
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PROCESSOR_H
+#define _ASM_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#if !defined (_LANGUAGE_ASSEMBLY)
+#include <asm/cachectl.h>
+#include <asm/mipsregs.h>
+#include <asm/reg.h>
+#include <asm/system.h>
+
+struct mips_cpuinfo {
+	unsigned long udelay_val;
+	unsigned long *pgd_quick;
+	unsigned long *pmd_quick;
+	unsigned long *pte_quick;
+	unsigned long pgtable_cache_sz;
+};
+
+/*
+ * System setup and hardware flags..
+ * XXX: Should go into mips_cpuinfo.
+ */
+extern char wait_available;		/* only available on R4[26]00 */
+extern char cyclecounter_available;	/* only available from R4000 upwards. */
+extern char dedicated_iv_available;	/* some embedded MIPS like Nevada */
+extern char vce_available;		/* Supports VCED / VCEI exceptions */
+extern char mips4_available;		/* CPU has MIPS IV ISA or better */
+
+extern struct mips_cpuinfo boot_cpu_data;
+extern unsigned int vced_count, vcei_count;
+
+#ifdef __SMP__
+extern struct mips_cpuinfo cpu_data[];
+#define current_cpu_data cpu_data[smp_processor_id()]
+#else
+#define cpu_data &boot_cpu_data
+#define current_cpu_data boot_cpu_data
+#endif
+
+/*
+ * Bus types (default is ISA, but people can check others with these..)
+ * MCA_bus hardcoded to 0 for now.
+ *
+ * This needs to be extended since MIPS systems are being delivered with
+ * numerous different types of bus systems.
+ */
+extern int EISA_bus;
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/*
+ * MIPS has no problems with write protection
+ */
+#define wp_works_ok 1
+#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
+
+/* Lazy FPU handling on uni-processor */
+extern struct task_struct *last_task_used_math;
+
+/*
+ * User space process size: 1TB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.  TASK_SIZE
+ * is limited to 1TB by the R4000 architecture; R10000 and better can
+ * support 16TB.
+ */
+#define TASK_SIZE32	   0x80000000UL
+#define TASK_SIZE	0x10000000000UL
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE	((current->thread.mflags & MF_32BIT) ? \
+	(TASK_SIZE32 / 3) : (TASK_SIZE / 3))
+
+/*
+ * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
+ */
+#define IO_BITMAP_SIZE	32
+
+#define NUM_FPU_REGS	32
+
+struct mips_fpu_hard_struct {
+	unsigned long fp_regs[NUM_FPU_REGS];
+	unsigned int control;
+};
+
+/*
+ * FIXME: no fpu emulator yet (but who cares anyway?)
+ */
+struct mips_fpu_soft_struct {
+	long	dummy;
+};
+
+union mips_fpu_union {
+        struct mips_fpu_hard_struct hard;
+        struct mips_fpu_soft_struct soft;
+};
+
+#define INIT_FPU { \
+	{{0,},} \
+}
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+/*
+ * If you change thread_struct remember to change the #defines below too!
+ */
+struct thread_struct {
+        /* Saved main processor registers. */
+        unsigned long reg16;
+	unsigned long reg17, reg18, reg19, reg20, reg21, reg22, reg23;
+        unsigned long reg29, reg30, reg31;
+
+	/* Saved cp0 stuff. */
+	unsigned long cp0_status;
+
+	/* Saved fpu/fpu emulator stuff. */
+	union mips_fpu_union fpu;
+
+	/* Other stuff associated with the thread. */
+	unsigned long cp0_badvaddr;	/* Last user fault */
+	unsigned long cp0_baduaddr;	/* Last kernel fault accessing USEG */
+	unsigned long error_code;
+	unsigned long trap_no;
+#define MF_FIXADE 1			/* Fix address errors in software */
+#define MF_LOGADE 2			/* Log address errors to syslog */
+#define MF_32BIT  4			/* Process is in 32-bit compat mode */
+	unsigned long mflags;
+	mm_segment_t current_ds;
+	unsigned long irix_trampoline;  /* Wheee... */
+	unsigned long irix_oldctx;
+};
+
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+
+#define INIT_MMAP { &init_mm, KSEG0, KSEG1, NULL, PAGE_SHARED, \
+                    VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
+
+#define INIT_THREAD  { \
+        /* \
+         * saved main processor registers \
+         */ \
+	0, 0, 0, 0, 0, 0, 0, 0, \
+	               0, 0, 0, \
+	/* \
+	 * saved cp0 stuff \
+	 */ \
+	0, \
+	/* \
+	 * saved fpu/fpu emulator stuff \
+	 */ \
+	INIT_FPU, \
+	/* \
+	 * Other stuff associated with the process \
+	 */ \
+	0, 0, 0, 0, \
+	/* \
+	 * For now the default is to fix address errors \
+	 */ \
+	MF_FIXADE, { 0 }, 0, 0 \
+}
+
+#ifdef __KERNEL__
+
+#define KERNEL_STACK_SIZE 0x4000
+
+#if !defined (_LANGUAGE_ASSEMBLY)
+
+/* Free all resources held by a thread. */
+#define release_thread(thread) do { } while(0)
+
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+/* Copy and release all segment info associated with a VM */
+#define copy_segments(p, mm) do { } while(0)
+#define release_segments(mm) do { } while(0)
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern inline unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	extern void ret_from_sys_call(void);
+
+	/* New born processes are a special case */
+	if (t->reg31 == (unsigned long) ret_from_sys_call)
+		return t->reg31;
+
+	return ((unsigned long*)t->reg29)[17];
+}
+
+struct pt_regs;
+extern int (*_user_mode)(struct pt_regs *);
+#define user_mode(regs)	_user_mode(regs)
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ */
+#define start_thread(regs, new_pc, new_sp) do {				\
+	/* New thread looses kernel privileges. */			\
+	regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU)) | KSU_USER;\
+	regs->cp0_epc = new_pc;						\
+	regs->regs[29] = new_sp;					\
+	current->thread.current_ds = USER_DS;				\
+} while (0)
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define __PT_REG(reg) ((long)&((struct pt_regs *)0)->reg - sizeof(struct pt_regs))
+#define __KSTK_TOS(tsk) ((unsigned long)(tsk) + KERNEL_STACK_SIZE - 32)
+#define KSTK_EIP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(cp0_epc)))
+#define KSTK_ESP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(regs[29])))
+
+/* Allocation and freeing of basic task resources. */
+/*
+ * NOTE! The task struct and the stack go together
+ */
+#define THREAD_SIZE (2*PAGE_SIZE)
+#define alloc_task_struct() \
+	((struct task_struct *) __get_free_pages(GFP_KERNEL, 2))
+#define free_task_struct(p)	free_pages((unsigned long)(p), 2)
+#define get_task_struct(tsk)	atomic_inc(&mem_map[MAP_NR(tsk)].count)
+
+#define init_task	(init_task_union.task)
+#define init_stack	(init_task_union.stack)
+
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+#endif /* __KERNEL__ */
+
+/*
+ * Return_address is a replacement for __builtin_return_address(count)
+ * which on certain architectures cannot reasonably be implemented in GCC
+ * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386).
+ * Note that __builtin_return_address(x>=1) is forbidden because GCC
+ * aborts compilation on some CPUs.  It's simply not possible to unwind
+ * some CPU's stackframes.
+ *
+ * In gcc 2.8 and newer  __builtin_return_address works only for non-leaf
+ * functions.  We avoid the overhead of a function call by forcing the
+ * compiler to save the return address register on the stack.
+ */
+#define return_address() ({__asm__ __volatile__("":::"$31");__builtin_return_address(0);})
+
+#endif /* _ASM_PROCESSOR_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/ptrace.h linux/include/asm-mips64/ptrace.h
--- v2.3.47/linux/include/asm-mips64/ptrace.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/ptrace.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,74 @@
+/* $Id: ptrace.h,v 1.4 2000/02/24 00:13:20 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PTRACE_H
+#define _ASM_PTRACE_H
+
+#include <linux/types.h>
+
+/* 0 - 31 are integer registers, 32 - 63 are fp registers.  */
+#define FPR_BASE	32
+#define PC		64
+#define CAUSE		65
+#define BADVADDR	66
+#define MMHI		67
+#define MMLO		68
+#define FPC_CSR		69
+#define FPC_EIR		70
+
+#ifndef __ASSEMBLY__
+
+#define abi64_no_regargs						\
+	unsigned long __dummy0,						\
+	unsigned long __dummy1,						\
+	unsigned long __dummy2,						\
+	unsigned long __dummy3,						\
+	unsigned long __dummy4,						\
+	unsigned long __dummy5,						\
+	unsigned long __dummy6,						\
+	unsigned long __dummy7
+
+/*
+ * This struct defines the way the registers are stored on the stack during a
+ * system call/exception. As usual the registers k0/k1 aren't being saved.
+ */
+struct pt_regs {
+	/* Saved main processor registers. */
+	unsigned long regs[32];
+
+	/* Other saved registers. */
+	unsigned long lo;
+	unsigned long hi;
+
+	/*
+	 * saved cp0 registers
+	 */
+	unsigned long cp0_epc;
+	unsigned long cp0_badvaddr;
+	unsigned long cp0_status;
+	unsigned long cp0_cause;
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+#include <asm/offset.h>
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+#define instruction_pointer(regs) ((regs)->cp0_epc)
+
+extern void (*_show_regs)(struct pt_regs *);
+#define show_regs(regs)	_show_regs(regs)
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif
+
+#endif /* _ASM_PTRACE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/r10kcache.h linux/include/asm-mips64/r10kcache.h
--- v2.3.47/linux/include/asm-mips64/r10kcache.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/r10kcache.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,415 @@
+/* $Id: r10kcache.h,v 1.2 2000/01/17 23:32:47 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Inline assembly cache operations.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * FIXME: Handle split L2 caches.
+ */
+#ifndef _ASM_R10KCACHE_H
+#define _ASM_R10KCACHE_H
+
+#include <asm/asm.h>
+#include <asm/r10kcacheops.h>
+
+/* These are fixed for the current R10000.  */
+#define icache_size	0x8000
+#define dcache_size	0x8000
+#define icache_way_size	0x4000
+#define dcache_way_size	0x4000
+#define ic_lsize	64
+#define dc_lsize	32
+
+/* These are configuration dependant.  */
+#define scache_size()	({						\
+	unsigned long __res;						\
+	__res = (read_32bit_cp0_register(CP0_CONFIG) >> 16) & 3;	\
+	__res = 1 << (__res + 19);					\
+	__res;								\
+})
+
+#define sc_lsize()	({						\
+	unsigned long __res;						\
+	__res = (read_32bit_cp0_register(CP0_CONFIG) >> 13) & 1;	\
+	__res = 1 << (__res + 6);					\
+	__res;								\
+})
+
+extern inline void flush_icache_line_indexed(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Index_Invalidate_I));
+}
+
+extern inline void flush_dcache_line_indexed(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Index_Writeback_Inv_D));
+}
+
+extern inline void flush_scache_line_indexed(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Index_Writeback_Inv_S));
+}
+
+extern inline void flush_icache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Hit_Invalidate_I));
+}
+
+extern inline void flush_dcache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Hit_Writeback_Inv_D));
+}
+
+extern inline void invalidate_dcache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Hit_Invalidate_D));
+}
+
+extern inline void invalidate_scache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Hit_Invalidate_S));
+}
+
+extern inline void flush_scache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Hit_Writeback_Inv_S));
+}
+
+/*
+ * The next two are for badland addresses like signal trampolines.
+ */
+extern inline void protected_flush_icache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"1:\tcache %1,(%0)\n"
+		"2:\t.set reorder\n\t"
+		".section\t__ex_table,\"a\"\n\t"
+		".dword\t1b,2b\n\t"
+		".previous"
+		:
+		: "r" (addr), "i" (Hit_Invalidate_I));
+}
+
+extern inline void protected_writeback_dcache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"1:\tcache %1,(%0)\n"
+		"2:\t.set reorder\n\t"
+		".section\t__ex_table,\"a\"\n\t"
+		".dword\t1b,2b\n\t"
+		".previous"
+		:
+		: "r" (addr), "i" (Hit_Writeback_Inv_D));
+}
+
+#define cache32_unroll16(base,op)				\
+	__asm__ __volatile__("					\
+		.set noreorder;					\
+		cache %1, 0x000(%0); cache %1, 0x020(%0);	\
+		cache %1, 0x040(%0); cache %1, 0x060(%0);	\
+		cache %1, 0x080(%0); cache %1, 0x0a0(%0);	\
+		cache %1, 0x0c0(%0); cache %1, 0x0e0(%0);	\
+		cache %1, 0x100(%0); cache %1, 0x120(%0);	\
+		cache %1, 0x140(%0); cache %1, 0x160(%0);	\
+		cache %1, 0x180(%0); cache %1, 0x1a0(%0);	\
+		cache %1, 0x1c0(%0); cache %1, 0x1e0(%0);	\
+		.set reorder"					\
+		:						\
+		: "r" (base),					\
+		  "i" (op));
+
+#define cache32_unroll32(base,op)				\
+	__asm__ __volatile__("					\
+		.set noreorder;					\
+		cache %1, 0x000(%0); cache %1, 0x020(%0);	\
+		cache %1, 0x040(%0); cache %1, 0x060(%0);	\
+		cache %1, 0x080(%0); cache %1, 0x0a0(%0);	\
+		cache %1, 0x0c0(%0); cache %1, 0x0e0(%0);	\
+		cache %1, 0x100(%0); cache %1, 0x120(%0);	\
+		cache %1, 0x140(%0); cache %1, 0x160(%0);	\
+		cache %1, 0x180(%0); cache %1, 0x1a0(%0);	\
+		cache %1, 0x1c0(%0); cache %1, 0x1e0(%0);	\
+		cache %1, 0x200(%0); cache %1, 0x220(%0);	\
+		cache %1, 0x240(%0); cache %1, 0x260(%0);	\
+		cache %1, 0x280(%0); cache %1, 0x2a0(%0);	\
+		cache %1, 0x2c0(%0); cache %1, 0x2e0(%0);	\
+		cache %1, 0x300(%0); cache %1, 0x320(%0);	\
+		cache %1, 0x340(%0); cache %1, 0x360(%0);	\
+		cache %1, 0x380(%0); cache %1, 0x3a0(%0);	\
+		cache %1, 0x3c0(%0); cache %1, 0x3e0(%0);	\
+		.set reorder"					\
+		:						\
+		: "r" (base),					\
+		  "i" (op));
+
+extern inline void blast_dcache32(void)
+{
+	unsigned long way0 = KSEG0;
+	unsigned long way1 = way0 ^ 1;
+	unsigned long end = (way0 + dcache_way_size);
+
+	while (way0 < end) {
+		cache32_unroll16(way0, Index_Writeback_Inv_D);
+		cache32_unroll16(way1, Index_Writeback_Inv_D);
+		way0 += 0x200;
+		way1 += 0x200;
+	}
+}
+
+extern inline void blast_dcache32_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = page + PAGE_SIZE;
+
+	while (start < end) {
+		cache32_unroll32(start, Hit_Writeback_Inv_D);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_dcache32_page_indexed(unsigned long page)
+{
+	unsigned long way0 = page;
+	unsigned long way1 = page ^ 1;
+	unsigned long end = page + PAGE_SIZE;
+
+	while (way0 < end) {
+		cache32_unroll16(way0, Index_Writeback_Inv_D);
+		cache32_unroll16(way1, Index_Writeback_Inv_D);
+		way0 += 0x200;
+		way1 += 0x200;
+	}
+}
+
+#define cache64_unroll16(base,op)				\
+	__asm__ __volatile__("					\
+		.set noreorder;					\
+		cache %1, 0x000(%0); cache %1, 0x040(%0);	\
+		cache %1, 0x080(%0); cache %1, 0x0c0(%0);	\
+		cache %1, 0x100(%0); cache %1, 0x140(%0);	\
+		cache %1, 0x180(%0); cache %1, 0x1c0(%0);	\
+		cache %1, 0x200(%0); cache %1, 0x240(%0);	\
+		cache %1, 0x280(%0); cache %1, 0x2c0(%0);	\
+		cache %1, 0x300(%0); cache %1, 0x340(%0);	\
+		cache %1, 0x380(%0); cache %1, 0x3c0(%0);	\
+		.set reorder"					\
+		:						\
+		: "r" (base),					\
+		  "i" (op));
+
+#define cache64_unroll32(base,op)				\
+	__asm__ __volatile__("					\
+		.set noreorder;					\
+		cache %1, 0x000(%0); cache %1, 0x040(%0);	\
+		cache %1, 0x080(%0); cache %1, 0x0c0(%0);	\
+		cache %1, 0x100(%0); cache %1, 0x140(%0);	\
+		cache %1, 0x180(%0); cache %1, 0x1c0(%0);	\
+		cache %1, 0x200(%0); cache %1, 0x240(%0);	\
+		cache %1, 0x280(%0); cache %1, 0x2c0(%0);	\
+		cache %1, 0x300(%0); cache %1, 0x340(%0);	\
+		cache %1, 0x380(%0); cache %1, 0x3c0(%0);	\
+		cache %1, 0x400(%0); cache %1, 0x440(%0);	\
+		cache %1, 0x480(%0); cache %1, 0x4c0(%0);	\
+		cache %1, 0x500(%0); cache %1, 0x540(%0);	\
+		cache %1, 0x580(%0); cache %1, 0x5c0(%0);	\
+		cache %1, 0x600(%0); cache %1, 0x640(%0);	\
+		cache %1, 0x680(%0); cache %1, 0x6c0(%0);	\
+		cache %1, 0x700(%0); cache %1, 0x740(%0);	\
+		cache %1, 0x780(%0); cache %1, 0x7c0(%0);	\
+		.set reorder"					\
+		:						\
+		: "r" (base),					\
+		  "i" (op));
+
+extern inline void blast_icache64(void)
+{
+	unsigned long way0 = KSEG0;
+	unsigned long way1 = way0 ^ 1;
+	unsigned long end = way0 + icache_way_size;
+
+	while (way0 < end) {
+		cache64_unroll16(way0,Index_Invalidate_I);
+		cache64_unroll16(way1,Index_Invalidate_I);
+		way0 += 0x400;
+		way1 += 0x400;
+	}
+}
+
+extern inline void blast_icache64_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = page + PAGE_SIZE;
+
+	while (start < end) {
+		cache64_unroll32(start,Hit_Invalidate_I);
+		start += 0x800;
+	}
+}
+
+extern inline void blast_icache64_page_indexed(unsigned long page)
+{
+	unsigned long way0 = page;
+	unsigned long way1 = page ^ 1;
+	unsigned long end = page + PAGE_SIZE;
+
+	while (way0 < end) {
+		cache64_unroll16(way0,Index_Invalidate_I);
+		cache64_unroll16(way1,Index_Invalidate_I);
+		way0 += 0x400;
+		way1 += 0x400;
+	}
+}
+
+extern inline void blast_scache64(void)
+{
+	unsigned long way0 = KSEG0;
+	unsigned long way1 = way0 ^ 1;
+	unsigned long end = KSEG0 + scache_size();
+
+	while (way0 < end) {
+		cache64_unroll16(way0,Index_Writeback_Inv_S);
+		cache64_unroll16(way1,Index_Writeback_Inv_S);
+		way0 += 0x400;
+		way1 += 0x400;
+	}
+}
+
+extern inline void blast_scache64_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = page + PAGE_SIZE;
+
+	while (start < end) {
+		cache64_unroll32(start,Hit_Writeback_Inv_S);
+		start += 0x800;
+	}
+}
+
+extern inline void blast_scache64_page_indexed(unsigned long page)
+{
+	unsigned long way0 = page;
+	unsigned long way1 = page ^ 1;
+	unsigned long end = page + PAGE_SIZE;
+
+	while (way0 < end) {
+		cache64_unroll16(way0,Index_Writeback_Inv_S);
+		cache64_unroll16(way1,Index_Writeback_Inv_S);
+		way0 += 0x400;
+		way1 += 0x400;
+	}
+}
+
+#define cache128_unroll16(base,op)				\
+	__asm__ __volatile__("					\
+		.set noreorder;					\
+		cache %1, 0x000(%0); cache %1, 0x080(%0);	\
+		cache %1, 0x100(%0); cache %1, 0x180(%0);	\
+		cache %1, 0x200(%0); cache %1, 0x280(%0);	\
+		cache %1, 0x300(%0); cache %1, 0x380(%0);	\
+		cache %1, 0x400(%0); cache %1, 0x480(%0);	\
+		cache %1, 0x500(%0); cache %1, 0x580(%0);	\
+		cache %1, 0x600(%0); cache %1, 0x680(%0);	\
+		cache %1, 0x700(%0); cache %1, 0x780(%0);	\
+		.set reorder"					\
+		:						\
+		: "r" (base),					\
+		  "i" (op));
+
+#define cache128_unroll32(base,op)				\
+	__asm__ __volatile__("					\
+		.set noreorder;					\
+		cache %1, 0x000(%0); cache %1, 0x080(%0);	\
+		cache %1, 0x100(%0); cache %1, 0x180(%0);	\
+		cache %1, 0x200(%0); cache %1, 0x280(%0);	\
+		cache %1, 0x300(%0); cache %1, 0x380(%0);	\
+		cache %1, 0x400(%0); cache %1, 0x480(%0);	\
+		cache %1, 0x500(%0); cache %1, 0x580(%0);	\
+		cache %1, 0x600(%0); cache %1, 0x680(%0);	\
+		cache %1, 0x700(%0); cache %1, 0x780(%0);	\
+		cache %1, 0x800(%0); cache %1, 0x880(%0);	\
+		cache %1, 0x900(%0); cache %1, 0x980(%0);	\
+		cache %1, 0xa00(%0); cache %1, 0xa80(%0);	\
+		cache %1, 0xb00(%0); cache %1, 0xb80(%0);	\
+		cache %1, 0xc00(%0); cache %1, 0xc80(%0);	\
+		cache %1, 0xd00(%0); cache %1, 0xd80(%0);	\
+		cache %1, 0xe00(%0); cache %1, 0xe80(%0);	\
+		cache %1, 0xf00(%0); cache %1, 0xf80(%0);	\
+		.set reorder"					\
+		:						\
+		: "r" (base),					\
+		  "i" (op));
+
+extern inline void blast_scache128(void)
+{
+	unsigned long way0 = KSEG0;
+	unsigned long way1 = way0 ^ 1;
+	unsigned long end = way0 + scache_size();
+
+	while (way0 < end) {
+		cache128_unroll16(way0, Index_Writeback_Inv_S);
+		cache128_unroll16(way1, Index_Writeback_Inv_S);
+		way0 += 0x800;
+		way1 += 0x800;
+	}
+}
+
+extern inline void blast_scache128_page(unsigned long page)
+{
+	cache128_unroll32(page, Hit_Writeback_Inv_S);
+}
+
+extern inline void blast_scache128_page_indexed(unsigned long page)
+{
+	cache128_unroll32(page    , Index_Writeback_Inv_S);
+	cache128_unroll32(page ^ 1, Index_Writeback_Inv_S);
+}
+
+#endif /* _ASM_R10KCACHE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/r10kcacheops.h linux/include/asm-mips64/r10kcacheops.h
--- v2.3.47/linux/include/asm-mips64/r10kcacheops.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/r10kcacheops.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,48 @@
+/* $Id: r10kcacheops.h,v 1.1 2000/01/16 01:27:14 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Cache operations for the cache instruction.
+ *
+ * (C) Copyright 1996, 1997, 1999 by Ralf Baechle
+ * (C) Copyright 1999 Silicon Graphics, Inc.
+ */
+#ifndef	_ASM_R10KCACHEOPS_H
+#define	_ASM_R10KCACHEOPS_H
+
+/*
+ * Cache Operations
+ */
+#define Index_Invalidate_I      0x00
+#define Index_Writeback_Inv_D   0x01
+					/* 0x02 is unused */
+#define Index_Writeback_Inv_S	0x03
+#define Index_Load_Tag_I	0x04
+#define Index_Load_Tag_D	0x05
+					/* 0x06 is unused */
+#define Index_Load_Tag_S	0x07
+#define Index_Store_Tag_I	0x08
+#define Index_Store_Tag_D	0x09
+					/* 0x0a is unused */
+#define Index_Store_Tag_S	0x0b
+					/* 0x0c - 0x0e are unused */
+#define Hit_Invalidate_I	0x10
+#define Hit_Invalidate_D	0x11
+					/* 0x12 is unused */
+#define Hit_Invalidate_S	0x13
+#define Cache_Barrier		0x14
+#define Hit_Writeback_Inv_D	0x15
+					/* 0x16 is unused */
+#define Hit_Writeback_Inv_S	0x17
+#define Index_Load_Data_I	0x18
+#define Index_Load_Data_D	0x19
+					/* 0x1a is unused */
+#define Index_Load_Data_S	0x1b
+#define Index_Store_Data_I	0x1c
+#define Index_Store_Data_D	0x1d
+					/* 0x1e is unused */
+#define Index_Store_Data_S	0x1f
+
+#endif	/* _ASM_R10KCACHEOPS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/r4kcache.h linux/include/asm-mips64/r4kcache.h
--- v2.3.47/linux/include/asm-mips64/r4kcache.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/r4kcache.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,494 @@
+/* $Id: r4kcache.h,v 1.2 2000/01/17 23:32:47 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Inline assembly cache operations.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * FIXME: Handle split L2 caches.
+ */
+#ifndef _ASM_R4KCACHE_H
+#define _ASM_R4KCACHE_H
+
+#include <asm/asm.h>
+#include <asm/r4kcacheops.h>
+
+extern inline void flush_icache_line_indexed(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Index_Invalidate_I));
+}
+
+extern inline void flush_dcache_line_indexed(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Index_Writeback_Inv_D));
+}
+
+extern inline void flush_scache_line_indexed(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Index_Writeback_Inv_SD));
+}
+
+extern inline void flush_icache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Hit_Invalidate_I));
+}
+
+extern inline void flush_dcache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Hit_Writeback_Inv_D));
+}
+
+extern inline void invalidate_dcache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Hit_Invalidate_D));
+}
+
+extern inline void invalidate_scache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Hit_Invalidate_SD));
+}
+
+extern inline void flush_scache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr), "i" (Hit_Writeback_Inv_SD));
+}
+
+/*
+ * The next two are for badland addresses like signal trampolines.
+ */
+extern inline void protected_flush_icache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"1:\tcache %1,(%0)\n"
+		"2:\t.set reorder\n\t"
+		".section\t__ex_table,\"a\"\n\t"
+		".dword\t1b,2b\n\t"
+		".previous"
+		:
+		: "r" (addr), "i" (Hit_Invalidate_I));
+}
+
+extern inline void protected_writeback_dcache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"1:\tcache %1,(%0)\n"
+		"2:\t.set reorder\n\t"
+		".section\t__ex_table,\"a\"\n\t"
+		".dword\t1b,2b\n\t"
+		".previous"
+		:
+		: "r" (addr), "i" (Hit_Writeback_D));
+}
+
+#define cache16_unroll32(base,op)				\
+	__asm__ __volatile__("					\
+		.set noreorder;					\
+		cache %1, 0x000(%0); cache %1, 0x010(%0);	\
+		cache %1, 0x020(%0); cache %1, 0x030(%0);	\
+		cache %1, 0x040(%0); cache %1, 0x050(%0);	\
+		cache %1, 0x060(%0); cache %1, 0x070(%0);	\
+		cache %1, 0x080(%0); cache %1, 0x090(%0);	\
+		cache %1, 0x0a0(%0); cache %1, 0x0b0(%0);	\
+		cache %1, 0x0c0(%0); cache %1, 0x0d0(%0);	\
+		cache %1, 0x0e0(%0); cache %1, 0x0f0(%0);	\
+		cache %1, 0x100(%0); cache %1, 0x110(%0);	\
+		cache %1, 0x120(%0); cache %1, 0x130(%0);	\
+		cache %1, 0x140(%0); cache %1, 0x150(%0);	\
+		cache %1, 0x160(%0); cache %1, 0x170(%0);	\
+		cache %1, 0x180(%0); cache %1, 0x190(%0);	\
+		cache %1, 0x1a0(%0); cache %1, 0x1b0(%0);	\
+		cache %1, 0x1c0(%0); cache %1, 0x1d0(%0);	\
+		cache %1, 0x1e0(%0); cache %1, 0x1f0(%0);	\
+		.set reorder"					\
+		:						\
+		: "r" (base),					\
+		  "i" (op));
+
+extern inline void blast_dcache16(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + dcache_size);
+
+	while(start < end) {
+		cache16_unroll32(start,Index_Writeback_Inv_D);
+		start += 0x200;
+	}
+}
+
+extern inline void blast_dcache16_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache16_unroll32(start,Hit_Writeback_Inv_D);
+		start += 0x200;
+	}
+}
+
+extern inline void blast_dcache16_page_indexed(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache16_unroll32(start,Index_Writeback_Inv_D);
+		start += 0x200;
+	}
+}
+
+extern inline void blast_icache16(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + icache_size);
+
+	while(start < end) {
+		cache16_unroll32(start,Index_Invalidate_I);
+		start += 0x200;
+	}
+}
+
+extern inline void blast_icache16_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache16_unroll32(start,Hit_Invalidate_I);
+		start += 0x200;
+	}
+}
+
+extern inline void blast_icache16_page_indexed(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache16_unroll32(start,Index_Invalidate_I);
+		start += 0x200;
+	}
+}
+
+extern inline void blast_scache16(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = KSEG0 + scache_size;
+
+	while(start < end) {
+		cache16_unroll32(start,Index_Writeback_Inv_SD);
+		start += 0x200;
+	}
+}
+
+extern inline void blast_scache16_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = page + PAGE_SIZE;
+
+	while(start < end) {
+		cache16_unroll32(start,Hit_Writeback_Inv_SD);
+		start += 0x200;
+	}
+}
+
+extern inline void blast_scache16_page_indexed(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = page + PAGE_SIZE;
+
+	while(start < end) {
+		cache16_unroll32(start,Index_Writeback_Inv_SD);
+		start += 0x200;
+	}
+}
+
+#define cache32_unroll32(base,op)				\
+	__asm__ __volatile__("					\
+		.set noreorder;					\
+		cache %1, 0x000(%0); cache %1, 0x020(%0);	\
+		cache %1, 0x040(%0); cache %1, 0x060(%0);	\
+		cache %1, 0x080(%0); cache %1, 0x0a0(%0);	\
+		cache %1, 0x0c0(%0); cache %1, 0x0e0(%0);	\
+		cache %1, 0x100(%0); cache %1, 0x120(%0);	\
+		cache %1, 0x140(%0); cache %1, 0x160(%0);	\
+		cache %1, 0x180(%0); cache %1, 0x1a0(%0);	\
+		cache %1, 0x1c0(%0); cache %1, 0x1e0(%0);	\
+		cache %1, 0x200(%0); cache %1, 0x220(%0);	\
+		cache %1, 0x240(%0); cache %1, 0x260(%0);	\
+		cache %1, 0x280(%0); cache %1, 0x2a0(%0);	\
+		cache %1, 0x2c0(%0); cache %1, 0x2e0(%0);	\
+		cache %1, 0x300(%0); cache %1, 0x320(%0);	\
+		cache %1, 0x340(%0); cache %1, 0x360(%0);	\
+		cache %1, 0x380(%0); cache %1, 0x3a0(%0);	\
+		cache %1, 0x3c0(%0); cache %1, 0x3e0(%0);	\
+		.set reorder"					\
+		:						\
+		: "r" (base),					\
+		  "i" (op));
+
+extern inline void blast_dcache32(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + dcache_size);
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Writeback_Inv_D);
+		start += 0x400;
+	}
+}
+
+/*
+ * Call this function only with interrupts disabled or R4600 V2.0 may blow
+ * up on you.
+ *
+ * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D,
+ * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Excl_D will only
+ * operate correctly if the internal data cache refill buffer is empty.  These
+ * CACHE instructions should be separated from any potential data cache miss
+ * by a load instruction to an uncached address to empty the response buffer."
+ * (Revision 2.0 device errata from IDT available on http://www.idt.com/
+ * in .pdf format.)
+ */
+extern inline void blast_dcache32_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	/*
+	 * Sigh ... workaround for R4600 v1.7 bug.  Explanation see above.
+	 */
+	*(volatile unsigned long *)KSEG1;
+
+	__asm__ __volatile__("nop;nop;nop;nop");
+	while(start < end) {
+		cache32_unroll32(start,Hit_Writeback_Inv_D);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_dcache32_page_indexed(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Writeback_Inv_D);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_icache32(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + icache_size);
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Invalidate_I);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_icache32_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache32_unroll32(start,Hit_Invalidate_I);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_icache32_page_indexed(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Invalidate_I);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_scache32(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = KSEG0 + scache_size;
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Writeback_Inv_SD);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_scache32_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = page + PAGE_SIZE;
+
+	while(start < end) {
+		cache32_unroll32(start,Hit_Writeback_Inv_SD);
+		start += 0x400;
+	}
+}
+
+extern inline void blast_scache32_page_indexed(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = page + PAGE_SIZE;
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Writeback_Inv_SD);
+		start += 0x400;
+	}
+}
+
+#define cache64_unroll32(base,op)				\
+	__asm__ __volatile__("					\
+		.set noreorder;					\
+		cache %1, 0x000(%0); cache %1, 0x040(%0);	\
+		cache %1, 0x080(%0); cache %1, 0x0c0(%0);	\
+		cache %1, 0x100(%0); cache %1, 0x140(%0);	\
+		cache %1, 0x180(%0); cache %1, 0x1c0(%0);	\
+		cache %1, 0x200(%0); cache %1, 0x240(%0);	\
+		cache %1, 0x280(%0); cache %1, 0x2c0(%0);	\
+		cache %1, 0x300(%0); cache %1, 0x340(%0);	\
+		cache %1, 0x380(%0); cache %1, 0x3c0(%0);	\
+		cache %1, 0x400(%0); cache %1, 0x440(%0);	\
+		cache %1, 0x480(%0); cache %1, 0x4c0(%0);	\
+		cache %1, 0x500(%0); cache %1, 0x540(%0);	\
+		cache %1, 0x580(%0); cache %1, 0x5c0(%0);	\
+		cache %1, 0x600(%0); cache %1, 0x640(%0);	\
+		cache %1, 0x680(%0); cache %1, 0x6c0(%0);	\
+		cache %1, 0x700(%0); cache %1, 0x740(%0);	\
+		cache %1, 0x780(%0); cache %1, 0x7c0(%0);	\
+		.set reorder"					\
+		:						\
+		: "r" (base),					\
+		  "i" (op));
+
+extern inline void blast_scache64(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = KSEG0 + scache_size;
+
+	while(start < end) {
+		cache64_unroll32(start,Index_Writeback_Inv_SD);
+		start += 0x800;
+	}
+}
+
+extern inline void blast_scache64_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = page + PAGE_SIZE;
+
+	while(start < end) {
+		cache64_unroll32(start,Hit_Writeback_Inv_SD);
+		start += 0x800;
+	}
+}
+
+extern inline void blast_scache64_page_indexed(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = page + PAGE_SIZE;
+
+	while(start < end) {
+		cache64_unroll32(start,Index_Writeback_Inv_SD);
+		start += 0x800;
+	}
+}
+
+#define cache128_unroll32(base,op)				\
+	__asm__ __volatile__("					\
+		.set noreorder;					\
+		cache %1, 0x000(%0); cache %1, 0x080(%0);	\
+		cache %1, 0x100(%0); cache %1, 0x180(%0);	\
+		cache %1, 0x200(%0); cache %1, 0x280(%0);	\
+		cache %1, 0x300(%0); cache %1, 0x380(%0);	\
+		cache %1, 0x400(%0); cache %1, 0x480(%0);	\
+		cache %1, 0x500(%0); cache %1, 0x580(%0);	\
+		cache %1, 0x600(%0); cache %1, 0x680(%0);	\
+		cache %1, 0x700(%0); cache %1, 0x780(%0);	\
+		cache %1, 0x800(%0); cache %1, 0x880(%0);	\
+		cache %1, 0x900(%0); cache %1, 0x980(%0);	\
+		cache %1, 0xa00(%0); cache %1, 0xa80(%0);	\
+		cache %1, 0xb00(%0); cache %1, 0xb80(%0);	\
+		cache %1, 0xc00(%0); cache %1, 0xc80(%0);	\
+		cache %1, 0xd00(%0); cache %1, 0xd80(%0);	\
+		cache %1, 0xe00(%0); cache %1, 0xe80(%0);	\
+		cache %1, 0xf00(%0); cache %1, 0xf80(%0);	\
+		.set reorder"					\
+		:						\
+		: "r" (base),					\
+		  "i" (op));
+
+extern inline void blast_scache128(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = KSEG0 + scache_size;
+
+	while(start < end) {
+		cache128_unroll32(start,Index_Writeback_Inv_SD);
+		start += 0x1000;
+	}
+}
+
+extern inline void blast_scache128_page(unsigned long page)
+{
+	cache128_unroll32(page,Hit_Writeback_Inv_SD);
+}
+
+extern inline void blast_scache128_page_indexed(unsigned long page)
+{
+	cache128_unroll32(page,Index_Writeback_Inv_SD);
+}
+
+#endif /* __ASM_R4KCACHE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/r4kcacheops.h linux/include/asm-mips64/r4kcacheops.h
--- v2.3.47/linux/include/asm-mips64/r4kcacheops.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/r4kcacheops.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,48 @@
+/* $Id: r4kcacheops.h,v 1.1 2000/01/17 23:32:47 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Cache operations for the cache instruction.
+ *
+ * (C) Copyright 1996, 1997, 1999 by Ralf Baechle
+ */
+#ifndef	_ASM_R4kCACHEOPS_H
+#define	_ASM_R4kCACHEOPS_H
+
+/*
+ * Cache Operations
+ */
+#define Index_Invalidate_I      0x00
+#define Index_Writeback_Inv_D   0x01
+#define Index_Invalidate_SI     0x02
+#define Index_Writeback_Inv_SD  0x03
+#define Index_Load_Tag_I	0x04
+#define Index_Load_Tag_D	0x05
+#define Index_Load_Tag_SI	0x06
+#define Index_Load_Tag_SD	0x07
+#define Index_Store_Tag_I	0x08
+#define Index_Store_Tag_D	0x09
+#define Index_Store_Tag_SI	0x0A
+#define Index_Store_Tag_SD	0x0B
+#define Create_Dirty_Excl_D	0x0d
+#define Create_Dirty_Excl_SD	0x0f
+#define Hit_Invalidate_I	0x10
+#define Hit_Invalidate_D	0x11
+#define Hit_Invalidate_SI	0x12
+#define Hit_Invalidate_SD	0x13
+#define Fill			0x14
+#define Hit_Writeback_Inv_D	0x15
+					/* 0x16 is unused */
+#define Hit_Writeback_Inv_SD	0x17
+#define Hit_Writeback_I		0x18
+#define Hit_Writeback_D		0x19
+					/* 0x1a is unused */
+#define Hit_Writeback_SD	0x1b
+					/* 0x1c is unused */
+					/* 0x1e is unused */
+#define Hit_Set_Virtual_SI	0x1e
+#define Hit_Set_Virtual_SD	0x1f
+
+#endif	/* _ASM_R4kCACHEOPS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/reg.h linux/include/asm-mips64/reg.h
--- v2.3.47/linux/include/asm-mips64/reg.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/reg.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,67 @@
+/*
+ * Various register offset definitions for debuggers, core file
+ * examiners and whatnot.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999 Ralf Baechle
+ * Copyright (C) 1995, 1999 Silicon Graphics
+ */
+#ifndef _ASM_REG_H
+#define _ASM_REG_H
+
+/*
+ * This defines/structures correspond to the register layout on stack -
+ * if the order here is changed, it needs to be updated in
+ * include/asm-mips/stackframe.h
+ */
+#define EF_REG0			8
+#define EF_REG1			9
+#define EF_REG2			10
+#define EF_REG3			11
+#define EF_REG4			12
+#define EF_REG5			13
+#define EF_REG6			14
+#define EF_REG7			15
+#define EF_REG8			16
+#define EF_REG9			17
+#define EF_REG10		18
+#define EF_REG11		19
+#define EF_REG12		20
+#define EF_REG13		21
+#define EF_REG14		22
+#define EF_REG15		23
+#define EF_REG16		24
+#define EF_REG17		25
+#define EF_REG18		26
+#define EF_REG19		27
+#define EF_REG20		28
+#define EF_REG21		29
+#define EF_REG22		30
+#define EF_REG23		31
+#define EF_REG24		32
+#define EF_REG25		33
+/*
+ * k0/k1 unsaved
+ */
+#define EF_REG28		36
+#define EF_REG29		37
+#define EF_REG30		38
+#define EF_REG31		39
+
+/*
+ * Saved special registers
+ */
+#define EF_LO			40
+#define EF_HI			41
+
+#define EF_CP0_EPC		42
+#define EF_CP0_BADVADDR		43
+#define EF_CP0_STATUS		44
+#define EF_CP0_CAUSE		45
+
+#define EF_SIZE			368	/* size in bytes */
+
+#endif /* _ASM_REG_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/regdef.h linux/include/asm-mips64/regdef.h
--- v2.3.47/linux/include/asm-mips64/regdef.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/regdef.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,53 @@
+/* $Id: regdef.h,v 1.1 1999/08/20 21:59:08 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1985 MIPS Computer Systems, Inc.
+ * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle
+ */
+#ifndef _ASM_REGDEF_H
+#define _ASM_REGDEF_H
+
+#define zero	$0	/* wired zero */
+#define AT	$at	/* assembler temp - uppercase because of ".set at" */
+#define v0	$2	/* return value - caller saved */
+#define v1	$3
+#define a0	$4	/* argument registers */
+#define a1	$5
+#define a2	$6
+#define a3	$7
+#define a4	$8	/* arg reg 64 bit; caller saved in 32 bit */
+#define ta0	$8
+#define a5	$9
+#define ta1	$9
+#define a6	$10
+#define ta2	$10
+#define a7	$11
+#define ta3	$11
+#define t0	$12	/* caller saved */
+#define t1	$13
+#define t2	$14
+#define t3	$15
+#define s0	$16	/* callee saved */
+#define s1	$17
+#define s2	$18
+#define s3	$19
+#define s4	$20
+#define s5	$21
+#define s6	$22
+#define s7	$23
+#define t8	$24	/* caller saved */
+#define t9	$25	/* callee address for PIC/temp */
+#define jp	$25	/* PIC jump register */
+#define k0	$26	/* kernel temporary */
+#define k1	$27
+#define gp	$28	/* global pointer - caller saved for PIC */
+#define sp	$29	/* stack pointer */
+#define fp	$30	/* frame pointer */
+#define s8	$30	/* callee saved */
+#define ra	$31	/* return address */
+
+#endif /* _ASM_REGDEF_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/resource.h linux/include/asm-mips64/resource.h
--- v2.3.47/linux/include/asm-mips64/resource.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/resource.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,53 @@
+/* $Id: resource.h,v 1.4 2000/02/04 07:40:53 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_RESOURCE_H
+#define _ASM_RESOURCE_H
+
+/*
+ * Resource limits
+ */
+#define RLIMIT_CPU 0			/* CPU time in ms */
+#define RLIMIT_FSIZE 1			/* Maximum filesize */
+#define RLIMIT_DATA 2			/* max data size */
+#define RLIMIT_STACK 3			/* max stack size */
+#define RLIMIT_CORE 4			/* max core file size */
+#define RLIMIT_NOFILE 5			/* max number of open files */
+#define RLIMIT_AS 6			/* mapped memory */
+#define RLIMIT_RSS 7			/* max resident set size */
+#define RLIMIT_NPROC 8			/* max number of processes */
+#define RLIMIT_MEMLOCK 9		/* max locked-in-memory address space */
+
+#define RLIM_NLIMITS 10			/* Number of limit flavors.  */
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY  (~0UL)
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS					\
+{							\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ _STK_LIM,      RLIM_INFINITY },		\
+	{        0,      RLIM_INFINITY },		\
+	{ NR_OPEN,       NR_OPEN },			\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ 0,             0             },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_RESOURCE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/scatterlist.h linux/include/asm-mips64/scatterlist.h
--- v2.3.47/linux/include/asm-mips64/scatterlist.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/scatterlist.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,22 @@
+#ifndef __ASM_MIPS64_SCATTERLIST_H
+#define __ASM_MIPS64_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+			 * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+    
+    __u32 dvma_address;
+};
+
+struct mmu_sglist {
+        char *addr;
+        char *__dont_touch;
+        unsigned int len;
+        __u32 dvma_addr;
+};
+
+#define ISA_DMA_THRESHOLD (0x00ffffffUL)
+
+#endif /* __ASM_MIPS64_SCATTERLIST_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/segment.h linux/include/asm-mips64/segment.h
--- v2.3.47/linux/include/asm-mips64/segment.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/segment.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,6 @@
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
+
+/* Only here because we have some old header files that expect it.. */
+
+#endif /* _ASM_SEGMENT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/semaphore-helper.h linux/include/asm-mips64/semaphore-helper.h
--- v2.3.47/linux/include/asm-mips64/semaphore-helper.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/semaphore-helper.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,149 @@
+/* $Id: semaphore-helper.h,v 1.3 1999/12/04 03:59:12 ralf Exp $
+ *
+ * SMP- and interrupt-safe semaphores helper functions.
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ * (C) Copyright 1999 Andrea Arcangeli
+ * (C) Copyright 1999 Ralf Baechle
+ * (C) Copyright 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SEMAPHORE_HELPER_H
+#define _ASM_SEMAPHORE_HELPER_H
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ */
+static inline void wake_one_more(struct semaphore * sem)
+{
+	atomic_inc(&sem->waking);
+}
+
+static inline int
+waking_non_zero(struct semaphore *sem)
+{
+	int ret, tmp;
+
+	__asm__ __volatile__(
+	"1:\tll\t%1, %2\n\t"
+	"blez\t%1, 2f\n\t"
+	"subu\t%0, %1, 1\n\t"
+	"sc\t%0, %2\n\t"
+	"beqz\t%0, 1b\n\t"
+	"2:"
+	".text"
+	: "=r"(ret), "=r"(tmp), "=m"(__atomic_fool_gcc(&sem->waking))
+	: "0"(0));
+
+	return ret;
+}
+
+/*
+ * waking_non_zero_interruptible:
+ *	1	got the lock
+ *	0	go to sleep
+ *	-EINTR	interrupted
+ *
+ * We must undo the sem->count down_interruptible decrement
+ * simultaneously and atomicly with the sem->waking adjustment,
+ * otherwise we can race with wake_one_more.
+ *
+ * This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words.
+ *
+ * Pseudocode:
+ *
+ * If(sem->waking > 0) {
+ *	Decrement(sem->waking)
+ *	Return(SUCCESS)
+ * } else If(segnal_pending(tsk)) {
+ *	Increment(sem->count)
+ *	Return(-EINTR)
+ * } else {
+ *	Return(SLEEP)
+ * }
+ */
+
+static inline int
+waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk)
+{
+	long ret, tmp;
+
+#ifdef __MIPSEB__
+
+        __asm__ __volatile__("
+	.set	push
+	.set	noat
+0:	lld	%1, %2
+	li	%0, 0
+	sll	$1, %1, 0
+	blez	$1, 1f
+	daddiu	%1, %1, -1
+	li	%0, 1
+	b 	2f
+1:
+	beqz	%3, 2f
+	li	%0, %4
+	dli	$1, 0x0000000100000000
+	daddu	%1, %1, $1
+2:
+	scd	%1, %2
+	beqz	%1, 0b
+	.set	pop"
+	: "=&r"(ret), "=&r"(tmp), "=m"(*sem)
+	: "r"(signal_pending(tsk)), "i"(-EINTR));
+
+#elif defined(__MIPSEL__)
+
+	__asm__ __volatile__("
+	.set	push
+	.set	noat
+0:
+	lld	%1, %2
+	li	%0, 0
+	blez	%1, 1f
+	dli	$1, 0x0000000100000000
+	dsubu	%1, %1, $1
+	li	%0, 1
+	b	2f
+1:
+	beqz	%3, 2f
+	li	%0, %4
+	/* 
+	 * It would be nice to assume that sem->count
+	 * is != -1, but we will guard against that case
+	 */
+	daddiu	$1, %1, 1
+	dsll32	$1, $1, 0
+	dsrl32	$1, $1, 0
+	dsrl32	%1, %1, 0
+	dsll32	%1, %1, 0
+	or	%1, %1, $1
+2:
+	scd	%1, %2
+	beqz	%1, 0b
+	.set	pop"
+	: "=&r"(ret), "=&r"(tmp), "=m"(*sem)
+	: "r"(signal_pending(tsk)), "i"(-EINTR));
+
+#else
+#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
+#endif
+
+	return ret;
+}
+
+/*
+ * waking_non_zero_trylock is unused.  we do everything in 
+ * down_trylock and let non-ll/sc hosts bounce around.
+ */
+
+static inline int
+waking_non_zero_trylock(struct semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	return 0;
+}
+
+#endif /* _ASM_SEMAPHORE_HELPER_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/semaphore.h linux/include/asm-mips64/semaphore.h
--- v2.3.47/linux/include/asm-mips64/semaphore.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/semaphore.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,347 @@
+/* $Id: semaphore.h,v 1.6 2000/02/24 03:09:52 ulfc Exp $
+ *
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996  Linus Torvalds
+ * Copyright (C) 1998, 1999, 2000  Ralf Baechle
+ * Copyright (C) 1999, 2000  Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SEMAPHORE_H
+#define _ASM_SEMAPHORE_H
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+
+struct semaphore {
+#ifdef __MIPSEB__
+	atomic_t count;
+	atomic_t waking;
+#else
+	atomic_t waking;
+	atomic_t count;
+#endif
+	wait_queue_head_t wait;
+#if WAITQUEUE_DEBUG
+	long __magic;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+# define __SEM_DEBUG_INIT(name) \
+		, (long)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+#ifdef __MIPSEB__
+#define __SEMAPHORE_INITIALIZER(name,count) \
+{ ATOMIC_INIT(count), ATOMIC_INIT(0), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+	__SEM_DEBUG_INIT(name) }
+#else
+#define __SEMAPHORE_INITIALIZER(name,count) \
+{ ATOMIC_INIT(0), ATOMIC_INIT(count), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+	__SEM_DEBUG_INIT(name) }
+#endif
+
+#define __MUTEX_INITIALIZER(name) \
+	__SEMAPHORE_INITIALIZER(name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+extern inline void sema_init (struct semaphore *sem, int val)
+{
+	atomic_set(&sem->count, val);
+	atomic_set(&sem->waking, 0);
+	init_waitqueue_head(&sem->wait);
+#if WAITQUEUE_DEBUG
+	sem->__magic = (long)&sem->__magic;
+#endif
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init(sem, 0);
+}
+
+asmlinkage void __down(struct semaphore * sem);
+asmlinkage int  __down_interruptible(struct semaphore * sem);
+asmlinkage int __down_trylock(struct semaphore * sem);
+asmlinkage void __up(struct semaphore * sem);
+
+extern inline void down(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+	if (atomic_dec_return(&sem->count) < 0)
+		__down(sem);
+}
+
+extern inline int down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+	if (atomic_dec_return(&sem->count) < 0)
+		ret = __down_interruptible(sem);
+	return ret;
+}
+
+/*
+ * down_trylock returns 0 on success, 1 if we failed to get the lock.
+ *
+ * We must manipulate count and waking simultaneously and atomically.
+ * Here, we this by using ll/sc on the pair of 32-bit words.
+ *
+ * Pseudocode:
+ *
+ *   Decrement(sem->count)
+ *   If(sem->count >=0) {
+ *	Return(SUCCESS)			// resource is free
+ *   } else {
+ *	If(sem->waking <= 0) {		// if no wakeup pending
+ *	   Increment(sem->count)	// undo decrement
+ *	   Return(FAILURE)
+ *      } else {
+ *	   Decrement(sem->waking)	// otherwise "steal" wakeup
+ *	   Return(SUCCESS)
+ *	}
+ *   }
+ */
+extern inline int down_trylock(struct semaphore * sem)
+{
+	long ret, tmp, tmp2, sub;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	__asm__ __volatile__("
+			.set	mips3
+
+		0:	lld	%1, %4
+			dli	%3, 0x0000000100000000
+			dsubu	%1, %3
+			li	%0, 0
+			bgez	%1, 2f
+			sll	%2, %1, 0
+			blez	%2, 1f
+			daddiu	%1, %1, -1
+			b	2f
+		1:
+			daddu	%1, %1, %3
+			li	%0, 1
+		2:
+			scd	%1, %4
+			beqz	%1, 0b
+
+			.set	mips0"
+		: "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub)
+		: "m"(*sem)
+		: "memory");
+
+	return ret;
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ */
+extern inline void up(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+	if (atomic_inc_return(&sem->count) <= 0)
+		__up(sem);
+}
+
+/*
+ * rw mutexes (should that be mutices? =) -- throw rw spinlocks and
+ * semaphores together, and this is what we end up with...
+ *
+ * The lock is initialized to BIAS.  This way, a writer subtracts BIAS ands
+ * gets 0 for the case of an uncontended lock.  Readers decrement by 1 and
+ * see a positive value when uncontended, negative if there are writers
+ * waiting (in which case it goes to sleep).
+ *
+ * The value 0x01000000 supports up to 128 processors and lots of processes.
+ * BIAS must be chosen such that subtracting BIAS once per CPU will result
+ * in the int remaining negative.  In terms of fairness, this should result
+ * in the lock flopping back and forth between readers and writers under
+ * heavy use.
+ *
+ * Once we start supporting machines with more than 128 CPUs, we should go
+ * for using a 64bit atomic type instead of 32bit as counter. We shall
+ * probably go for bias 0x80000000 then, so that single sethi can set it.
+ * */
+
+#define RW_LOCK_BIAS		0x01000000
+
+struct rw_semaphore {
+	atomic_t		count;
+	/* bit 0 means read bias granted;
+	   bit 1 means write bias granted.  */
+	unsigned		granted;
+	wait_queue_head_t	wait;
+	wait_queue_head_t	write_bias_wait;
+#if WAITQUEUE_DEBUG
+	long			__magic;
+	atomic_t		readers;
+	atomic_t		writers;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+#define __RWSEM_DEBUG_INIT	, ATOMIC_INIT(0), ATOMIC_INIT(0)
+#else
+#define __RWSEM_DEBUG_INIT	/* */
+#endif
+
+#define __RWSEM_INITIALIZER(name,count)					\
+	{ ATOMIC_INIT(count), 0,					\
+	  __WAIT_QUEUE_HEAD_INITIALIZER((name).wait),			\
+	  __WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait)		\
+	  __SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT }
+
+#define __DECLARE_RWSEM_GENERIC(name,count) \
+	struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
+
+#define DECLARE_RWSEM(name) \
+	__DECLARE_RWSEM_GENERIC(name, RW_LOCK_BIAS)
+#define DECLARE_RWSEM_READ_LOCKED(name) \
+	__DECLARE_RWSEM_GENERIC(name, RW_LOCK_BIAS-1)
+#define DECLARE_RWSEM_WRITE_LOCKED(name) \
+	__DECLARE_RWSEM_GENERIC(name, 0)
+
+extern inline void init_rwsem(struct rw_semaphore *sem)
+{
+	atomic_set(&sem->count, RW_LOCK_BIAS);
+	sem->granted = 0;
+	init_waitqueue_head(&sem->wait);
+	init_waitqueue_head(&sem->write_bias_wait);
+#if WAITQUEUE_DEBUG
+	sem->__magic = (long)&sem->__magic;
+	atomic_set(&sem->readers, 0);
+	atomic_set(&sem->writers, 0);
+#endif
+}
+
+/* The expensive part is outlined.  */
+extern void __down_read(struct rw_semaphore *sem, int count);
+extern void __down_write(struct rw_semaphore *sem, int count);
+extern void __rwsem_wake(struct rw_semaphore *sem, unsigned long readers);
+
+extern inline void down_read(struct rw_semaphore *sem)
+{
+	int count;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	count = atomic_dec_return(&sem->count);
+	if (count < 0) {
+		__down_read(sem, count);
+	}
+	mb();
+
+#if WAITQUEUE_DEBUG
+	if (sem->granted & 2)
+		BUG();
+	if (atomic_read(&sem->writers))
+		BUG();
+	atomic_inc(&sem->readers);
+#endif
+}
+
+extern inline void down_write(struct rw_semaphore *sem)
+{
+	int count;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	count = atomic_sub_return(RW_LOCK_BIAS, &sem->count);
+	if (count) {
+		__down_write(sem, count);
+	}
+	mb();
+
+#if WAITQUEUE_DEBUG
+	if (atomic_read(&sem->writers))
+		BUG();
+	if (atomic_read(&sem->readers))
+		BUG();
+	if (sem->granted & 3)
+		BUG();
+	atomic_inc(&sem->writers);
+#endif
+}
+
+/* When a reader does a release, the only significant case is when
+   there was a writer waiting, and we've bumped the count to 0: we must
+   wake the writer up.  */
+
+extern inline void up_read(struct rw_semaphore *sem)
+{
+	int count;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+	if (sem->granted & 2)
+		BUG();
+	if (atomic_read(&sem->writers))
+		BUG();
+	atomic_dec(&sem->readers);
+#endif
+
+	mb();
+	count = atomic_inc_return(&sem->count);
+	if (count == 0) {
+		__rwsem_wake(sem, 0);
+	}
+}
+
+/*
+ * Releasing the writer is easy -- just release it and wake up any sleepers.
+ */
+extern inline void up_write(struct rw_semaphore *sem)
+{
+	int count;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+	if (sem->granted & 3)
+		BUG();
+	if (atomic_read(&sem->readers))
+		BUG();
+	if (atomic_read(&sem->writers) != 1)
+		BUG();
+	atomic_dec(&sem->writers);
+#endif
+
+	mb();
+	count = atomic_add_return(RW_LOCK_BIAS, &sem->count);
+	if (count - RW_LOCK_BIAS < 0 && count >= 0) {
+		/* Only do the wake if we're no longer negative.  */
+		__rwsem_wake(sem, count);
+	}
+}
+
+#endif /* _ASM_SEMAPHORE_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sembuf.h linux/include/asm-mips64/sembuf.h
--- v2.3.47/linux/include/asm-mips64/sembuf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sembuf.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,22 @@
+#ifndef _ASM_SEMBUF_H
+#define _ASM_SEMBUF_H
+
+/* 
+ * The semid64_ds structure for the MIPS architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 2 miscellaneous 64-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+};
+
+#endif /* _ASM_SEMBUF_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/serial.h linux/include/asm-mips64/serial.h
--- v2.3.47/linux/include/asm-mips64/serial.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/serial.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,54 @@
+/* $Id: serial.h,v 1.3 2000/02/04 07:40:53 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SERIAL_H
+#define _ASM_SERIAL_H
+
+#include <linux/config.h>
+
+#include <asm/sn/sn0/ip27.h>
+
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD (1843200 / 16)
+
+/* Standard COM flags (except for COM4, because of the 8514 problem) */
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+/*
+ * The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
+ */
+#define IOC3_BAUD (22000000 / (3*16))
+#define IOC3_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_IOC3)
+
+/* Let the compiler figure out the size.  */
+#define RS_TABLE_SIZE
+
+#ifdef CONFIG_SGI_IP27
+#define _ORIGIN_SERIAL_INIT(int, base)					\
+	{ baud_base: IOC3_BAUD, irq: int, flags: IOC3_COM_FLAGS,	\
+	  iomem_base: (u8 *) base, iomem_reg_shift: 0,			\
+	  io_type: SERIAL_IO_MEM }
+#define ORIGIN_SERIAL_PORT_DFNS						\
+	_ORIGIN_SERIAL_INIT(0, 0x9200000008620178UL),			\
+	_ORIGIN_SERIAL_INIT(0, 0x9200000008620170UL),
+
+#else
+#define ORIGIN_SERIAL_PORT_DFNS
+#endif
+
+#define SERIAL_PORT_DFNS						\
+	ORIGIN_SERIAL_PORT_DFNS
+
+#endif /* _ASM_SERIAL_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sgi/io.h linux/include/asm-mips64/sgi/io.h
--- v2.3.47/linux/include/asm-mips64/sgi/io.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sgi/io.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,22 @@
+/* $Id: io.h,v 1.1 2000/02/04 07:40:53 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Ralf Baechle
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SGI_IO_H
+#define _ASM_SGI_IO_H
+
+#include <asm/addrspace.h>
+
+#define IO_SPACE_BASE K1BASE
+
+/* For Indigo2.  */
+#define IO_SPACE_LIMIT 0xffff
+
+/* XXX ISA specific functions go here here.  */
+
+#endif /* _ASM_SGI_IO_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sgi/sgi.h linux/include/asm-mips64/sgi/sgi.h
--- v2.3.47/linux/include/asm-mips64/sgi/sgi.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sgi/sgi.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,48 @@
+/* $Id: sgi.h,v 1.2 1999/12/04 03:59:13 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * sgi.h: Definitions specific to SGI machines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@sgi.com)
+ */
+#ifndef _ASM_SGI_SGI_H
+#define _ASM_SGI_SGI_H
+
+/* UP=UniProcessor MP=MultiProcessor(capable) */
+enum sgi_mach {
+	ip4,	/* R2k UP */
+	ip5,	/* R2k MP */
+	ip6,	/* R3k UP */
+	ip7,	/* R3k MP */
+	ip9,	/* R3k UP */
+	ip12,	/* R3kA UP, Indigo */
+	ip15,	/* R3kA MP */
+	ip17,	/* R4K UP */
+	ip19,	/* R4K MP */
+	ip20,	/* R4K UP, Indigo */
+	ip21,	/* TFP MP */
+	ip22,	/* R4x00 UP, Indigo2 */
+	ip25,	/* R10k MP */
+	ip26,	/* TFP UP, Indigo2 */
+	ip27,	/* R10k MP, R12k MP, Origin */
+	ip28,	/* R10k UP, Indigo2 */
+	ip30,
+	ip32,
+};
+
+extern enum sgi_mach sgimach;
+extern void sgi_sysinit(void);
+
+/* Many I/O space registers are byte sized and are contained within
+ * one byte per word, specifically the MSB, this macro helps out.
+ */
+#ifdef __MIPSEL__
+#define SGI_MSB(regaddr)   (regaddr)
+#else
+#define SGI_MSB(regaddr)   ((regaddr) | 0x3)
+#endif
+
+#endif /* _ASM_SGI_SGI_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sgi/sgihpc.h linux/include/asm-mips64/sgi/sgihpc.h
--- v2.3.47/linux/include/asm-mips64/sgi/sgihpc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sgi/sgihpc.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,378 @@
+/* $Id: sgihpc.h,v 1.2 1999/12/04 03:59:13 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * sgihpc.h: Various HPC I/O controller defines.  The HPC is basically
+ *           the approximate functional equivalent of the Sun SYSIO
+ *           on SGI INDY machines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1998 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_SGI_SGIHPC_H
+#define _ASM_SGI_SGIHPC_H
+
+#include <asm/page.h>
+
+extern int sgi_has_ioc2; /* to know if we have older ioc1 or ioc2. */
+extern int sgi_guiness;  /* GUINESS or FULLHOUSE machine. */
+extern int sgi_boardid;  /* Board revision. */
+
+/* An HPC dma descriptor. */
+struct hpc_dma_desc {
+	int pbuf;		 /* physical address of data buffer */
+	int cntinfo;   		 /* counter and info bits */
+#define HPCDMA_EOX    0x80000000 /* last desc in chain for tx */
+#define HPCDMA_EOR    0x80000000 /* last desc in chain for rx */
+#define HPCDMA_EOXP   0x40000000 /* end of packet for tx */
+#define HPCDMA_EORP   0x40000000 /* end of packet for rx */
+#define HPCDMA_XIE    0x20000000 /* irq generated when at end of this desc */
+#define HPCDMA_XIU    0x01000000 /* Tx buffer in use by CPU. */
+#define HPCDMA_EIPC   0x00ff0000 /* SEEQ ethernet special xternal bytecount */
+#define HPCDMA_ETXD   0x00008000 /* set to one by HPC when packet tx'd */
+#define HPCDMA_OWN    0x00004000 /* Denotes ring buffer ownership on rx */
+#define HPCDMA_BCNT   0x00003fff /* size in bytes of this dma buffer */
+
+	int pnext;		 /* paddr of next hpc_dma_desc if any */
+};
+
+typedef volatile unsigned int hpcreg;
+
+/* HPC1 stuff. */
+
+/* HPC3 stuff. */
+
+/* The set of regs for each HPC3 pbus dma channel. */
+struct hpc3_pbus_dmacregs {
+	hpcreg pbdma_bptr; /* pbus dma channel buffer ptr */
+	hpcreg pbdma_dptr; /* pbus dma channel desc ptr */
+	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
+	hpcreg pbdma_ctrl; /* pbus dma channel control reg */
+#define HPC3_PDMACTRL_SEL  0x00000002 /* little endian transfer */
+#define HPC3_PDMACTRL_RCV  0x00000004 /* direction is receive */
+#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */
+#define HPC3_PDMACTRL_ACT  0x00000010 /* start dma transfer */
+#define HPC3_PDMACTRL_LD   0x00000020 /* load enable for ACT */
+#define HPC3_PDMACTRL_RT   0x00000040 /* Use realtime GIO bus servicing */
+#define HPC3_PDMACTRL_HW   0x0000ff00 /* DMA High-water mark */
+#define HPC3_PDMACTRL_FB   0x003f0000 /* Ptr to beginning of fifo */
+#define HPC3_PDMACTRL_FE   0x3f000000 /* Ptr to end of fifo */
+
+	char _unused2[PAGE_SIZE - (sizeof(hpcreg))]; /* padding */
+};
+
+/* The HPC3 scsi registers, this does not include external ones. */
+struct hpc3_scsiregs {
+	hpcreg cbptr;   /* current dma buffer ptr, diagnostic use only */
+	hpcreg ndptr;   /* next dma descriptor ptr */
+	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
+	hpcreg bcd;     /* byte count info */
+#define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */
+#define HPC3_SBCD_XIE     0x00004000 /* Send IRQ when done with cur buf */
+#define HPC3_SBCD_EOX     0x00008000 /* Indicates this is last buf in chain */
+
+	hpcreg ctrl;    /* control register */
+#define HPC3_SCTRL_IRQ    0x01 /* IRQ asserted, either dma done or parity */
+#define HPC3_SCTRL_ENDIAN 0x02 /* DMA endian mode, 0=big 1=little */
+#define HPC3_SCTRL_DIR    0x04 /* DMA direction, 1=dev2mem 0=mem2dev */
+#define HPC3_SCTRL_FLUSH  0x08 /* Tells HPC3 to flush scsi fifos */
+#define HPC3_SCTRL_ACTIVE 0x10 /* SCSI DMA channel is active */
+#define HPC3_SCTRL_AMASK  0x20 /* DMA active inhibits PIO */
+#define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */
+#define HPC3_SCTRL_PERR   0x80 /* Bad parity on HPC3 iface to scsi controller */
+
+	hpcreg gfptr;   /* current GIO fifo ptr */
+	hpcreg dfptr;   /* current device fifo ptr */
+	hpcreg dconfig; /* DMA configuration register */
+#define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */
+#define HPC3_SDCFG_D1   0x00006 /* Cycles to spend in D1 state */
+#define HPC3_SDCFG_D2   0x00038 /* Cycles to spend in D2 state */
+#define HPC3_SDCFG_D3   0x001c0 /* Cycles to spend in D3 state */
+#define HPC3_SDCFG_HWAT 0x00e00 /* DMA high water mark */
+#define HPC3_SDCFG_HW   0x01000 /* Enable 16-bit halfword DMA accesses to scsi */
+#define HPC3_SDCFG_SWAP 0x02000 /* Byte swap all DMA accesses */
+#define HPC3_SDCFG_EPAR 0x04000 /* Enable parity checking for DMA */
+#define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */
+#define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */
+
+	hpcreg pconfig; /* PIO configuration register */
+#define HPC3_SPCFG_P3   0x0003 /* Cycles to spend in P3 state */
+#define HPC3_SPCFG_P2W  0x001c /* Cycles to spend in P2 state for writes */
+#define HPC3_SPCFG_P2R  0x01e0 /* Cycles to spend in P2 state for reads */
+#define HPC3_SPCFG_P1   0x0e00 /* Cycles to spend in P1 state */
+#define HPC3_SPCFG_HW   0x1000 /* Enable 16-bit halfword PIO accesses to scsi */
+#define HPC3_SPCFG_SWAP 0x2000 /* Byte swap all PIO accesses */
+#define HPC3_SPCFG_EPAR 0x4000 /* Enable parity checking for PIO */
+#define HPC3_SPCFG_FUJI 0x8000 /* Fujitsu scsi controller mode for faster dma/pio */
+
+	char _unused2[PAGE_SIZE - (6 * sizeof(hpcreg))]; /* padding */
+};
+
+/* SEEQ ethernet HPC3 registers, only one seeq per HPC3. */
+struct hpc3_ethregs {
+	/* Receiver registers. */
+	hpcreg rx_cbptr;   /* current dma buffer ptr, diagnostic use only */
+	hpcreg rx_ndptr;   /* next dma descriptor ptr */
+	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
+	hpcreg rx_bcd;     /* byte count info */
+#define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */
+#define HPC3_ERXBCD_XIE     0x20000000 /* HPC3 interrupts cpu at end of this buf */
+#define HPC3_ERXBCD_EOX     0x80000000 /* flags this as end of descriptor chain */
+
+	hpcreg rx_ctrl;    /* control register */
+#define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */
+#define HPC3_ERXCTRL_STAT6  0x00000040 /* Rdonly irq status */
+#define HPC3_ERXCTRL_STAT7  0x00000080 /* Rdonlt old/new status bit from Seeq */
+#define HPC3_ERXCTRL_ENDIAN 0x00000100 /* Endian for dma channel, little=1 big=0 */
+#define HPC3_ERXCTRL_ACTIVE 0x00000200 /* Tells if DMA transfer is in progress */
+#define HPC3_ERXCTRL_AMASK  0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */
+#define HPC3_ERXCTRL_RBO    0x00000800 /* Receive buffer overflow if set to 1 */
+
+	hpcreg rx_gfptr;   /* current GIO fifo ptr */
+	hpcreg rx_dfptr;   /* current device fifo ptr */
+	hpcreg _unused2;   /* padding */
+	hpcreg rx_reset;   /* reset register */
+#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */
+#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */
+#define HPC3_ERXRST_LBACK  0x4 /* Enable diagnostic loopback mode of Seeq8003 */
+
+	hpcreg rx_dconfig; /* DMA configuration register */
+#define HPC3_ERXDCFG_D1    0x0000f /* Cycles to spend in D1 state for PIO */
+#define HPC3_ERXDCFG_D2    0x000f0 /* Cycles to spend in D2 state for PIO */
+#define HPC3_ERXDCFG_D3    0x00f00 /* Cycles to spend in D3 state for PIO */
+#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
+#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
+#define HPC3_ERXDCFG_FEOP  0x04000 /* Bad packet marker timeout enable */
+#define HPC3_ERXDCFG_FIRQ  0x08000 /* Another bad packet timeout enable */
+#define HPC3_ERXDCFG_PTO   0x30000 /* Programmed timeout value for above two */
+
+	hpcreg rx_pconfig; /* PIO configuration register */
+#define HPC3_ERXPCFG_P1    0x000f /* Cycles to spend in P1 state for PIO */
+#define HPC3_ERXPCFG_P2    0x00f0 /* Cycles to spend in P2 state for PIO */
+#define HPC3_ERXPCFG_P3    0x0f00 /* Cycles to spend in P3 state for PIO */
+#define HPC3_ERXPCFG_TST   0x1000 /* Diagnistic ram test feature bit */
+
+	char _unused3[PAGE_SIZE - (8 * sizeof(hpcreg))]; /* padding */
+
+	/* Transmitter registers. */
+	hpcreg tx_cbptr;   /* current dma buffer ptr, diagnostic use only */
+	hpcreg tx_ndptr;   /* next dma descriptor ptr */
+	char _unused4[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
+	hpcreg tx_bcd;     /* byte count info */
+#define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */
+#define HPC3_ETXBCD_ESAMP   0x10000000 /* if set, too late to add descriptor */
+#define HPC3_ETXBCD_XIE     0x20000000 /* Interrupt cpu at end of cur desc */
+#define HPC3_ETXBCD_EOP     0x40000000 /* Last byte of cur buf is end of packet */
+#define HPC3_ETXBCD_EOX     0x80000000 /* This buf is the end of desc chain */
+
+	hpcreg tx_ctrl;    /* control register */
+#define HPC3_ETXCTRL_STAT30 0x0000000f /* Rdonly copy of seeq tx stat reg */
+#define HPC3_ETXCTRL_STAT4  0x00000010 /* Indicate late collision occurred */
+#define HPC3_ETXCTRL_STAT75 0x000000e0 /* Rdonly irq status from seeq */
+#define HPC3_ETXCTRL_ENDIAN 0x00000100 /* Dma channel endian mode, 1=little 0=big */
+#define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */
+#define HPC3_ETXCTRL_AMASK  0x00000400 /* Indicates ACTIVE inhibits PIO's */
+
+	hpcreg tx_gfptr;   /* current GIO fifo ptr */
+	hpcreg tx_dfptr;   /* current device fifo ptr */
+	char _unused5[PAGE_SIZE - (4 * sizeof(hpcreg))]; /* padding */
+};
+
+struct hpc3_regs {
+	/* First regs for the PBUS 8 dma channels. */
+	struct hpc3_pbus_dmacregs pbdma[8];
+
+	/* Now the HPC scsi registers, we get two scsi reg sets. */
+	struct hpc3_scsiregs scsi_chan0, scsi_chan1;
+
+	/* The SEEQ hpc3 ethernet dma/control registers. */
+	struct hpc3_ethregs ethregs;
+
+	/* Here are where the hpc3 fifo's can be directly accessed
+	 * via PIO accesses.  Under normal operation we never stick
+	 * our grubby paws in here so it's just padding.
+	 */
+	char _unused1[PAGE_SIZE * 24];
+
+	/* HPC3 irq status regs.  Due to a peculiar bug you need to
+	 * look at two different register addresses to get at all of
+	 * the status bits.  The first reg can only reliably report
+	 * bits 4:0 of the status, and the second reg can only
+	 * reliably report bits 9:5 of the hpc3 irq status.  I told
+	 * you it was a peculiar bug. ;-)
+	 */
+	hpcreg istat0;      /* Irq status, only bits <4:0> reliable. */
+#define HPC3_ISTAT_PBIMASK  0x0ff  /* irq bits for pbus devs 0 --> 7 */
+#define HPC3_ISTAT_SC0MASK  0x100  /* irq bit for scsi channel 0 */
+#define HPC3_ISTAT_SC1MASK  0x200  /* irq bit for scsi channel 1 */
+
+	hpcreg gio64_misc;  /* GIO64 misc control bits. */
+#define HPC3_GIOMISC_ERTIME   0x1    /* Enable external timer real time. */
+#define HPC3_GIOMISC_DENDIAN  0x2    /* dma descriptor endian, 1=lit 0=big */
+
+	hpcreg eeprom_data; /* EEPROM data reg. */
+#define HPC3_EEPROM_EPROT     0x01   /* Protect register enable */
+#define HPC3_EEPROM_CSEL      0x02   /* Chip select */
+#define HPC3_EEPROM_ECLK      0x04   /* EEPROM clock */
+#define HPC3_EEPROM_DATO      0x08   /* Data out */
+#define HPC3_EEPROM_DATI      0x10   /* Data in */
+
+	hpcreg istat1;      /* Irq status, only bits <9:5> reliable. */
+	hpcreg gio64_estat; /* GIO64 error interrupt status reg. */
+#define HPC3_GIOESTAT_BLMASK  0x000ff  /* Bus lane where bad parity occurred */
+#define HPC3_GIOESTAT_CTYPE   0x00100  /* Bus cycle type, 0=PIO 1=DMA */
+#define HPC3_GIOESTAT_PIDMSK  0x3f700  /* DMA channel parity identifier */
+
+	/* Now direct PIO per-HPC3 peripheral access to external regs. */
+	char _unused2[0x13fec]; /* Trust me... */
+	hpcreg scsi0_ext[256];  /* SCSI channel 0 external regs */
+	char _unused3[0x07c00]; /* Trust me... */
+	hpcreg scsi1_ext[256];  /* SCSI channel 1 external regs */
+	char _unused4[0x07c00]; /* It'll only hurt a little... */
+
+	/* Did DaveM forget the ethernet external regs?
+	 * Anyhow, they're not here and we need some padding instead.
+	 */
+	char _unused5[0x04000]; /* It'll hurt a lot if you leave this out */
+
+	/* Per-peripheral device external registers and dma/pio control. */
+	hpcreg pbus_extregs[16][256]; /* 2nd indice indexes controller */
+	hpcreg pbus_dmacfgs[8][128]; /* 2nd indice indexes controller */
+#define HPC3_PIODCFG_D3R    0x00000001 /* Cycles to spend in D3 for reads */
+#define HPC3_PIODCFG_D4R    0x0000001e /* Cycles to spend in D4 for reads */
+#define HPC3_PIODCFG_D5R    0x000001e0 /* Cycles to spend in D5 for reads */
+#define HPC3_PIODCFG_D3W    0x00000200 /* Cycles to spend in D3 for writes */
+#define HPC3_PIODCFG_D4W    0x00003c00 /* Cycles to spend in D4 for writes */
+#define HPC3_PIODCFG_D5W    0x0003c000 /* Cycles to spend in D5 for writes */
+#define HPC3_PIODCFG_HWORD  0x00040000 /* Enable 16-bit dma access mode */
+#define HPC3_PIODCFG_EHI    0x00080000 /* Places halfwords on high 16 bits of bus */
+#define HPC3_PIODCFG_RTIME  0x00200000 /* Make this device real time on GIO bus */
+#define HPC3_PIODCFG_BURST  0x07c00000 /* 5 bit burst count for DMA device */
+#define HPC3_PIODCFG_DRQLV  0x08000000 /* Use live pbus_dreq unsynchronized signal */
+
+	hpcreg pbus_piocfgs[64][10]; /* 2nd indice indexes controller */
+#define HPC3_PIOPCFG_RP2    0x00001  /* Cycles to spend in P2 state for reads */
+#define HPC3_PIOPCFG_RP3    0x0001e  /* Cycles to spend in P3 state for reads */
+#define HPC3_PIOPCFG_RP4    0x001e0  /* Cycles to spend in P4 state for reads */
+#define HPC3_PIOPCFG_WP2    0x00200  /* Cycles to spend in P2 state for writes */
+#define HPC3_PIOPCFG_WP3    0x03c00  /* Cycles to spend in P3 state for writes */
+#define HPC3_PIOPCFG_WP4    0x3c000  /* Cycles to spend in P4 state for writes */
+#define HPC3_PIOPCFG_HW     0x40000  /* Enable 16-bit PIO accesses */
+#define HPC3_PIOPCFG_EHI    0x80000  /* Place even address bits in bits <15:8> */
+
+	/* PBUS PROM control regs. */
+	hpcreg pbus_promwe;     /* PROM write enable register */
+#define HPC3_PROM_WENAB     0x1 /* Enable writes to the PROM */
+
+	char _unused6[0x800 - sizeof(hpcreg)];
+	hpcreg pbus_promswap;   /* Chip select swap reg */
+#define HPC3_PROM_SWAP      0x1 /* invert GIO addr bit to select prom0 or prom1 */
+
+	char _unused7[0x800 - sizeof(hpcreg)];
+	hpcreg pbus_gout;       /* PROM general purpose output reg */
+#define HPC3_PROM_STAT      0x1 /* General purpose status bit in gout */
+
+	char _unused8[0x1000 - sizeof(hpcreg)];
+	hpcreg pbus_promram[16384]; /* 64k of PROM battery backed ram */
+};
+
+/* It is possible to have two HPC3's within the address space on
+ * one machine, though only having one is more likely on an INDY.
+ * Controller 0 lives at physical address 0x1fb80000 and the controller
+ * 1 if present lives at address 0x1fb00000.
+ */
+extern struct hpc3_regs *hpc3c0, *hpc3c1;
+#define HPC3_CHIP0_PBASE   0x1fb80000 /* physical */
+#define HPC3_CHIP1_PBASE   0x1fb00000 /* physical */
+
+/* Control and misc status information, these live in pbus channel 6. */
+struct hpc3_miscregs {
+	hpcreg pdata, pctrl, pstat, pdmactrl, pistat, pimask;
+	hpcreg ptimer1, ptimer2, ptimer3, ptimer4;
+	hpcreg _unused1[2];
+	hpcreg ser1cmd, ser1data;
+	hpcreg ser0cmd, ser0data;
+	hpcreg kbdmouse0, kbdmouse1;
+	hpcreg gcsel, genctrl, panel;
+	hpcreg _unused2;
+	hpcreg sysid;
+	hpcreg _unused3;
+	hpcreg read, _unused4;
+	hpcreg dselect;
+#define HPC3_DSELECT_SCLK10MHZ   0x00 /* use 10MHZ serial clock */
+#define HPC3_DSELECT_ISDNB       0x01 /* enable isdn B */
+#define HPC3_DSELECT_ISDNA       0x02 /* enable isdn A */
+#define HPC3_DSELECT_LPR         0x04 /* use parallel DMA */
+#define HPC3_DSELECT_SCLK667MHZ  0x10 /* use 6.67MHZ serial clock */
+#define HPC3_DSELECT_SCLKEXT     0x20 /* use external serial clock */
+
+	hpcreg _unused5;
+	hpcreg write1;
+#define HPC3_WRITE1_PRESET    0x01  /* 0=LPR_RESET, 1=NORMAL */
+#define HPC3_WRITE1_KMRESET   0x02  /* 0=KBDMOUSE_RESET, 1=NORMAL */
+#define HPC3_WRITE1_ERESET    0x04  /* 0=EISA_RESET, 1=NORMAL */
+#define HPC3_WRITE1_GRESET    0x08  /* 0=MAGIC_GIO_RESET, 1=NORMAL */
+#define HPC3_WRITE1_LC0OFF    0x10  /* turn led off (guiness=red, else green) */
+#define HPC3_WRITE1_LC1OFF    0x20  /* turn led off (guiness=green, else amber) */
+
+	hpcreg _unused6;
+	hpcreg write2;
+#define HPC3_WRITE2_NTHRESH  0x01 /* use 4.5db threshhold */
+#define HPC3_WRITE2_TPSPEED  0x02 /* use 100ohm TP speed */
+#define HPC3_WRITE2_EPSEL    0x04 /* force cable mode: 1=AUI 0=TP */
+#define HPC3_WRITE2_EASEL    0x08 /* 1=autoselect 0=manual cable selection */
+#define HPC3_WRITE2_U1AMODE  0x10 /* 1=PC 0=MAC UART mode */
+#define HPC3_WRITE2_U0AMODE  0x20 /* 1=PC 0=MAC UART mode */
+#define HPC3_WRITE2_MLO      0x40 /* 1=4.75V 0=+5V */
+#define HPC3_WRITE2_MHI      0x80 /* 1=5.25V 0=+5V */
+};
+extern struct hpc3_miscregs *hpc3mregs;
+#define HPC3_MREGS_PBASE   0x1fbd9800 /* physical */
+
+/* We need software copies of these because they are write only. */
+extern unsigned int sgi_hpc_write1, sgi_hpc_write2;
+
+#define SGI_KEYBOARD_IRQ 20
+
+struct hpc_keyb {
+#ifdef __MIPSEB__
+	unsigned char _unused0[3];
+	volatile unsigned char data;
+	unsigned char _unused1[3];
+	volatile unsigned char command;
+#else
+	volatile unsigned char data;
+	unsigned char _unused0[3];
+	volatile unsigned char command;
+	unsigned char _unused1[3];
+#endif
+};
+
+/* Indy RTC  */
+
+/* The layout of registers for the INDY Dallas 1286 clock chipset. */
+struct indy_clock {
+	volatile unsigned int hsec;
+	volatile unsigned int sec;
+	volatile unsigned int min;
+	volatile unsigned int malarm;
+	volatile unsigned int hr;
+	volatile unsigned int halarm;
+	volatile unsigned int day;
+	volatile unsigned int dalarm;
+	volatile unsigned int date;
+	volatile unsigned int month;
+	volatile unsigned int year;
+	volatile unsigned int cmd;
+	volatile unsigned int whsec;
+	volatile unsigned int wsec;
+	volatile unsigned int _unused0[50];
+};
+
+#define INDY_CLOCK_REGS (KSEG1ADDR(0x1fbe0000))
+
+extern void sgihpc_init(void);
+
+#endif /* _ASM_SGI_SGIHPC_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sgi/sgimc.h linux/include/asm-mips64/sgi/sgimc.h
--- v2.3.47/linux/include/asm-mips64/sgi/sgimc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sgi/sgimc.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,229 @@
+/* $Id: sgimc.h,v 1.2 1999/12/04 03:59:13 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * sgimc.h: Definitions for memory controller hardware found on
+ *          SGI IP20, IP22, IP26, and IP28 machines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SGI_SGIMC_H
+#define _ASM_SGI_SGIMC_H
+
+struct sgimc_misc_ctrl {
+	u32 _unused1;
+	volatile u32 cpuctrl0;     /* CPU control register 0, readwrite */
+#define SGIMC_CCTRL0_REFS         0x0000000f /* REFS mask */
+#define SGIMC_CCTRL0_EREFRESH     0x00000010 /* Memory refresh enable */
+#define SGIMC_CCTRL0_EPERRGIO     0x00000020 /* GIO parity error enable */
+#define SGIMC_CCTRL0_EPERRMEM     0x00000040 /* Main mem parity error enable */
+#define SGIMC_CCTRL0_EPERRCPU     0x00000080 /* CPU bus parity error enable */
+#define SGIMC_CCTRL0_WDOG         0x00000100 /* Watchdog timer enable */
+#define SGIMC_CCTRL0_SYSINIT      0x00000200 /* System init bit */
+#define SGIMC_CCTRL0_GFXRESET     0x00000400 /* Graphics interface reset */
+#define SGIMC_CCTRL0_EISALOCK     0x00000800 /* Lock CPU from memory for EISA */
+#define SGIMC_CCTRL0_EPERRSCMD    0x00001000 /* SysCMD bus parity error enable */
+#define SGIMC_CCTRL0_IENAB        0x00002000 /* Allow interrupts from MC */
+#define SGIMC_CCTRL0_ESNOOP       0x00004000 /* Snooping I/O enable */
+#define SGIMC_CCTRL0_EPROMWR      0x00008000 /* Prom writes from cpu enable */
+#define SGIMC_CCTRL0_WRESETPMEM   0x00010000 /* Perform warm reset, preserves mem */
+#define SGIMC_CCTRL0_LENDIAN      0x00020000 /* Put MC in little-endian mode */
+#define SGIMC_CCTRL0_WRESETDMEM   0x00040000 /* Warm reset, destroys mem contents */
+#define SGIMC_CCTRL0_CMEMBADPAR   0x02000000 /* Generate bad perr from cpu to mem */
+#define SGIMC_CCTRL0_R4KNOCHKPARR 0x04000000 /* Don't chk parity on mem data reads */
+#define SGIMC_CCTRL0_GIOBTOB      0x08000000 /* Allow GIO back to back writes */
+
+	u32 _unused2;
+	volatile u32 cpuctrl1;     /* CPU control register 1, readwrite */
+#define SGIMC_CCTRL1_EGIOTIMEO    0x00000010 /* GIO bus timeout enable */
+#define SGIMC_CCTRL1_FIXEDEHPC    0x00001000 /* Fixed HPC endianness */
+#define SGIMC_CCTRL1_LITTLEHPC    0x00002000 /* Little endian HPC */
+#define SGIMC_CCTRL1_FIXEDEEXP0   0x00004000 /* Fixed EXP0 endianness */
+#define SGIMC_CCTRL1_LITTLEEXP0   0x00008000 /* Little endian EXP0 */
+#define SGIMC_CCTRL1_FIXEDEEXP1   0x00010000 /* Fixed EXP1 endianness */
+#define SGIMC_CCTRL1_LITTLEEXP1   0x00020000 /* Little endian EXP1 */
+
+	u32 _unused3;
+	volatile u32 watchdogt;    /* Watchdog reg rdonly, write clears */
+
+	u32 _unused4;
+	volatile u32 systemid;     /* MC system ID register, readonly */
+#define SGIMC_SYSID_MASKREV       0x0000000f /* Revision of MC controller */
+#define SGIMC_SYSID_EPRESENT      0x00000010 /* Indicates presence of EISA bus */
+
+	u32 _unused5[3];
+	volatile u32 divider;      /* Divider reg for RPSS */
+
+	u32 _unused6;
+	volatile unsigned char eeprom;       /* EEPROM byte reg for r4k */
+#define SGIMC_EEPROM_PRE          0x00000001 /* eeprom chip PRE pin assertion */
+#define SGIMC_EEPROM_CSEL         0x00000002 /* Active high, eeprom chip select */
+#define SGIMC_EEPROM_SECLOCK      0x00000004 /* EEPROM serial clock */
+#define SGIMC_EEPROM_SDATAO       0x00000008 /* Serial EEPROM data-out */
+#define SGIMC_EEPROM_SDATAI       0x00000010 /* Serial EEPROM data-in */
+
+	unsigned char _unused7[3];
+	u32 _unused8[3];
+	volatile unsigned short rcntpre;     /* Preload refresh counter */
+
+	unsigned short _unused9;
+	u32 _unused9a;
+	volatile unsigned short rcounter;    /* Readonly refresh counter */
+
+	unsigned short _unused10;
+	u32 _unused11[13];
+	volatile u32 gioparm;      /* Parameter word for GIO64 */
+#define SGIMC_GIOPARM_HPC64       0x00000001 /* HPC talks to GIO using 64-bits */
+#define SGIMC_GIOPARM_GFX64       0x00000002 /* GFX talks to GIO using 64-bits */
+#define SGIMC_GIOPARM_EXP064      0x00000004 /* EXP(slot0) talks using 64-bits */
+#define SGIMC_GIOPARM_EXP164      0x00000008 /* EXP(slot1) talks using 64-bits */
+#define SGIMC_GIOPARM_EISA64      0x00000010 /* EISA bus talks 64-bits to GIO */
+#define SGIMC_GIOPARM_HPC264      0x00000020 /* 2nd HPX talks 64-bits to GIO */
+#define SGIMC_GIOPARM_RTIMEGFX    0x00000040 /* GFX device has realtime attr */
+#define SGIMC_GIOPARM_RTIMEEXP0   0x00000080 /* EXP(slot0) has realtime attr */
+#define SGIMC_GIOPARM_RTIMEEXP1   0x00000100 /* EXP(slot1) has realtime attr */
+#define SGIMC_GIOPARM_MASTEREISA  0x00000200 /* EISA bus can act as bus master */
+#define SGIMC_GIOPARM_ONEBUS      0x00000400 /* Exists one GIO64 pipelined bus */
+#define SGIMC_GIOPARM_MASTERGFX   0x00000800 /* GFX can act as a bus master */
+#define SGIMC_GIOPARM_MASTEREXP0  0x00001000 /* EXP(slot0) can bus master */
+#define SGIMC_GIOPARM_MASTEREXP1  0x00002000 /* EXP(slot1) can bus master */
+#define SGIMC_GIOPARM_PLINEEXP0   0x00004000 /* EXP(slot0) has pipeline attr */
+#define SGIMC_GIOPARM_PLINEEXP1   0x00008000 /* EXP(slot1) has pipeline attr */
+
+	u32 _unused13;
+	volatile unsigned short cputp;       /* CPU bus arb time period */
+
+	unsigned short _unused14;
+	u32 _unused15[3];
+	volatile unsigned short lbursttp;    /* Time period for long bursts */
+
+	unsigned short _unused16;
+	u32 _unused17[9];
+	volatile u32 mconfig0;     /* Memory config register zero */
+	u32 _unused18;
+	volatile u32 mconfig1;     /* Memory config register one */
+
+        /* These defines apply to both mconfig registers above. */
+#define SGIMC_MCONFIG_FOURMB     0x00000000  /* Physical ram = 4megs */
+#define SGIMC_MCONFIG_EIGHTMB    0x00000100  /* Physical ram = 8megs */
+#define SGIMC_MCONFIG_SXTEENMB   0x00000300  /* Physical ram = 16megs */
+#define SGIMC_MCONFIG_TTWOMB     0x00000700  /* Physical ram = 32megs */
+#define SGIMC_MCONFIG_SFOURMB    0x00000f00  /* Physical ram = 64megs */
+#define SGIMC_MCONFIG_OTEIGHTMB  0x00001f00  /* Physical ram = 128megs */
+#define SGIMC_MCONFIG_RMASK      0x00001f00  /* Ram config bitmask */
+
+	u32 _unused19;
+	volatile u32 cmacc;        /* Mem access config for CPU */
+	u32 _unused20;
+	volatile u32 gmacc;        /* Mem access config for GIO */
+
+	/* This define applies to both cmacc and gmacc registers above. */
+#define SGIMC_MACC_ALIASBIG       0x20000000 /* 512MB home for alias */
+
+	/* Error address/status regs from GIO and CPU perspectives. */
+	u32 _unused21;
+	volatile u32 cerr;         /* Error address reg for CPU */
+	u32 _unused22;
+	volatile u32 cstat;        /* Status reg for CPU */
+	u32 _unused23;
+	volatile u32 gerr;         /* Error address reg for GIO */
+	u32 _unused24;
+	volatile u32 gstat;        /* Status reg for GIO */
+
+	/* Special hard bus locking registers. */
+	u32 _unused25;
+	volatile unsigned char syssembit;    /* Uni-bit system semaphore */
+	unsigned char _unused26[3];
+	u32 _unused27;
+	volatile unsigned char mlock;        /* Global GIO memory access lock */
+	unsigned char _unused28[3];
+	u32 _unused29;
+	volatile unsigned char elock;        /* Locks EISA from GIO accesses */
+
+	/* GIO dma control registers. */
+	unsigned char _unused30[3];
+	u32 _unused31[14];
+	volatile u32 gio_dma_trans;/* DMA mask to translation GIO addrs */
+	u32 _unused32;
+	volatile u32 gio_dma_sbits;/* DMA GIO addr substitution bits */
+	u32 _unused33;
+	volatile u32 dma_intr_cause; /* DMA IRQ cause indicator bits */
+	u32 _unused34;
+	volatile u32 dma_ctrl;     /* Main DMA control reg */
+
+	/* DMA TLB entry 0 */
+	u32 _unused35;
+	volatile u32 dtlb_hi0;
+	u32 _unused36;
+	volatile u32 dtlb_lo0;
+
+	/* DMA TLB entry 1 */
+	u32 _unused37;
+	volatile u32 dtlb_hi1;
+	u32 _unused38;
+	volatile u32 dtlb_lo1;
+
+	/* DMA TLB entry 2 */
+	u32 _unused39;
+	volatile u32 dtlb_hi2;
+	u32 _unused40;
+	volatile u32 dtlb_lo2;
+
+	/* DMA TLB entry 3 */
+	u32 _unused41;
+	volatile u32 dtlb_hi3;
+	u32 _unused42;
+	volatile u32 dtlb_lo3;
+};
+
+/* MC misc control registers live at physical 0x1fa00000. */
+extern struct sgimc_misc_ctrl *mcmisc_regs;
+extern u32 *rpsscounter;          /* Chirps at 100ns */
+
+struct sgimc_dma_ctrl {
+	u32 _unused1;
+	volatile u32 maddronly;   /* Address DMA goes at */
+	u32 _unused2;
+	volatile u32 maddrpdeflts; /* Same as above, plus set defaults */
+	u32 _unused3;
+	volatile u32 dmasz;       /* DMA count */
+	u32 _unused4;
+	volatile u32 ssize;       /* DMA stride size */
+	u32 _unused5;
+	volatile u32 gmaddronly;  /* Set GIO DMA but do not start trans */
+	u32 _unused6;
+	volatile u32 dmaddnpgo;   /* Set GIO DMA addr + start transfer */
+	u32 _unused7;
+	volatile u32 dmamode;     /* DMA mode config bit settings */
+	u32 _unused8;
+	volatile u32 dmacount;    /* Zoom and byte count for DMA */
+	u32 _unused9;
+	volatile u32 dmastart;    /* Pedal to the metal. */
+	u32 _unused10;
+	volatile u32 dmarunning;  /* DMA op is in progress */
+	u32 _unused11;
+
+	/* Set dma addr, defaults, and kick it */
+	volatile u32 maddr_defl_go; /* go go go! -lm */
+};
+
+/* MC controller dma regs live at physical 0x1fa02000. */
+extern struct sgimc_dma_ctrl *dmactrlregs;
+
+/* Base location of the two ram banks found in IP2[0268] machines. */
+#define SGIMC_SEG0_BADDR     0x08000000
+#define SGIMC_SEG1_BADDR     0x20000000
+
+/* Maximum size of the above banks are per machine. */
+extern u32 sgimc_seg0_size, sgimc_seg1_size;
+#define SGIMC_SEG0_SIZE_ALL         0x10000000 /* 256MB */
+#define SGIMC_SEG1_SIZE_IP20_IP22   0x08000000 /* 128MB */
+#define SGIMC_SEG1_SIZE_IP26_IP28   0x20000000 /* 512MB */
+
+extern void sgimc_init(void);
+
+#endif /* _ASM_SGI_SGIMC_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sgi/sgint23.h linux/include/asm-mips64/sgi/sgint23.h
--- v2.3.47/linux/include/asm-mips64/sgi/sgint23.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sgi/sgint23.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,218 @@
+/* $Id: sgint23.h,v 1.2 1999/12/04 03:59:13 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * sgint23.h: Defines for the SGI INT2 and INT3 chipsets.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - INT2 corrections
+ */
+#ifndef _ASM_SGI_SGINT23_H
+#define _ASM_SGI_SGINT23_H
+
+/* These are the virtual IRQ numbers, we divide all IRQ's into
+ * 'spaces', the 'space' determines where and how to enable/disable
+ * that particular IRQ on an SGI machine.  Add new 'spaces' as new
+ * IRQ hardware is supported.
+ */
+#define SGINT_LOCAL0   0   /* INDY has 8 local0 irq levels */
+#define SGINT_LOCAL1   8   /* INDY has 8 local1 irq levels */
+#define SGINT_LOCAL2   16  /* INDY has 8 local2 vectored irq levels */
+#define SGINT_LOCAL3   24  /* INDY has 8 local3 vectored irq levels */
+#define SGINT_GIO      32  /* INDY has 9 GIO irq levels */
+#define SGINT_HPCDMA   41  /* INDY has 11 HPCDMA irq _sources_ */
+#define SGINT_END      52  /* End of 'spaces' */
+
+/* Individual interrupt definitions for the INDY and Indigo2
+ */
+
+#define SGI_WD93_0_IRQ	SGINT_LOCAL0 + 1	/* 1st onboard WD93 */
+#define SGI_WD93_1_IRQ	SGINT_LOCAL0 + 2	/* 2nd onboard WD93 */
+#define SGI_ENET_IRQ	SGINT_LOCAL0 + 3	/* onboard ethernet */
+
+#define SGI_PANEL_IRQ	SGINT_LOCAL1 + 1	/* front panel */
+
+#define SGI_EISA_IRQ	SGINT_LOCAL2 + 3	/* EISA interrupts */
+#define SGI_KEYBOARD_IRQ	SGINT_LOCAL2 + 4	/* keyboard */
+#define SGI_SERIAL_IRQ	SGINT_LOCAL2 + 5	/* onboard serial */
+
+/* Individual interrupt definitions for the INDY and Indigo2
+ */
+
+#define SGI_WD93_0_IRQ	SGINT_LOCAL0 + 1	/* 1st onboard WD93 */
+#define SGI_WD93_1_IRQ	SGINT_LOCAL0 + 2	/* 2nd onboard WD93 */
+#define SGI_ENET_IRQ	SGINT_LOCAL0 + 3	/* onboard ethernet */
+
+#define SGI_PANEL_IRQ	SGINT_LOCAL1 + 1	/* front panel */
+
+#define SGI_EISA_IRQ	SGINT_LOCAL2 + 3	/* EISA interrupts */
+#define SGI_KEYBOARD_IRQ	SGINT_LOCAL2 + 4	/* keyboard */
+#define SGI_SERIAL_IRQ	SGINT_LOCAL2 + 5	/* onboard serial */
+
+/* INT2 occupies HPC PBUS slot 4, INT3 uses slot 6. */
+#define SGI_INT2_BASE 0x1fbd9000 /* physical */
+#define SGI_INT3_BASE 0x1fbd9880 /* physical */
+
+struct sgi_ioc_ints {
+#ifdef __MIPSEB__
+	unsigned char _unused0[3];
+	volatile unsigned char istat0;    /* Interrupt status zero */
+#else
+	volatile unsigned char istat0;    /* Interrupt status zero */
+	unsigned char _unused0[3];
+#endif
+#define ISTAT0_FFULL           0x01
+#define ISTAT0_SCSI0           0x02
+#define ISTAT0_SCSI1           0x04
+#define ISTAT0_ENET            0x08
+#define ISTAT0_GFXDMA          0x10
+#define ISTAT0_LPR             0x20
+#define ISTAT0_HPC2            0x40
+#define ISTAT0_LIO2            0x80
+
+#ifdef __MIPSEB__
+	unsigned char _unused1[3];
+	volatile unsigned char imask0;    /* Interrupt mask zero */
+	unsigned char _unused2[3];
+	volatile unsigned char istat1;    /* Interrupt status one */
+#else
+	volatile unsigned char imask0;    /* Interrupt mask zero */
+	unsigned char _unused1[3];
+	volatile unsigned char istat1;    /* Interrupt status one */
+	unsigned char _unused2[3];
+#endif
+#define ISTAT1_ISDNI           0x01
+#define ISTAT1_PWR             0x02
+#define ISTAT1_ISDNH           0x04
+#define ISTAT1_LIO3            0x08
+#define ISTAT1_HPC3            0x10
+#define ISTAT1_AFAIL           0x20
+#define ISTAT1_VIDEO           0x40
+#define ISTAT1_GIO2            0x80
+
+#ifdef __MIPSEB__
+	unsigned char _unused3[3];
+	volatile unsigned char imask1;    /* Interrupt mask one */
+	unsigned char _unused4[3];
+	volatile unsigned char vmeistat;  /* VME interrupt status */
+	unsigned char _unused5[3];
+	volatile unsigned char cmeimask0; /* VME interrupt mask zero */
+	unsigned char _unused6[3];
+	volatile unsigned char cmeimask1; /* VME interrupt mask one */
+	unsigned char _unused7[3];
+	volatile unsigned char cmepol;    /* VME polarity */
+#else
+	volatile unsigned char imask1;    /* Interrupt mask one */
+	unsigned char _unused3[3];
+	volatile unsigned char vmeistat;  /* VME interrupt status */
+	unsigned char _unused4[3];
+	volatile unsigned char cmeimask0; /* VME interrupt mask zero */
+	unsigned char _unused5[3];
+	volatile unsigned char cmeimask1; /* VME interrupt mask one */
+	unsigned char _unused6[3];
+	volatile unsigned char cmepol;    /* VME polarity */
+	unsigned char _unused7[3];
+#endif
+};
+
+struct sgi_ioc_timers {
+#ifdef __MIPSEB__
+	unsigned char _unused0[3];
+	volatile unsigned char tcnt0;  /* counter 0 */
+	unsigned char _unused1[3];
+	volatile unsigned char tcnt1;  /* counter 1 */
+	unsigned char _unused2[3];
+	volatile unsigned char tcnt2;  /* counter 2 */
+	unsigned char _unused3[3];
+	volatile unsigned char tcword; /* control word */
+#else
+	volatile unsigned char tcnt0;  /* counter 0 */
+	unsigned char _unused0[3];
+	volatile unsigned char tcnt1;  /* counter 1 */
+	unsigned char _unused1[3];
+	volatile unsigned char tcnt2;  /* counter 2 */
+	unsigned char _unused2[3];
+	volatile unsigned char tcword; /* control word */
+	unsigned char _unused3[3];
+#endif
+};
+
+/* Timer control word bits. */
+#define SGINT_TCWORD_BCD    0x01 /* Use BCD mode for counters */
+#define SGINT_TCWORD_MMASK  0x0e /* Mode bitmask. */
+#define SGINT_TCWORD_MITC   0x00 /* IRQ on terminal count (doesn't work) */
+#define SGINT_TCWORD_MOS    0x02 /* One-shot IRQ mode. */
+#define SGINT_TCWORD_MRGEN  0x04 /* Normal rate generation */
+#define SGINT_TCWORD_MSWGEN 0x06 /* Square wave generator mode */
+#define SGINT_TCWORD_MSWST  0x08 /* Software strobe */
+#define SGINT_TCWORD_MHWST  0x0a /* Hardware strobe */
+#define SGINT_TCWORD_CMASK  0x30 /* Command mask */
+#define SGINT_TCWORD_CLAT   0x00 /* Latch command */
+#define SGINT_TCWORD_CLSB   0x10 /* LSB read/write */
+#define SGINT_TCWORD_CMSB   0x20 /* MSB read/write */
+#define SGINT_TCWORD_CALL   0x30 /* Full counter read/write */
+#define SGINT_TCWORD_CNT0   0x00 /* Select counter zero */
+#define SGINT_TCWORD_CNT1   0x40 /* Select counter one */
+#define SGINT_TCWORD_CNT2   0x80 /* Select counter two */
+#define SGINT_TCWORD_CRBCK  0xc0 /* Readback command */
+
+#define SGINT_TCSAMP_COUNTER  10255
+
+/* FIXME: What does this really look like?  It was written to have
+ * 17 registers, but there are only 16 in my Indigo2.
+ * I guessed at which one to remove...  	- andrewb
+ */
+struct sgi_int2_regs {
+	struct sgi_ioc_ints ints;
+
+	volatile u32 ledbits; 		  /* LED control bits */
+#define INT2_LED_TXCLK         0x01       /* GPI to TXCLK enable */
+#define INT2_LED_SERSLCT0      0x02       /* serial port0: 0=apple 1=pc */
+#define INT2_LED_SERSLCT1      0x04       /* serial port1: 0=apple 1=pc */
+#define INT2_LED_CHEAPER       0x08       /* 0=cheapernet 1=ethernet */
+#define INT2_LED_POWEROFF      0x10       /* Power-off request, active high */
+
+#ifdef __MIPSEB__
+	unsigned char _unused0[3];
+	volatile unsigned char tclear;    /* Timer clear strobe address */
+#else
+	volatile unsigned char tclear;    /* Timer clear strobe address */
+	unsigned char _unused0[3];
+#endif
+#define INT2_TCLEAR_T0CLR      0x1        /* Clear timer0 IRQ */
+#define INT2_TCLEAR_T1CLR      0x2        /* Clear timer1 IRQ */
+/* I am guesing there are only two unused registers here 
+ * but I could be wrong...			- andrewb
+ */
+/*	u32 _unused[3]; */
+	u32 _unused[2];
+	struct sgi_ioc_timers timers;
+};
+
+struct sgi_int3_regs {
+	struct sgi_ioc_ints ints;
+
+#ifdef __MIPSEB__
+	unsigned char _unused0[3];
+	volatile unsigned char tclear;		/* Timer clear strobe address */
+#else
+	volatile unsigned char tclear;		/* Timer clear strobe address */
+	unsigned char _unused0[3];
+#endif
+	volatile u32 estatus;			/* Error status reg */
+	u32 _unused1[2];
+	struct sgi_ioc_timers timers;
+};
+
+extern struct sgi_int2_regs *sgi_i2regs;
+extern struct sgi_int3_regs *sgi_i3regs;
+extern struct sgi_ioc_ints *ioc_icontrol;
+extern struct sgi_ioc_timers *ioc_timers;
+extern volatile unsigned char *ioc_tclear;
+
+extern void sgint_init(void);
+extern void indy_timer_init(void);
+
+#endif /* _ASM_SGI_SGINT23_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sgialib.h linux/include/asm-mips64/sgialib.h
--- v2.3.47/linux/include/asm-mips64/sgialib.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sgialib.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,132 @@
+/* $Id: sgialib.h,v 1.4 2000/01/17 23:32:47 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SGI ARCS firmware interface library for the Linux kernel.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#ifndef _ASM_SGIALIB_H
+#define _ASM_SGIALIB_H
+
+#include <asm/sgiarcs.h>
+
+extern PSYSTEM_PARAMETER_BLOCK sgi_pblock;
+extern struct linux_romvec *romvec;
+extern int prom_argc;
+
+extern LONG *_prom_argv, *_prom_envp;
+
+/* A 32-bit ARC PROM pass arguments and environment as 32-bit pointer.
+   These macros take care of sign extension.  */
+#define prom_argv(index) ((char *) (long) _prom_argv[(index)])
+#define prom_argc(index) ((char *) (long) _prom_argc[(index)])
+
+extern int prom_flags;
+#define PROM_FLAG_ARCS  1
+
+/* Init the PROM library and it's internal data structures.  Called
+ * at boot time from head.S before start_kernel is invoked.
+ */
+extern int prom_init(int argc, char **argv, char **envp);
+
+/* Simple char-by-char console I/O. */
+extern void prom_putchar(char c);
+extern char prom_getchar(void);
+
+/* Generic printf() using ARCS console I/O. */
+extern void prom_printf(char *fmt, ...);
+
+/* Memory descriptor management. */
+#define PROM_MAX_PMEMBLOCKS    32
+struct prom_pmemblock {
+	LONG	base;		/* Within KSEG0 or XKPHYS. */
+	ULONG size;		/* In bytes. */
+        ULONG type;		/* free or prom memory */
+};
+
+/* Get next memory descriptor after CURR, returns first descriptor
+ * in chain is CURR is NULL.
+ */
+extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr);
+#define PROM_NULL_MDESC   ((struct linux_mdesc *) 0)
+
+/* Called by prom_init to setup the physical memory pmemblock
+ * array.
+ */
+extern void prom_meminit(void);
+extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem);
+
+/* Returns pointer to PROM physical memory block array. */
+extern struct prom_pmemblock *prom_getpblock_array(void);
+
+/* PROM device tree library routines. */
+#define PROM_NULL_COMPONENT ((pcomponent *) 0)
+
+/* Get sibling component of THIS. */
+extern pcomponent *ArcGetPeer(pcomponent *this);
+
+/* Get child component of THIS. */
+extern pcomponent *ArcGetChild(pcomponent *this);
+
+/* Get parent component of CHILD. */
+extern pcomponent *prom_getparent(pcomponent *child);
+
+/* Copy component opaque data of component THIS into BUFFER
+ * if component THIS has opaque data.  Returns success or
+ * failure status.
+ */
+extern long prom_getcdata(void *buffer, pcomponent *this);
+
+/* Other misc. component routines. */
+extern pcomponent *prom_childadd(pcomponent *this, pcomponent *tmp, void *data);
+extern long prom_delcomponent(pcomponent *this);
+extern pcomponent *prom_componentbypath(char *path);
+
+/* This is called at prom_init time to identify the
+ * ARC architecture we are running on
+ */
+extern void prom_identify_arch(void);
+
+/* Environemt variable routines. */
+extern PCHAR ArcGetEnvironmentVariable(PCHAR name);
+extern LONG SetEnvironmentVariable(PCHAR name, PCHAR value);
+
+/* ARCS command line acquisition and parsing. */
+extern char *prom_getcmdline(void);
+extern void prom_init_cmdline(void);
+
+/* Acquiring info about the current time, etc. */
+extern struct linux_tinfo *prom_gettinfo(void);
+extern unsigned long prom_getrtime(void);
+
+/* File operations. */
+extern long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt);
+extern long prom_open(char *name, enum linux_omode md, unsigned long *fd);
+extern long prom_close(unsigned long fd);
+extern LONG ArcRead(ULONG fd, PVOID buf, ULONG num, PULONG cnt);
+extern long prom_getrstatus(unsigned long fd);
+extern LONG ArcWrite(ULONG fd, PVOID buf, ULONG num, PULONG cnt);
+extern long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm);
+extern long prom_mount(char *name, enum linux_mountops op);
+extern long prom_getfinfo(unsigned long fd, struct linux_finfo *buf);
+extern long prom_setfinfo(unsigned long fd, unsigned long flags, unsigned long msk);
+
+/* Running stand-along programs. */
+extern long prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr);
+extern long prom_invoke(unsigned long pc, unsigned long sp, long argc, char **argv, char **envp);
+extern long prom_exec(char *name, long argc, char **argv, char **envp);
+
+/* Misc. routines. */
+extern void prom_halt(VOID) __attribute__((noreturn));
+extern void prom_powerdown(VOID) __attribute__((noreturn));
+extern void prom_restart(VOID) __attribute__((noreturn));
+extern VOID ArcReboot(VOID) __attribute__((noreturn));
+extern VOID ArcEnterInteractiveMode(void) __attribute__((noreturn));
+extern long prom_cfgsave(VOID);
+extern struct linux_sysid *prom_getsysid(VOID);
+extern VOID ArcFlushAllCaches(VOID);
+
+#endif /* _ASM_SGIALIB_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sgiarcs.h linux/include/asm-mips64/sgiarcs.h
--- v2.3.47/linux/include/asm-mips64/sgiarcs.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sgiarcs.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,544 @@
+/* $Id: sgiarcs.h,v 1.5 2000/01/17 23:32:47 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * ARC firmware interface defines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SGIARCS_H
+#define _ASM_SGIARCS_H
+
+#include <linux/config.h>
+#include <asm/arc/types.h>
+
+/* Various ARCS error codes. */
+#define PROM_ESUCCESS                   0x00
+#define PROM_E2BIG                      0x01
+#define PROM_EACCESS                    0x02
+#define PROM_EAGAIN                     0x03
+#define PROM_EBADF                      0x04
+#define PROM_EBUSY                      0x05
+#define PROM_EFAULT                     0x06
+#define PROM_EINVAL                     0x07
+#define PROM_EIO                        0x08
+#define PROM_EISDIR                     0x09
+#define PROM_EMFILE                     0x0a
+#define PROM_EMLINK                     0x0b
+#define PROM_ENAMETOOLONG               0x0c
+#define PROM_ENODEV                     0x0d
+#define PROM_ENOENT                     0x0e
+#define PROM_ENOEXEC                    0x0f
+#define PROM_ENOMEM                     0x10
+#define PROM_ENOSPC                     0x11
+#define PROM_ENOTDIR                    0x12
+#define PROM_ENOTTY                     0x13
+#define PROM_ENXIO                      0x14
+#define PROM_EROFS                      0x15
+/* SGI ARCS specific errno's. */
+#define PROM_EADDRNOTAVAIL              0x1f
+#define PROM_ETIMEDOUT                  0x20
+#define PROM_ECONNABORTED               0x21
+#define PROM_ENOCONNECT                 0x22
+
+/* Device classes, types, and identifiers for prom
+ * device inventory queries.
+ */
+enum linux_devclass {
+	system, processor, cache, adapter, controller, peripheral, memory
+};
+
+enum linux_devtypes {
+	/* Generic stuff. */
+	Arc, Cpu, Fpu,
+
+	/* Primary insn and data caches. */
+	picache, pdcache,
+
+	/* Secondary insn, data, and combined caches. */
+	sicache, sdcache, sccache,
+
+	memdev, eisa_adapter, tc_adapter, scsi_adapter, dti_adapter,
+	multifunc_adapter, dsk_controller, tp_controller, cdrom_controller,
+	worm_controller, serial_controller, net_controller, disp_controller,
+	parallel_controller, ptr_controller, kbd_controller, audio_controller,
+	misc_controller, disk_peripheral, flpy_peripheral, tp_peripheral,
+	modem_peripheral, monitor_peripheral, printer_peripheral,
+	ptr_peripheral, kbd_peripheral, term_peripheral, line_peripheral,
+	net_peripheral, misc_peripheral, anon
+};
+
+enum linux_identifier {
+	bogus, ronly, removable, consin, consout, input, output
+};
+
+/* A prom device tree component. */
+struct linux_component {
+	enum linux_devclass     class;	/* node class */
+	enum linux_devtypes     type;	/* node type */
+	enum linux_identifier   iflags;	/* node flags */
+	USHORT 			vers;	/* node version */
+	USHORT 			rev;	/* node revision */
+	ULONG 			key;	/* completely magic */
+	ULONG 			amask;	/* XXX affinity mask??? */
+	ULONG			cdsize;	/* size of configuration data */
+	ULONG			ilen;	/* length of string identifier */
+	_PULONG			iname;	/* string identifier */
+};
+typedef struct linux_component pcomponent;
+
+struct linux_sysid {
+	char vend[8], prod[8];
+};
+
+/* ARCS prom memory descriptors. */
+enum arcs_memtypes {
+	arcs_eblock,  /* exception block */
+	arcs_rvpage,  /* ARCS romvec page */
+	arcs_fcontig, /* Contiguous and free */
+	arcs_free,    /* Generic free memory */
+	arcs_bmem,    /* Borken memory, don't use */
+	arcs_prog,    /* A loaded program resides here */
+	arcs_atmp,    /* ARCS temporary storage area, wish Sparc OpenBoot told this */
+	arcs_aperm,   /* ARCS permanent storage... */
+};
+
+/* ARC has slightly different types than ARCS */
+enum arc_memtypes {
+	arc_eblock,  /* exception block */
+	arc_rvpage,  /* romvec page */
+	arc_free,    /* Generic free memory */
+	arc_bmem,    /* Borken memory, don't use */
+	arc_prog,    /* A loaded program resides here */
+	arc_atmp,    /* temporary storage area */
+	arc_aperm,   /* permanent storage */
+	arc_fcontig, /* Contiguous and free */    
+};
+
+union linux_memtypes {
+    enum arcs_memtypes arcs;
+    enum arc_memtypes arc;
+};
+
+struct linux_mdesc {
+	union linux_memtypes type;
+	ULONG base;
+	ULONG pages;
+};
+
+/* Time of day descriptor. */
+struct linux_tinfo {
+	unsigned short yr;
+	unsigned short mnth;
+	unsigned short day;
+	unsigned short hr;
+	unsigned short min;
+	unsigned short sec;
+	unsigned short msec;
+};
+
+/* ARCS virtual dirents. */
+struct linux_vdirent {
+	unsigned long namelen;
+	unsigned char attr;
+	char fname[32]; /* XXX imperical, should be a define */
+};
+
+/* Other stuff for files. */
+enum linux_omode {
+	rdonly, wronly, rdwr, wronly_creat, rdwr_creat,
+	wronly_ssede, rdwr_ssede, dirent, dirent_creat
+};
+
+enum linux_seekmode {
+	absolute, relative
+};
+
+enum linux_mountops {
+	media_load, media_unload
+};
+
+/* This prom has a bolixed design. */
+struct linux_bigint {
+#ifdef __MIPSEL__
+	unsigned long lo;
+	long hi;
+#else /* !(__MIPSEL__) */
+	long hi;
+	unsigned long lo;
+#endif
+};
+
+struct linux_finfo {
+	struct linux_bigint   begin;
+	struct linux_bigint   end;
+	struct linux_bigint   cur;
+	enum linux_devtypes dtype;
+	unsigned long         namelen;
+	unsigned char         attr;
+	char                  name[32]; /* XXX imperical, should be define */
+};
+
+/* This describes the vector containing fuction pointers to the ARC
+   firmware functions.  */
+struct linux_romvec {
+	LONG load;			/* Load an executable image. */
+	LONG invoke;			/* Invoke a standalong image. */
+	LONG exec;			/* Load and begin execution of a
+					   standalone image. */
+	LONG halt;			/* Halt the machine. */
+	LONG pdown;			/* Power down the machine. */
+	LONG restart;			/* XXX soft reset??? */
+	LONG reboot;			/* Reboot the machine. */
+	LONG imode;			/* Enter PROM interactive mode. */
+	LONG _unused1;			/* Was ReturnFromMain(). */
+
+	/* PROM device tree interface. */
+	LONG next_component;
+	LONG child_component;
+	LONG parent_component;
+	LONG component_data;
+	LONG child_add;
+	LONG comp_del;
+	LONG component_by_path;
+
+	/* Misc. stuff. */
+	LONG cfg_save;
+	LONG get_sysid;
+
+	/* Probing for memory. */
+	LONG	get_mdesc;
+	LONG	_unused2;		/* was Signal() */
+
+	LONG	get_tinfo;
+	LONG	get_rtime;
+
+	/* File type operations. */
+	LONG	get_vdirent;
+	LONG	open;
+	LONG	close;
+	LONG	read;
+	LONG	get_rstatus;
+	LONG	write;
+	LONG	seek;
+	LONG	mount;
+
+	/* Dealing with firmware environment variables. */
+	LONG	get_evar;
+	LONG	set_evar;
+
+	LONG	get_finfo;
+	LONG	set_finfo;
+
+	/* Miscellaneous. */
+	LONG	cache_flush;
+};
+
+/* The SGI ARCS parameter block is in a fixed location for standalone
+ * programs to access PROM facilities easily.
+ */
+typedef struct _SYSTEM_PARAMETER_BLOCK {
+	ULONG			magic;		/* magic cookie */
+#define PROMBLOCK_MAGIC      0x53435241
+
+	ULONG			len;		/* length of parm block */
+	USHORT			ver;		/* ARCS firmware version */
+	USHORT			rev;		/* ARCS firmware revision */
+	_PLONG			rs_block;	/* Restart block. */
+	_PLONG			dbg_block;	/* Debug block. */
+	_PLONG			gevect;		/* XXX General vector??? */
+	_PLONG			utlbvect;	/* XXX UTLB vector??? */
+	ULONG			rveclen;	/* Size of romvec struct. */
+	_PVOID			romvec;		/* Function interface. */
+	ULONG			pveclen;	/* Length of private vector. */
+	_PVOID			pvector;	/* Private vector. */
+	ULONG			adap_cnt;	/* Adapter count. */
+	ULONG			adap_typ0;	/* First adapter type. */
+	ULONG			adap_vcnt0;	/* Adapter 0 vector count. */
+	_PVOID			adap_vector;	/* Adapter 0 vector ptr. */
+	ULONG			adap_typ1;	/* Second adapter type. */
+	ULONG			adap_vcnt1;	/* Adapter 1 vector count. */
+	_PVOID			adap_vector1;	/* Adapter 1 vector ptr. */
+	/* More adapter vectors go here... */
+} SYSTEM_PARAMETER_BLOCK, *PSYSTEM_PARAMETER_BLOCK;
+
+#define PROMBLOCK ((PSYSTEM_PARAMETER_BLOCK) (int)0xA0001000)
+#define ROMVECTOR ((struct linux_romvec *) (long)(PROMBLOCK)->romvec)
+
+/* Cache layout parameter block. */
+union linux_cache_key {
+	struct param {
+#ifdef __MIPSEL__
+		unsigned short size;
+		unsigned char lsize;
+		unsigned char bsize;
+#else /* !(__MIPSEL__) */
+		unsigned char bsize;
+		unsigned char lsize;
+		unsigned short size;
+#endif
+	} info;
+	unsigned long allinfo;
+};
+
+/* Configuration data. */
+struct linux_cdata {
+	char *name;
+	int mlen;
+	enum linux_devtypes type;
+};
+
+/* Common SGI ARCS firmware file descriptors. */
+#define SGIPROM_STDIN     0
+#define SGIPROM_STDOUT    1
+
+/* Common SGI ARCS firmware file types. */
+#define SGIPROM_ROFILE    0x01  /* read-only file */
+#define SGIPROM_HFILE     0x02  /* hidden file */
+#define SGIPROM_SFILE     0x04  /* System file */
+#define SGIPROM_AFILE     0x08  /* Archive file */
+#define SGIPROM_DFILE     0x10  /* Directory file */
+#define SGIPROM_DELFILE   0x20  /* Deleted file */
+
+/* SGI ARCS boot record information. */
+struct sgi_partition {
+	unsigned char flag;
+#define SGIPART_UNUSED 0x00
+#define SGIPART_ACTIVE 0x80
+
+	unsigned char shead, ssect, scyl; /* unused */
+	unsigned char systype; /* OS type, Irix or NT */
+	unsigned char ehead, esect, ecyl; /* unused */
+	unsigned char rsect0, rsect1, rsect2, rsect3;
+	unsigned char tsect0, tsect1, tsect2, tsect3;
+};
+
+#define SGIBBLOCK_MAGIC   0xaa55
+#define SGIBBLOCK_MAXPART 0x0004
+
+struct sgi_bootblock {
+	unsigned char _unused[446];
+	struct sgi_partition partitions[SGIBBLOCK_MAXPART];
+	unsigned short magic;
+};
+
+/* BIOS parameter block. */
+struct sgi_bparm_block {
+	unsigned short bytes_sect;    /* bytes per sector */
+	unsigned char  sect_clust;    /* sectors per cluster */
+	unsigned short sect_resv;     /* reserved sectors */
+	unsigned char  nfats;         /* # of allocation tables */
+	unsigned short nroot_dirents; /* # of root directory entries */
+	unsigned short sect_volume;   /* sectors in volume */
+	unsigned char  media_type;    /* media descriptor */
+	unsigned short sect_fat;      /* sectors per allocation table */
+	unsigned short sect_track;    /* sectors per track */
+	unsigned short nheads;        /* # of heads */
+	unsigned short nhsects;       /* # of hidden sectors */
+};
+
+struct sgi_bsector {
+	unsigned char   jmpinfo[3];
+	unsigned char   manuf_name[8];
+	struct sgi_bparm_block info;
+};
+
+/* Debugging block used with SGI symmon symbolic debugger. */
+#define SMB_DEBUG_MAGIC   0xfeeddead
+struct linux_smonblock {
+	unsigned long   magic;
+	void            (*handler)(void);  /* Breakpoint routine. */
+	unsigned long   dtable_base;       /* Base addr of dbg table. */
+	int             (*printf)(const char *fmt, ...);
+	unsigned long   btable_base;       /* Breakpoint table. */
+	unsigned long   mpflushreqs;       /* SMP cache flush request list. */
+	unsigned long   ntab;              /* Name table. */
+	unsigned long   stab;              /* Symbol table. */
+	int             smax;              /* Max # of symbols. */
+};
+
+/*
+ * Macros for calling a 32-bit ARC implementation from 64-bit code
+ */
+
+#ifdef CONFIG_ARC32
+#define __arc_clobbers							\
+	"$2","$3","$4","$5","$6","$7","$8","$9","$10","$11",		\
+	"$12","$13","$14","$15","$16","$24","25","$31"
+
+#define ARC_CALL0(dest)							\
+({	long __res;							\
+	long __vec = (long) romvec->dest;				\
+	__asm__ __volatile__(						\
+	"dsubu\t$29, 32\n\t"						\
+	"jalr\t%1\n\t"							\
+	"daddu\t$29, 32\n\t"						\
+	"move\t%0, $2"							\
+	: "=r" (__res), "=r" (__vec)					\
+	: "1" (__vec)							\
+	: __arc_clobbers);						\
+	(unsigned long) __res;						\
+})
+
+#define ARC_CALL1(dest,a1)						\
+({	long __res;							\
+	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
+	long __vec = (long) romvec->dest;				\
+	__asm__ __volatile__(						\
+	"dsubu\t$29, 32\n\t"						\
+	"jalr\t%1\n\t"							\
+	"daddu\t$29, 32\n\t"						\
+	"move\t%0, $2"							\
+	: "=r" (__res), "=r" (__vec)					\
+	: "1" (__vec), "r" (__a1)					\
+	: __arc_clobbers);						\
+	(unsigned long) __res;						\
+})
+
+#define ARC_CALL2(dest,a1,a2)						\
+({	long __res;							\
+	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
+	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
+	long __vec = (long) romvec->dest;				\
+	__asm__ __volatile__(						\
+	"dsubu\t$29, 32\n\t"						\
+	"jalr\t%1\n\t"							\
+	"daddu\t$29, 32\n\t"						\
+	"move\t%0, $2"							\
+	: "=r" (__res), "=r" (__vec)					\
+	: "1" (__vec), "r" (__a1), "r" (__a2)				\
+	: __arc_clobbers);						\
+	__res;								\
+})
+
+#define ARC_CALL3(dest,a1,a2,a3)					\
+({	long __res;							\
+	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
+	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
+	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
+	long __vec = (long) romvec->dest;				\
+	__asm__ __volatile__(						\
+	"dsubu\t$29, 32\n\t"						\
+	"jalr\t%1\n\t"							\
+	"daddu\t$29, 32\n\t"						\
+	"move\t%0, $2"							\
+	: "=r" (__res), "=r" (__vec)					\
+	: "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3)		\
+	: __arc_clobbers);						\
+	__res;								\
+})
+
+#define ARC_CALL4(dest,a1,a2,a3,a4)					\
+({	long __res;							\
+	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
+	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
+	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
+	register signed int __a4 __asm__("$7") = (int) (long) (a4);	\
+	long __vec = (long) romvec->dest;				\
+	__asm__ __volatile__(						\
+	"dsubu\t$29, 32\n\t"						\
+	"jalr\t%1\n\t"							\
+	"daddu\t$29, 32\n\t"						\
+	"move\t%0, $2"							\
+	: "=r" (__res), "=r" (__vec)					\
+	: "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3), 		\
+	  "r" (__a4)							\
+	: __arc_clobbers);						\
+	__res;								\
+})
+
+#define ARC_CALL5(dest,a1,a2,a3,a4,a5)					\
+({	long __res;							\
+	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
+	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
+	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
+	register signed int __a4 __asm__("$7") = (int) (long) (a4);	\
+	register signed int __a5 = (a5);				\
+	long __vec = (long) romvec->dest;				\
+	__asm__ __volatile__(						\
+	"dsubu\t$29, 32\n\t"						\
+	"sw\t%6, 16($29)\n\t"						\
+	"jalr\t%1\n\t"							\
+	"daddu\t$29, 32\n\t"						\
+	"move\t%0, $2"							\
+	: "=r" (__res), "=r" (__vec)					\
+	: "1" (__vec),							\
+	  "r" (__a1), "r" (__a2), "r" (__a3), "r" (__a4),		\
+	  "r" (__a5)							\
+	: __arc_clobbers);						\
+	__res;								\
+})
+#endif /* CONFIG_ARC32 */
+
+#ifdef CONFIG_ARC64
+
+#define ARC_CALL0(dest)							\
+({	long __res;							\
+	long (*__vec)(void) = (void *) romvec->dest;			\
+									\
+	__res = __vec();						\
+	__res;								\
+})
+
+#define ARC_CALL1(dest,a1)						\
+({	long __res;							\
+	long __a1 = (long) (a1);					\
+	long (*__vec)(long) = (void *) romvec->dest;			\
+									\
+	__res = __vec(__a1);						\
+	__res;								\
+})
+
+#define ARC_CALL2(dest,a1,a2)						\
+({	long __res;							\
+	long __a1 = (long) (a1);					\
+	long __a2 = (long) (a2);					\
+	long (*__vec)(long, long) = (void *) romvec->dest;		\
+									\
+	__res = __vec(__a1, __a2);					\
+	__res;								\
+})
+
+#define ARC_CALL3(dest,a1,a2,a3)					\
+({	long __res;							\
+	long __a1 = (long) (a1);					\
+	long __a2 = (long) (a2);					\
+	long __a3 = (long) (a3);					\
+	long (*__vec)(long, long, long)	= (void *) romvec->dest;	\
+									\
+	__res = __vec(__a1, __a2, __a3);				\
+	__res;								\
+})
+
+#define ARC_CALL4(dest,a1,a2,a3,a4)					\
+({	long __res;							\
+	long __a1 = (long) (a1);					\
+	long __a2 = (long) (a2);					\
+	long __a3 = (long) (a3);					\
+	long __a4 = (long) (a4);					\
+	long (*__vec)(long, long, long, long) = (void *) romvec->dest;	\
+									\
+	__res = __vec(__a1, __a2, __a3, __a4);				\
+	__res;								\
+})
+
+#define ARC_CALL5(dest,a1,a2,a3,a4,a5)					\
+({	long __res;							\
+	long __a1 = (long) (a1);					\
+	long __a2 = (long) (a2);					\
+	long __a3 = (long) (a3);					\
+	long __a4 = (long) (a4);					\
+	long __a5 = (long) (a5);					\
+	long (*__vec)(long, long, long, long, long);			\
+	__vec = (void *) romvec->dest;					\
+									\
+	__res = __vec(__a1, __a2, __a3, __a4, __a5);			\
+	__res;								\
+})
+#endif /* CONFIG_ARC64 */
+
+#endif /* _ASM_SGIARCS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sgidefs.h linux/include/asm-mips64/sgidefs.h
--- v2.3.47/linux/include/asm-mips64/sgidefs.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sgidefs.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,31 @@
+/* $Id: sgidefs.h,v 1.2 1999/08/20 21:59:08 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * Definitions commonly used in SGI style code.
+ */
+#ifndef _ASM_SGIDEFS_H
+#define _ASM_SGIDEFS_H
+
+/*
+ * Definitions for the ISA level
+ */
+#define _MIPS_ISA_MIPS1 1
+#define _MIPS_ISA_MIPS2 2
+#define _MIPS_ISA_MIPS3 3
+#define _MIPS_ISA_MIPS4 4
+#define _MIPS_ISA_MIPS5 5
+
+/*
+ * Subprogram calling convention
+ */
+#define _MIPS_SIM_ABI32		1
+#define _MIPS_SIM_NABI32	2
+#define _MIPS_SIM_ABI64		3
+
+#endif /* _ASM_SGIDEFS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/shmbuf.h linux/include/asm-mips64/shmbuf.h
--- v2.3.47/linux/include/asm-mips64/shmbuf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/shmbuf.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,38 @@
+#ifndef _ASM_SHMBUF_H
+#define _ASM_SHMBUF_H
+
+/* 
+ * The shmid64_ds structure for the MIPS architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 2 miscellaneous 64-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	__kernel_time_t		shm_ctime;	/* last change time */
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _ASM_SHMBUF_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/shmiq.h linux/include/asm-mips64/shmiq.h
--- v2.3.47/linux/include/asm-mips64/shmiq.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/shmiq.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,234 @@
+/* $Id: shmiq.h,v 1.1 1999/08/19 22:56:34 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Please note that the comments on this file may be out of date
+ * and that they represent what I have figured about the shmiq device
+ * so far in IRIX.
+ *
+ * This also contains some streams and idev bits.
+ *
+ * They may contain errors, please, refer to the source code of the Linux  
+ * kernel for a definitive answer on what we have implemented
+ *
+ * Miguel.
+ */
+#ifndef _ASM_SHMIQ_H
+#define _ASM_SHMIQ_H
+
+/* STREAMs ioctls */
+#define STRIOC    ('S' << 8)
+#define I_STR     (STRIOC | 010)
+#define I_PUSH    (STRIOC | 02)
+#define I_LINK    (STRIOC | 014)
+#define I_UNLINK  (STRIOC | 015)
+
+/* Data structure passed on I_STR ioctls */
+struct strioctl {
+        int     ic_cmd;                 /* streams ioctl command */
+        int     ic_timout;              /* timeout */
+        int     ic_len;                 /* lenght of data */
+        void    *ic_dp;                 /* data */
+};
+
+/*
+ * For mapping the shared memory input queue, you have to:
+ *
+ * 1. Map /dev/zero for the number of bytes you want to use
+ *    for your shared memory input queue plus the size of the
+ *    sharedMemoryInputQueue structure + 4 (I still have not figured
+ *    what this one is for
+ *
+ * 2. Open /dev/shmiq
+ *
+ * 3. Open /dev/qcntlN N is [0..Nshmiqs]
+ *
+ * 4. Fill a shmiqreq structure.  user_vaddr should point to the return
+ *    address from the /dev/zero mmap.  Arg is the number of shmqevents
+ *    that fit into the /dev/zero region (remember that at the beginning there
+ *    is a sharedMemoryInputQueue header).
+ *
+ * 5. Issue the ioctl (qcntlfd, QIOCATTACH, &your_shmiqreq);
+ */
+
+struct shmiqreq {
+	char *user_vaddr;
+	int  arg;
+};
+
+/* map the shmiq into the process address space */
+#define QIOCATTACH       _IOW('Q',1,struct shmiqreq)
+
+/* remove mappings */
+#define QIOCDETACH       _IO('Q',2)
+
+/*
+ * A shared memory input queue event.
+ */
+struct shmqdata {
+	unsigned char device;          /* device major */
+        unsigned char which;           /* device minor */
+        unsigned char type;            /* event type */
+        unsigned char flags;           /* little event data */
+        union {
+            int pos;                   /* big event data */
+            short ptraxis [2];         /* event data for PTR events */
+        } un;
+};
+
+/* indetifies the shmiq and the device */
+struct shmiqlinkid {
+        short int devminor;
+        short int index;
+};
+
+struct shmqevent {
+	union {
+                int time;
+                struct shmiqlinkid id;
+        } un ;
+        struct shmqdata data ;
+};
+
+/*
+ * sharedMemoryInputQueue: this describes the shared memory input queue.
+ *
+ * head   is the user index into the events, user can modify this one.
+ * tail   is managed by the kernel.
+ * flags  is one of SHMIQ_OVERFLOW or SHMIQ_CORRUPTED
+ *        if OVERFLOW is set it seems ioctl QUIOCSERVICED should be called 
+ *        to notify the kernel.
+ * events where the kernel sticks the events.
+ */
+struct sharedMemoryInputQueue {
+	volatile int head;	     /* user's index into events */
+        volatile int tail;	     /* kernel's index into events */
+        volatile unsigned int flags; /* place for out-of-band data */
+#define SHMIQ_OVERFLOW  1
+#define SHMIQ_CORRUPTED 2
+        struct shmqevent events[1];  /* input event buffer */
+};
+
+/* have to figure this one out */
+#define QIOCGETINDX      _IOWR('Q', 8, int)
+
+
+/* acknowledge shmiq overflow */
+#define QIOCSERVICED     _IO('Q', 3)
+
+/* Double indirect I_STR ioctl, yeah, fun fun fun */
+
+struct muxioctl {
+        int index;		/* lower stream index */
+        int realcmd;		/* the actual command for the subdevice */
+};
+/* Double indirect ioctl */
+#define QIOCIISTR        _IOW('Q', 7, struct muxioctl)
+
+/* Cursor ioclts: */
+
+/* set cursor tracking mode */
+#define QIOCURSTRK      _IOW('Q', 4, int)
+
+/* set cursor filter box */
+#define QIOCURSIGN      _IOW('Q', 5, int [4])
+
+/* set cursor axes */
+struct shmiqsetcurs {
+        short index;
+        short axes;
+};
+
+#define QIOCSETCURS     _IOWR('Q',  9, struct shmiqsetcurs)
+
+/* set cursor position */
+struct shmiqsetcpos {
+        short   x;
+        short   y;
+};
+#define QIOCSETCPOS     _IOWR('Q', 10, struct shmiqsetcpos)
+
+/* get time since last event */
+#define QIOCGETITIME    _IOR('Q', 11, time_t)
+
+/* set curent screen */
+#define QIOCSETSCRN     _IOW('Q',6,int)
+
+
+/* -------------------- iDev stuff -------------------- */
+
+#define IDEV_MAX_NAME_LEN 15
+#define IDEV_MAX_TYPE_LEN 15
+
+typedef struct {
+        char            devName[IDEV_MAX_NAME_LEN+1];
+        char            devType[IDEV_MAX_TYPE_LEN+1];
+        unsigned short  nButtons;
+        unsigned short  nValuators;
+        unsigned short  nLEDs;
+        unsigned short  nStrDpys;
+        unsigned short  nIntDpys;
+        unsigned char   nBells;
+        unsigned char   flags;
+#define IDEV_HAS_KEYMAP		0x01
+#define IDEV_HAS_PROXIMITY 	0x02
+#define IDEV_HAS_PCKBD 		0x04
+} idevDesc;
+
+typedef struct {
+	char *nothing_for_now;
+} idevInfo;
+
+#define IDEV_KEYMAP_NAME_LEN 15
+
+typedef struct {
+        char name[IDEV_KEYMAP_NAME_LEN+1];
+} idevKeymapDesc;
+
+/* The valuator definition */
+typedef struct {
+        unsigned        hwMinRes;
+        unsigned        hwMaxRes;
+        int             hwMinVal;
+        int             hwMaxVal;
+	
+        unsigned char   possibleModes;
+#define IDEV_ABSOLUTE           0x0
+#define IDEV_RELATIVE           0x1
+#define IDEV_EITHER             0x2
+	
+        unsigned char   mode;	/* One of: IDEV_ABSOLUTE, IDEV_RELATIVE */
+	
+        unsigned short  resolution;
+        int             minVal;
+        int             maxVal;
+} idevValuatorDesc;
+
+/* This is used to query a specific valuator with the IDEVGETVALUATORDESC ioctl */
+typedef struct {
+        short                   valNum;
+        unsigned short          flags;
+        idevValuatorDesc        desc;
+} idevGetSetValDesc;
+
+#define IDEVGETDEVICEDESC	_IOWR('i', 0,  idevDesc)
+#define IDEVGETVALUATORDESC     _IOWR('i', 1,  idevGetSetValDesc)
+#define IDEVGETKEYMAPDESC	_IOWR('i', 2,  idevKeymapDesc)
+#define IDEVINITDEVICE		_IOW ('i', 51, unsigned int)
+
+
+#ifdef __KERNEL__
+
+/* These are only interpreted by SHMIQ-attacheable devices and are internal
+ * to the kernel
+ */
+#define SHMIQ_OFF        _IO('Q',1)
+#define SHMIQ_ON         _IO('Q',2)
+
+void shmiq_push_event (struct shmqevent *e);
+int get_sioc (struct strioctl *sioc, unsigned long arg);
+#endif
+
+#endif /* _ASM_SHMIQ_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/shmparam.h linux/include/asm-mips64/shmparam.h
--- v2.3.47/linux/include/asm-mips64/shmparam.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/shmparam.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,12 @@
+/* $Id: shmparam.h,v 1.2 2000/01/29 01:42:28 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_SHMPARAM_H
+#define _ASM_SHMPARAM_H
+
+#define	SHMLBA 0x40000			/* attach addr a multiple of this */
+
+#endif /* _ASM_SHMPARAM_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sigcontext.h linux/include/asm-mips64/sigcontext.h
--- v2.3.47/linux/include/asm-mips64/sigcontext.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sigcontext.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,32 @@
+/* $Id: sigcontext.h,v 1.2 1999/09/28 22:27:19 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SIGCONTEXT_H
+#define _ASM_SIGCONTEXT_H
+
+/*
+ * Keep this struct definition in sync with the sigcontext fragment
+ * in arch/mips/tools/offset.c
+ */
+struct sigcontext {
+	unsigned long long sc_regs[32];
+	unsigned long long sc_fpregs[32];
+	unsigned long long sc_mdhi;
+	unsigned long long sc_mdlo;
+	unsigned long long sc_pc;
+	unsigned int       sc_status;
+	unsigned int       sc_ownedfp;
+	unsigned int       sc_fpc_csr;
+	unsigned int       sc_fpc_eir;
+
+	unsigned int       sc_cause;
+	unsigned int       sc_badvaddr;
+};
+
+#endif /* _ASM_SIGCONTEXT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/siginfo.h linux/include/asm-mips64/siginfo.h
--- v2.3.47/linux/include/asm-mips64/siginfo.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/siginfo.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,219 @@
+/* $Id: siginfo.h,v 1.3 2000/02/18 00:24:49 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SIGINFO_H
+#define _ASM_SIGINFO_H
+
+#include <linux/types.h>
+
+/* This structure matches IRIX 32/n32 ABIs for binary compatibility. */
+
+typedef union sigval {
+	int sival_int;
+	void *sival_ptr;
+} sigval_t;
+
+/* This structure matches IRIX 32/n32 ABIs for binary compatibility but
+   has Linux extensions.  */
+
+#define SI_MAX_SIZE	128
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo {
+	int si_signo;
+	int si_code;
+	int si_errno;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+		} _kill;
+
+		/* SIGCHLD */
+		struct {
+			pid_t _pid;		/* which child */
+			uid_t _uid;		/* sender's uid */
+			clock_t _utime;
+			int _status;		/* exit code */
+			clock_t _stime;
+		} _sigchld;
+
+		/* IRIX SIGCHLD */
+		struct {
+			pid_t _pid;		/* which child */
+			clock_t _utime;
+			int _status;		/* exit code */
+			clock_t _stime;
+		} _irix_sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void *_addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL, SIGXFSZ (To do ...)  */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+			sigval_t _sigval;
+		} _rt;
+
+	} _sifields;
+} siginfo_t;
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#define si_uid		_sifields._kill._uid
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+
+/*
+ * si_code values
+ * Again these have been choosen to be IRIX compatible.
+ */
+#define SI_USER		0	/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80	/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1	/* sent by sigqueue */
+#define SI_ASYNCIO	-2	/* sent by AIO completion */
+#define SI_TIMER	-3	/* sent by timer expiration */
+#define SI_MESGQ	-4	/* sent by real time mesq state change */
+#define SI_SIGIO	-5	/* sent by queued SIGIO */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	1	/* illegal opcode */
+#define ILL_ILLOPN	2	/* illegal operand */
+#define ILL_ILLADR	3	/* illegal addressing mode */
+#define ILL_ILLTRP	4	/* illegal trap */
+#define ILL_PRVOPC	5	/* privileged opcode */
+#define ILL_PRVREG	6	/* privileged register */
+#define ILL_COPROC	7	/* coprocessor error */
+#define ILL_BADSTK	8	/* internal stack error */
+#define NSIGILL		8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	1	/* integer divide by zero */
+#define FPE_INTOVF	2	/* integer overflow */
+#define FPE_FLTDIV	3	/* floating point divide by zero */
+#define FPE_FLTOVF	4	/* floating point overflow */
+#define FPE_FLTUND	5	/* floating point underflow */
+#define FPE_FLTRES	6	/* floating point inexact result */
+#define FPE_FLTINV	7	/* floating point invalid operation */
+#define FPE_FLTSUB	8	/* subscript out of range */
+#define NSIGFPE		8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	1	/* address not mapped to object */
+#define SEGV_ACCERR	2	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	1	/* invalid address alignment */
+#define BUS_ADRERR	2	/* non-existant physical address */
+#define BUS_OBJERR	3	/* object specific hardware error */
+#define NSIGBUS		3
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT	1	/* process breakpoint */
+#define TRAP_TRACE	2	/* process trace trap */
+#define NSIGTRAP	2
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	1	/* child has exited */
+#define CLD_KILLED	2	/* child was killed */
+#define CLD_DUMPED	3	/* child terminated abnormally */
+#define CLD_TRAPPED	4	/* traced child has trapped */
+#define CLD_STOPPED	5	/* child has stopped */
+#define CLD_CONTINUED	6	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		1	/* data input available */
+#define POLL_OUT	2	/* output buffers available */
+#define POLL_MSG	3	/* input message available */
+#define POLL_ERR	4	/* I/O error */
+#define POLL_PRI	5	/* high priority input available */
+#define POLL_HUP	6	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_NONE	128	/* other notification: meaningless */
+#define SIGEV_SIGNAL	129	/* notify via signal */
+#define SIGEV_CALLBACK	130	/* ??? */
+#define SIGEV_THREAD	131	/* deliver via thread creation */
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 6)
+
+/* XXX This one isn't yet IRIX / ABI compatible.  */
+typedef struct sigevent {
+	int sigev_notify;
+	sigval_t sigev_value;
+	int sigev_signo;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+
+#endif /* _ASM_SIGINFO_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/signal.h linux/include/asm-mips64/signal.h
--- v2.3.47/linux/include/asm-mips64/signal.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/signal.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,173 @@
+/* $Id: signal.h,v 1.2 1999/09/28 22:27:19 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 - 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SIGNAL_H
+#define _ASM_SIGNAL_H
+
+#include <linux/types.h>
+
+#define _NSIG		128
+#define _NSIG_BPW	64
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef struct {
+	long sig[_NSIG_WORDS];
+} sigset_t;
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+#define SIGHUP		 1	/* Hangup (POSIX).  */
+#define SIGINT		 2	/* Interrupt (ANSI).  */
+#define SIGQUIT		 3	/* Quit (POSIX).  */
+#define SIGILL		 4	/* Illegal instruction (ANSI).  */
+#define SIGTRAP		 5	/* Trace trap (POSIX).  */
+#define SIGIOT		 6	/* IOT trap (4.2 BSD).  */
+#define SIGABRT		 SIGIOT	/* Abort (ANSI).  */
+#define SIGEMT		 7
+#define SIGFPE		 8	/* Floating-point exception (ANSI).  */
+#define SIGKILL		 9	/* Kill, unblockable (POSIX).  */
+#define SIGBUS		10	/* BUS error (4.2 BSD).  */
+#define SIGSEGV		11	/* Segmentation violation (ANSI).  */
+#define SIGSYS		12
+#define SIGPIPE		13	/* Broken pipe (POSIX).  */
+#define SIGALRM		14	/* Alarm clock (POSIX).  */
+#define SIGTERM		15	/* Termination (ANSI).  */
+#define SIGUSR1		16	/* User-defined signal 1 (POSIX).  */
+#define SIGUSR2		17	/* User-defined signal 2 (POSIX).  */
+#define SIGCHLD		18	/* Child status has changed (POSIX).  */
+#define SIGCLD		SIGCHLD	/* Same as SIGCHLD (System V).  */
+#define SIGPWR		19	/* Power failure restart (System V).  */
+#define SIGWINCH	20	/* Window size change (4.3 BSD, Sun).  */
+#define SIGURG		21	/* Urgent condition on socket (4.2 BSD).  */
+#define SIGIO		22	/* I/O now possible (4.2 BSD).  */
+#define SIGPOLL		SIGIO	/* Pollable event occurred (System V).  */
+#define SIGSTOP		23	/* Stop, unblockable (POSIX).  */
+#define SIGTSTP		24	/* Keyboard stop (POSIX).  */
+#define SIGCONT		25	/* Continue (POSIX).  */
+#define SIGTTIN		26	/* Background read from tty (POSIX).  */
+#define SIGTTOU		27	/* Background write to tty (POSIX).  */
+#define SIGVTALRM	28	/* Virtual alarm clock (4.2 BSD).  */
+#define SIGPROF		29	/* Profiling alarm clock (4.2 BSD).  */
+#define SIGXCPU		30	/* CPU limit exceeded (4.2 BSD).  */
+#define SIGXFSZ		31	/* File size limit exceeded (4.2 BSD).  */
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * 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_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_ONSTACK	0x08000000
+#define SA_RESETHAND	0x80000000
+#define SA_RESTART	0x10000000
+#define SA_SIGINFO	0x00000008
+#define SA_NODEFER	0x40000000
+#define SA_NOCLDWAIT	0x00010000	/* Not supported yet */
+#define SA_NOCLDSTOP	0x00000001
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000	/* dummy -- ignored */
+
+#define SA_RESTORER	0x04000000
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK     1
+#define SS_DISABLE     2
+
+#define MINSIGSTKSZ    2048
+#define SIGSTKSZ       8192
+
+#ifdef __KERNEL__
+
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x02000000
+
+#endif /* __KERNEL__ */
+
+#define SIG_BLOCK	1	/* for blocking signals */
+#define SIG_UNBLOCK	2	/* for unblocking signals */
+#define SIG_SETMASK	3	/* for setting the signal mask */
+#define SIG_SETMASK32	256	/* Goodie from SGI for BSD compatibility:
+				   set only the low 32 bit of the sigset.  */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+/* Fake signal functions */
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+struct sigaction {
+	unsigned int	sa_flags;
+	__sighandler_t	sa_handler;
+	sigset_t	sa_mask;
+	void		(*sa_restorer)(void);
+	int		sa_resv[1];	/* reserved */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+
+/* IRIX compatible stack_t  */
+typedef struct sigaltstack {
+	void *ss_sp;
+	size_t ss_size;
+	int ss_flags;
+} stack_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+
+/*
+ * The following break codes are or were in use for specific purposes in
+ * other MIPS operating systems.  Linux/MIPS doesn't use all of them.  The
+ * unused ones are here as placeholders; we might encounter them in
+ * non-Linux/MIPS object files or make use of them in the future.
+ */
+#define BRK_USERBP	0	/* User bp (used by debuggers) */
+#define BRK_KERNELBP	1	/* Break in the kernel */
+#define BRK_ABORT	2	/* Sometimes used by abort(3) to SIGIOT */
+#define BRK_BD_TAKEN	3	/* For bd slot emulation - not implemented */
+#define BRK_BD_NOTTAKEN	4	/* For bd slot emulation - not implemented */
+#define BRK_SSTEPBP	5	/* User bp (used by debuggers) */
+#define BRK_OVERFLOW	6	/* Overflow check */
+#define BRK_DIVZERO	7	/* Divide by zero check */
+#define BRK_RANGE	8	/* Range error check */
+#define BRK_STACKOVERFLOW 9	/* For Ada stackchecking */
+#define BRK_NORLD	10	/* No rld found - not used by Linux/MIPS */
+#define _BRK_THREADBP	11	/* For threads, user bp (used by debuggers) */
+#define BRK_MULOVF	1023	/* Multiply overflow */
+#endif /* defined (__KERNEL__) || defined (__USE_MISC) */
+
+#endif /* !defined (_ASM_SIGNAL_H) */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/addrs.h linux/include/asm-mips64/sn/addrs.h
--- v2.3.47/linux/include/asm-mips64/sn/addrs.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/addrs.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,428 @@
+/* $Id: addrs.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/addrs.h>.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SN_ADDRS_H
+#define _ASM_SN_ADDRS_H
+
+#if _LANGUAGE_C
+#include <linux/types.h>
+#endif /* _LANGUAGE_C */
+
+#include <asm/addrspace.h>
+#include <asm/reg.h>
+#include <asm/sn/kldir.h>
+
+#if _LANGUAGE_C
+
+#define PS_UINT_CAST		(unsigned long)
+#define UINT64_CAST		(unsigned long)
+#define HUBREG_CAST		(volatile hubreg_t *)
+
+#elif _LANGUAGE_ASSEMBLY
+
+#define PS_UINT_CAST
+#define UINT64_CAST
+#define HUBREG_CAST
+
+#endif
+
+
+#define NASID_GET_META(_n)	((_n) >> NASID_LOCAL_BITS)
+#define NASID_GET_LOCAL(_n)	((_n) & 0xf)
+#define NASID_MAKE(_m, _l)	(((_m) << NASID_LOCAL_BITS) | (_l))
+
+#define NODE_ADDRSPACE_MASK	(NODE_ADDRSPACE_SIZE - 1)
+#define TO_NODE_ADDRSPACE(_pa)	(UINT64_CAST (_pa) & NODE_ADDRSPACE_MASK)
+
+#define CHANGE_ADDR_NASID(_pa, _nasid)	\
+		((UINT64_CAST (_pa) & ~NASID_MASK) | \
+		 (UINT64_CAST(_nasid) <<  NASID_SHFT))
+
+
+/*
+ * The following macros are used to index to the beginning of a specific
+ * node's address space.
+ */
+
+#define NODE_OFFSET(_n)		(UINT64_CAST (_n) << NODE_SIZE_BITS)
+
+#define NODE_CAC_BASE(_n)	(CAC_BASE   + NODE_OFFSET(_n))
+#define NODE_HSPEC_BASE(_n)	(HSPEC_BASE + NODE_OFFSET(_n))
+#define NODE_IO_BASE(_n)	(IO_BASE    + NODE_OFFSET(_n))
+#define NODE_MSPEC_BASE(_n)	(MSPEC_BASE + NODE_OFFSET(_n))
+#define NODE_UNCAC_BASE(_n)	(UNCAC_BASE + NODE_OFFSET(_n))
+
+#define TO_NODE(_n, _x)		(NODE_OFFSET(_n)     | ((_x)		   ))
+#define TO_NODE_CAC(_n, _x)	(NODE_CAC_BASE(_n)   | ((_x) & TO_PHYS_MASK))
+#define TO_NODE_UNCAC(_n, _x)	(NODE_UNCAC_BASE(_n) | ((_x) & TO_PHYS_MASK))
+#define TO_NODE_MSPEC(_n, _x)	(NODE_MSPEC_BASE(_n) | ((_x) & TO_PHYS_MASK))
+#define TO_NODE_HSPEC(_n, _x)	(NODE_HSPEC_BASE(_n) | ((_x) & TO_PHYS_MASK))
+
+
+#define RAW_NODE_SWIN_BASE(nasid, widget)				\
+	(NODE_IO_BASE(nasid) + (UINT64_CAST (widget) << SWIN_SIZE_BITS))
+
+#define WIDGETID_GET(addr)	((unsigned char)((addr >> SWIN_SIZE_BITS) & 0xff))
+
+/*
+ * The following definitions pertain to the IO special address
+ * space.  They define the location of the big and little windows
+ * of any given node.
+ */
+
+#define SWIN_SIZE_BITS		24
+#define SWIN_SIZE		(UINT64_CAST 1 << 24)
+#define	SWIN_SIZEMASK		(SWIN_SIZE - 1)
+#define	SWIN_WIDGET_MASK	0xF
+
+/*
+ * Convert smallwindow address to xtalk address.
+ *
+ * 'addr' can be physical or virtual address, but will be converted
+ * to Xtalk address in the range 0 -> SWINZ_SIZEMASK
+ */
+#define	SWIN_WIDGETADDR(addr)	((addr) & SWIN_SIZEMASK)
+#define	SWIN_WIDGETNUM(addr)	(((addr)  >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK)
+/*
+ * Verify if addr belongs to small window address on node with "nasid"
+ *
+ *
+ * NOTE: "addr" is expected to be XKPHYS address, and NOT physical
+ * address
+ *
+ *
+ */
+#define	NODE_SWIN_ADDR(nasid, addr)	\
+		(((addr) >= NODE_SWIN_BASE(nasid, 0))  && \
+		 ((addr) <  (NODE_SWIN_BASE(nasid, HUB_NUM_WIDGET) + SWIN_SIZE)\
+		 ))
+
+/*
+ * The following define the major position-independent aliases used
+ * in SN.
+ *	UALIAS -- 256MB in size, reads in the UALIAS result in
+ *			uncached references to the memory of the reader's node.
+ *	CPU_UALIAS -- 128kb in size, the bottom part of UALIAS is flipped
+ *			depending on which CPU does the access to provide
+ *			all CPUs with unique uncached memory at low addresses.
+ *	LBOOT  -- 256MB in size, reads in the LBOOT area result in
+ *			uncached references to the local hub's boot prom and
+ *			other directory-bus connected devices.
+ *	IALIAS -- 8MB in size, reads in the IALIAS result in uncached
+ *			references to the local hub's registers.
+ */
+
+#define UALIAS_BASE		HSPEC_BASE
+#define UALIAS_SIZE		0x10000000	/* 256 Megabytes */
+#define UALIAS_LIMIT		(UALIAS_BASE + UALIAS_SIZE)
+
+/*
+ * The bottom of ualias space is flipped depending on whether you're
+ * processor 0 or 1 within a node.
+ */
+#define UALIAS_FLIP_BASE	UALIAS_BASE
+#define UALIAS_FLIP_SIZE	0x20000
+#define UALIAS_FLIP_BIT		0x10000
+#define UALIAS_FLIP_ADDR(_x)	(cputoslice(getcpuid()) ? \
+				 (_x) ^ UALIAS_FLIP_BIT : (_x))
+
+#define LBOOT_BASE		(HSPEC_BASE + 0x10000000)
+#define LBOOT_SIZE		0x10000000
+#define LBOOT_LIMIT		(LBOOT_BASE + LBOOT_SIZE)
+
+#define	HUB_REGISTER_WIDGET	1
+#define IALIAS_BASE		NODE_SWIN_BASE(0, HUB_REGISTER_WIDGET)
+#define IALIAS_SIZE		0x800000	/* 8 Megabytes */
+#define IS_IALIAS(_a)		(((_a) >= IALIAS_BASE) &&		\
+				 ((_a) < (IALIAS_BASE + IALIAS_SIZE)))
+
+/*
+ * Macro for referring to Hub's RBOOT space
+ */
+#define RBOOT_SIZE		0x10000000	/* 256 Megabytes */
+#define NODE_RBOOT_BASE(_n)	(NODE_HSPEC_BASE(_n) + 0x30000000)
+#define NODE_RBOOT_LIMIT(_n)	(NODE_RBOOT_BASE(_n) + RBOOT_SIZE)
+
+/*
+ * Macros for referring the Hub's back door space
+ *
+ *   These macros correctly process addresses in any node's space.
+ *   WARNING: They won't work in assembler.
+ *
+ *   BDDIR_ENTRY_LO returns the address of the low double-word of the dir
+ *                  entry corresponding to a physical (Cac or Uncac) address.
+ *   BDDIR_ENTRY_HI returns the address of the high double-word of the entry.
+ *   BDPRT_ENTRY    returns the address of the double-word protection entry
+ *                  corresponding to the page containing the physical address.
+ *   BDECC_ENTRY    returns the address of the ECC byte corresponding to a
+ *                  double-word at a specified physical address.
+ */
+#define NODE_BDOOR_BASE(_n)	(NODE_HSPEC_BASE(_n) + (NODE_ADDRSPACE_SIZE/2))
+
+#define NODE_BDECC_BASE(_n)	(NODE_BDOOR_BASE(_n))
+#define NODE_BDDIR_BASE(_n)	(NODE_BDOOR_BASE(_n) + (NODE_ADDRSPACE_SIZE/4))
+
+#define BDDIR_ENTRY_LO(_pa)	((HSPEC_BASE +				      \
+				  NODE_ADDRSPACE_SIZE * 3 / 4 +		      \
+				  0x200)				    | \
+				 UINT64_CAST (_pa)	 & NASID_MASK	    | \
+				 UINT64_CAST (_pa) >> 2 & BDDIR_UPPER_MASK  | \
+				 UINT64_CAST (_pa) >> 3 & 0x1f << 4)
+
+#define BDDIR_ENTRY_HI(_pa)	((HSPEC_BASE +				      \
+				  NODE_ADDRSPACE_SIZE * 3 / 4 +		      \
+				  0x208)				    | \
+				 UINT64_CAST (_pa)	 & NASID_MASK	    | \
+				 UINT64_CAST (_pa) >> 2 & BDDIR_UPPER_MASK  | \
+				 UINT64_CAST (_pa) >> 3 & 0x1f << 4)
+
+#define BDPRT_ENTRY(_pa, _rgn)	((HSPEC_BASE +				      \
+				  NODE_ADDRSPACE_SIZE * 3 / 4)		    | \
+				 UINT64_CAST (_pa)	 & NASID_MASK	    | \
+				 UINT64_CAST (_pa) >> 2 & BDDIR_UPPER_MASK  | \
+				 (_rgn) << 3)
+
+#define BDECC_ENTRY(_pa)	((HSPEC_BASE +				      \
+				  NODE_ADDRSPACE_SIZE / 2)		    | \
+				 UINT64_CAST (_pa)	 & NASID_MASK	    | \
+				 UINT64_CAST (_pa) >> 2 & BDECC_UPPER_MASK  | \
+				 UINT64_CAST (_pa) >> 3 & 3)
+
+/*
+ * Macro to convert a back door directory or protection address into the
+ *   raw physical address of the associated cache line or protection page.
+ */
+#define BDADDR_IS_DIR(_ba)	((UINT64_CAST  (_ba) & 0x200) != 0)
+#define BDADDR_IS_PRT(_ba)	((UINT64_CAST  (_ba) & 0x200) == 0)
+
+#define BDDIR_TO_MEM(_ba)	(UINT64_CAST  (_ba) & NASID_MASK            | \
+				 (UINT64_CAST (_ba) & BDDIR_UPPER_MASK)<<2  | \
+				 (UINT64_CAST (_ba) & 0x1f << 4) << 3)
+
+#define BDPRT_TO_MEM(_ba) 	(UINT64_CAST  (_ba) & NASID_MASK	    | \
+				 (UINT64_CAST (_ba) & BDDIR_UPPER_MASK)<<2)
+
+#define BDECC_TO_MEM(_ba)	(UINT64_CAST  (_ba) & NASID_MASK	    | \
+				 (UINT64_CAST (_ba) & BDECC_UPPER_MASK)<<2  | \
+				 (UINT64_CAST (_ba) & 3) << 3)
+
+
+/*
+ * The following macros produce the correct base virtual address for
+ * the hub registers.  The LOCAL_HUB_* macros produce the appropriate
+ * address for the local registers.  The REMOTE_HUB_* macro produce
+ * the address for the specified hub's registers.  The intent is
+ * that the appropriate PI, MD, NI, or II register would be substituted
+ * for _x.
+ */
+
+#ifdef _STANDALONE
+
+/* DO NOT USE THESE DIRECTLY IN THE KERNEL. SEE BELOW. */
+#define LOCAL_HUB(_x)		(HUBREG_CAST (IALIAS_BASE + (_x)))
+#define REMOTE_HUB(_n, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
+					      0x800000 + (_x)))
+
+#endif /* _STANDALONE */
+
+/*
+ * WARNING:
+ *	When certain Hub chip workaround are defined, it's not sufficient
+ *	to dereference the *_HUB_ADDR() macros.  You should instead use
+ *	HUB_L() and HUB_S() if you must deal with pointers to hub registers.
+ *	Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
+ *	They're always safe.
+ */
+#define LOCAL_HUB_ADDR(_x)	(HUBREG_CAST (IALIAS_BASE + (_x)))
+#define REMOTE_HUB_ADDR(_n, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
+					      0x800000 + (_x)))
+
+#if _LANGUAGE_C
+
+#define HUB_L(_a)			*(_a)
+#define	HUB_S(_a, _d)			*(_a) = (_d)
+
+#define LOCAL_HUB_L(_r)			HUB_L(LOCAL_HUB_ADDR(_r))
+#define LOCAL_HUB_S(_r, _d)		HUB_S(LOCAL_HUB_ADDR(_r), (_d))
+#define REMOTE_HUB_L(_n, _r)		HUB_L(REMOTE_HUB_ADDR((_n), (_r)))
+#define REMOTE_HUB_S(_n, _r, _d)	HUB_S(REMOTE_HUB_ADDR((_n), (_r)), (_d))
+
+#endif /* _LANGUAGE_C */
+
+/*
+ * The following macros are used to get to a hub/bridge register, given
+ * the base of the register space.
+ */
+#define HUB_REG_PTR(_base, _off)	\
+	(HUBREG_CAST ((__psunsigned_t)(_base) + (__psunsigned_t)(_off)))
+
+#define HUB_REG_PTR_L(_base, _off)	\
+	HUB_L(HUB_REG_PTR((_base), (_off)))
+
+#define HUB_REG_PTR_S(_base, _off, _data)	\
+	HUB_S(HUB_REG_PTR((_base), (_off)), (_data))
+
+/*
+ * Software structure locations -- permanently fixed
+ *    See diagram in kldir.h
+ */
+
+#define PHYS_RAMBASE		0x0
+#define K0_RAMBASE		PHYS_TO_K0(PHYS_RAMBASE)
+
+#define EX_HANDLER_OFFSET(slice) ((slice) << 16)
+#define EX_HANDLER_ADDR(nasid, slice)					\
+	PHYS_TO_K0(NODE_OFFSET(nasid) | EX_HANDLER_OFFSET(slice))
+#define EX_HANDLER_SIZE		0x0400
+
+#define EX_FRAME_OFFSET(slice)	((slice) << 16 | 0x400)
+#define EX_FRAME_ADDR(nasid, slice)					\
+	PHYS_TO_K0(NODE_OFFSET(nasid) | EX_FRAME_OFFSET(slice))
+#define EX_FRAME_SIZE		0x0c00
+
+#define ARCS_SPB_OFFSET		0x1000
+#define ARCS_SPB_ADDR(nasid)						\
+	PHYS_TO_K0(NODE_OFFSET(nasid) | ARCS_SPB_OFFSET)
+#define ARCS_SPB_SIZE		0x0400
+
+#ifdef _STANDALONE
+
+#define ARCS_TVECTOR_OFFSET	0x2800
+#define ARCS_PVECTOR_OFFSET	0x2c00
+
+/*
+ * These addresses are used by the master CPU to install the transfer
+ * and private vectors.  All others use the SPB to find them.
+ */
+#define TVADDR	(NODE_CAC_BASE(get_nasid()) + ARCS_TVECTOR_OFFSET)
+#define PVADDR	(NODE_CAC_BASE(get_nasid()) + ARCS_PVECTOR_OFFSET)
+
+#endif /* _STANDALONE */
+
+#define KLDIR_OFFSET		0x2000
+#define KLDIR_ADDR(nasid)						\
+	TO_NODE_UNCAC((nasid), KLDIR_OFFSET)
+#define KLDIR_SIZE		0x0400
+
+
+/*
+ * Software structure locations -- indirected through KLDIR
+ *    See diagram in kldir.h
+ *
+ * Important:	All low memory structures must only be accessed
+ *		uncached, except for the symmon stacks.
+ */
+
+#define KLI_LAUNCH		0		/* Dir. entries */
+#define KLI_KLCONFIG		1
+#define	KLI_NMI			2
+#define KLI_GDA			3
+#define KLI_FREEMEM		4
+#define	KLI_SYMMON_STK		5
+#define KLI_PI_ERROR		6
+#define KLI_KERN_VARS		7
+#define	KLI_KERN_XP		8
+#define	KLI_KERN_PARTID		9
+
+#if _LANGUAGE_C
+
+#define KLD_BASE(nasid)		((kldir_ent_t *) KLDIR_ADDR(nasid))
+#define KLD_LAUNCH(nasid)	(KLD_BASE(nasid) + KLI_LAUNCH)
+#define KLD_NMI(nasid)		(KLD_BASE(nasid) + KLI_NMI)
+#define KLD_KLCONFIG(nasid)	(KLD_BASE(nasid) + KLI_KLCONFIG)
+#define KLD_PI_ERROR(nasid)	(KLD_BASE(nasid) + KLI_PI_ERROR)
+#define KLD_GDA(nasid)		(KLD_BASE(nasid) + KLI_GDA)
+#define KLD_SYMMON_STK(nasid)	(KLD_BASE(nasid) + KLI_SYMMON_STK)
+#define KLD_FREEMEM(nasid)	(KLD_BASE(nasid) + KLI_FREEMEM)
+#define KLD_KERN_VARS(nasid)	(KLD_BASE(nasid) + KLI_KERN_VARS)
+#define	KLD_KERN_XP(nasid)	(KLD_BASE(nasid) + KLI_KERN_XP)
+#define	KLD_KERN_PARTID(nasid)	(KLD_BASE(nasid) + KLI_KERN_PARTID)
+
+#define LAUNCH_OFFSET(nasid, slice)					\
+	(KLD_LAUNCH(nasid)->offset +					\
+	 KLD_LAUNCH(nasid)->stride * (slice))
+#define LAUNCH_ADDR(nasid, slice)					\
+	TO_NODE_UNCAC((nasid), LAUNCH_OFFSET(nasid, slice))
+#define LAUNCH_SIZE(nasid)	KLD_LAUNCH(nasid)->size
+
+#define NMI_OFFSET(nasid, slice)					\
+	(KLD_NMI(nasid)->offset +					\
+	 KLD_NMI(nasid)->stride * (slice))
+#define NMI_ADDR(nasid, slice)						\
+	TO_NODE_UNCAC((nasid), NMI_OFFSET(nasid, slice))
+#define NMI_SIZE(nasid)	KLD_NMI(nasid)->size
+
+#define KLCONFIG_OFFSET(nasid)	KLD_KLCONFIG(nasid)->offset
+#define KLCONFIG_ADDR(nasid)						\
+	TO_NODE_UNCAC((nasid), KLCONFIG_OFFSET(nasid))
+#define KLCONFIG_SIZE(nasid)	KLD_KLCONFIG(nasid)->size
+
+#define GDA_ADDR(nasid)		KLD_GDA(nasid)->pointer
+#define GDA_SIZE(nasid)		KLD_GDA(nasid)->size
+
+#define SYMMON_STK_OFFSET(nasid, slice)					\
+	(KLD_SYMMON_STK(nasid)->offset +				\
+	 KLD_SYMMON_STK(nasid)->stride * (slice))
+#define SYMMON_STK_STRIDE(nasid)	KLD_SYMMON_STK(nasid)->stride
+
+#define SYMMON_STK_ADDR(nasid, slice)					\
+	TO_NODE_CAC((nasid), SYMMON_STK_OFFSET(nasid, slice))
+
+#define SYMMON_STK_SIZE(nasid)	KLD_SYMMON_STK(nasid)->stride
+
+#define SYMMON_STK_END(nasid)	(SYMMON_STK_ADDR(nasid, 0) + KLD_SYMMON_STK(nasid)->size)
+
+/* loading symmon 4k below UNIX. the arcs loader needs the topaddr for a
+ * relocatable program
+ */
+#ifdef SN0XXL
+#define UNIX_DEBUG_LOADADDR     0x360000
+#else
+#define	UNIX_DEBUG_LOADADDR	0x300000
+#endif
+#define	SYMMON_LOADADDR(nasid)						\
+	TO_NODE(nasid, PHYS_TO_K0(UNIX_DEBUG_LOADADDR - 0x1000))
+
+#define FREEMEM_OFFSET(nasid)	KLD_FREEMEM(nasid)->offset
+#define FREEMEM_ADDR(nasid)	SYMMON_STK_END(nasid)
+/*
+ * XXX
+ * Fix this. FREEMEM_ADDR should be aware of if symmon is loaded.
+ * Also, it should take into account what prom thinks to be a safe
+ * address
+	PHYS_TO_K0(NODE_OFFSET(nasid) + FREEMEM_OFFSET(nasid))
+ */
+#define FREEMEM_SIZE(nasid)	KLD_FREEMEM(nasid)->size
+
+#define PI_ERROR_OFFSET(nasid)	KLD_PI_ERROR(nasid)->offset
+#define PI_ERROR_ADDR(nasid)						\
+	TO_NODE_UNCAC((nasid), PI_ERROR_OFFSET(nasid))
+#define PI_ERROR_SIZE(nasid)	KLD_PI_ERROR(nasid)->size
+
+#define NODE_OFFSET_TO_K0(_nasid, _off)					\
+	PHYS_TO_K0((NODE_OFFSET(_nasid) + (_off)) | K0BASE)
+#define NODE_OFFSET_TO_K1(_nasid, _off)					\
+	TO_UNCAC((NODE_OFFSET(_nasid) + (_off)) | K1BASE)
+#define K0_TO_NODE_OFFSET(_k0addr)					\
+	((__psunsigned_t)(_k0addr) & NODE_ADDRSPACE_MASK)
+
+#define KERN_VARS_ADDR(nasid)	KLD_KERN_VARS(nasid)->pointer
+#define KERN_VARS_SIZE(nasid)	KLD_KERN_VARS(nasid)->size
+
+#define	KERN_XP_ADDR(nasid)	KLD_KERN_XP(nasid)->pointer
+#define	KERN_XP_SIZE(nasid)	KLD_KERN_XP(nasid)->size
+
+#endif /* _LANGUAGE_C */
+
+/* Fixme for SN1 */
+#include <asm/sn/sn0/addrs.h>
+
+#endif /* _ASM_SN_ADDRS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/agent.h linux/include/asm-mips64/sn/agent.h
--- v2.3.47/linux/include/asm-mips64/sn/agent.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/agent.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,41 @@
+/* $Id: agent.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * This file has definitions for the hub and snac interfaces.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_SGI_SN_AGENT_H
+#define _ASM_SGI_SN_AGENT_H
+
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+//#include <sys/SN/io.h>
+
+#include <asm/sn/sn0/hub.h>
+
+/*
+ * NIC register macros
+ */
+
+#define HUB_NIC_ADDR(_cpuid) 						   \
+	REMOTE_HUB_ADDR(COMPACT_TO_NASID_NODEID(cputocnode(_cpuid)),       \
+		MD_MLAN_CTL)
+
+#define SET_HUB_NIC(_my_cpuid, _val) 				  	   \
+	(HUB_S(HUB_NIC_ADDR(_my_cpuid), (_val)))
+
+#define SET_MY_HUB_NIC(_v) 					           \
+	SET_HUB_NIC(cpuid(), (_v))
+
+#define GET_HUB_NIC(_my_cpuid) 						   \
+	(HUB_L(HUB_NIC_ADDR(_my_cpuid)))
+
+#define GET_MY_HUB_NIC() 						   \
+	GET_HUB_NIC(cpuid())
+
+#endif /* _ASM_SGI_SN_AGENT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/arch.h linux/include/asm-mips64/sn/arch.h
--- v2.3.47/linux/include/asm-mips64/sn/arch.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/arch.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,109 @@
+/* $Id: arch.h,v 1.2 2000/02/10 07:28:35 kanoj Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SGI IP27 specific setup.
+ *
+ * Copyright (C) 1995 - 1997, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_SN_ARCH_H
+#define _ASM_SN_ARCH_H
+
+#include <linux/types.h>
+
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/arch.h>
+
+#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+typedef u64	hubreg_t;
+typedef u64	nic_t;
+#endif
+
+#define CPUS_PER_NODE		2	/* CPUs on a single hub */
+#define CPUS_PER_NODE_SHFT	1	/* Bits to shift in the node number */
+#define CNODE_NUM_CPUS(_cnode)		(NODEPDA(_cnode)->node_num_cpus)
+#define CNODE_TO_CPU_BASE(_cnode)	(NODEPDA(_cnode)->node_first_cpu)
+#define cputocnode(cpu)				\
+               (ASSERT(pdaindr[(cpu)].pda), (pdaindr[(cpu)].pda->p_nodeid))
+#define cputonasid(cpu)				\
+               (ASSERT(pdaindr[(cpu)].pda), (pdaindr[(cpu)].pda->p_nasid))
+#define cputoslice(cpu)				\
+               (ASSERT(pdaindr[(cpu)].pda), (pdaindr[(cpu)].pda->p_slice))
+#define makespnum(_nasid, _slice)					\
+		(((_nasid) << CPUS_PER_NODE_SHFT) | (_slice))
+
+
+#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+
+#define INVALID_NASID		(nasid_t)-1
+#define INVALID_CNODEID		(cnodeid_t)-1
+#define INVALID_PNODEID		(pnodeid_t)-1
+#define INVALID_MODULE		(moduleid_t)-1
+#define	INVALID_PARTID		(partid_t)-1
+
+extern nasid_t get_nasid(void);
+/*
+ * NO ONE should access these arrays directly.  The only reason we refer to
+ * them here is to avoid the procedure call that would be required in the
+ * macros below.  (Really want private data members here :-)
+ */
+extern cnodeid_t nasid_to_compact_node[MAX_NASIDS];
+extern nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
+
+/*
+ * These macros are used by various parts of the kernel to convert
+ * between the three different kinds of node numbering.   At least some
+ * of them may change to procedure calls in the future, but the macros
+ * will continue to work.  Don't use the arrays above directly.
+ */
+
+#define	NASID_TO_REGION(nnode)	      	\
+    ((nnode) >> \
+     (is_fine_dirmode() ? NASID_TO_FINEREG_SHFT : NASID_TO_COARSEREG_SHFT))
+
+#if !defined(DEBUG) && (!defined(SABLE) || defined(_STANDALONE))
+
+#define NASID_TO_COMPACT_NODEID(nnode)	(nasid_to_compact_node[nnode])
+#define COMPACT_TO_NASID_NODEID(cnode)	(compact_to_nasid_node[cnode])
+#define CPUID_TO_COMPACT_NODEID(cpu)	(cpuid_to_compact_node[(cpu)])
+#else
+
+/*
+ * These functions can do type checking and fail if they need to return
+ * a bad nodeid, but they're not as fast so just use 'em for debug kernels.
+ */
+cnodeid_t nasid_to_compact_nodeid(nasid_t nasid);
+nasid_t compact_to_nasid_nodeid(cnodeid_t cnode);
+
+#define NASID_TO_COMPACT_NODEID(nnode)	nasid_to_compact_nodeid(nnode)
+#define COMPACT_TO_NASID_NODEID(cnode)	compact_to_nasid_nodeid(cnode)
+#define CPUID_TO_COMPACT_NODEID(cpu)	(cpuid_to_compact_node[(cpu)])
+#endif
+
+extern int node_getlastslot(cnodeid_t);
+
+#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */
+
+#define SLOT_BITMASK    	(MAX_MEM_SLOTS - 1)
+#define SLOT_SIZE		(1LL<<SLOT_SHIFT)
+
+#if SABLE
+#define node_getnumslots(node)	(1)
+#define	NODE_MAX_MEM_SIZE	SLOT_SIZE * 1
+#else
+#define node_getnumslots(node)	(MAX_MEM_SLOTS)
+#define NODE_MAX_MEM_SIZE	SLOT_SIZE * MAX_MEM_SLOTS
+#endif /* SABLE */
+
+/*
+ * New stuff in here from Irix sys/pfdat.h.
+ */
+#define	SLOT_PFNSHIFT		(SLOT_SHIFT - PAGE_SHIFT)
+#define	PFN_NASIDSHFT		(NASID_SHFT - PAGE_SHIFT)
+#define mkpfn(nasid, off)	(((pfn_t)(nasid) << PFN_NASIDSHFT) | (off))
+#define slot_getbasepfn(node,slot) \
+		(mkpfn(COMPACT_TO_NASID_NODEID(node), slot<<SLOT_PFNSHIFT))
+#endif /* _ASM_SN_ARCH_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/gda.h linux/include/asm-mips64/sn/gda.h
--- v2.3.47/linux/include/asm-mips64/sn/gda.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/gda.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,112 @@
+/**************************************************************************
+ *                                                                        *
+ *               Copyright (C) 1992-1997, Silicon Graphics, Inc.          *
+ *                                                                        *
+ *  These coded instructions, statements, and computer programs  contain  *
+ *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
+ *  are protected by Federal copyright law.  They  may  not be disclosed  *
+ *  to  third  parties  or copied or duplicated in any form, in whole or  *
+ *  in part, without the prior written consent of Silicon Graphics, Inc.  *
+ *                                                                        *
+ **************************************************************************/
+
+/*
+ * gda.h -- Contains the data structure for the global data area,
+ * 	The GDA contains information communicated between the
+ *	PROM, SYMMON, and the kernel. 
+ */
+
+#ifndef __SYS_SN_GDA_H__
+#define __SYS_SN_GDA_H__
+
+#include <asm/sn/addrs.h>
+
+#define GDA_MAGIC	0x58464552
+
+/*
+ * GDA Version History
+ *
+ * Version #	| Change
+ * -------------+-------------------------------------------------------
+ * 	1	| Initial SN0 version 
+ * 	2	| Prom sets g_partid field to the partition number. 0 IS
+ *		| a valid partition #. 
+ */
+
+#define GDA_VERSION	2	/* Current GDA version # */
+
+#define G_MAGICOFF	0
+#define G_VERSIONOFF	4
+#define G_PROMOPOFF	6
+#define G_MASTEROFF	8
+#define G_VDSOFF	12
+#define G_HKDNORMOFF	16
+#define G_HKDUTLBOFF	24
+#define G_HKDXUTLBOFF	32
+#define G_PARTIDOFF	40
+#define G_TABLEOFF	128
+
+#ifdef _LANGUAGE_C
+
+typedef struct gda {
+	u32	g_magic;	/* GDA magic number */
+	u16	g_version;	/* Version of this structure */
+	u16	g_masterid;	/* The NASID:CPUNUM of the master cpu */
+	u32	g_promop;	/* Passes requests from the kernel to prom */
+	u32	g_vds;		/* Store the virtual dipswitches here */
+	void	**g_hooked_norm;/* ptr to pda loc for norm hndlr */
+	void	**g_hooked_utlb;/* ptr to pda loc for utlb hndlr */
+	void	**g_hooked_xtlb;/* ptr to pda loc for xtlb hndlr */
+	int	g_partid;	/* partition id */
+	int	g_symmax;	/* Max symbols in name table. */
+	void	*g_dbstab;	/* Address of idbg symbol table */
+	char	*g_nametab;	/* Address of idbg name table */
+	void	*g_ktext_repmask;
+				/* Pointer to a mask of nodes with copies
+				 * of the kernel. */
+	char	g_padding[56];	/* pad out to 128 bytes */
+	nasid_t	g_nasidtable[MAX_COMPACT_NODES]; /* NASID of each node,
+						  * indexed by cnodeid.
+						  */
+} gda_t;
+
+#define GDA ((gda_t*) GDA_ADDR(get_nasid()))
+
+#endif /* __LANGUAGE_C */
+/*
+ * Define:	PART_GDA_VERSION
+ * Purpose:	Define the minimum version of the GDA required, lower 
+ *		revisions assume GDA is NOT set up, and read partition
+ *		information from the board info.
+ */
+#define	PART_GDA_VERSION	2
+
+/*
+ * The following requests can be sent to the PROM during startup.
+ */
+
+#define PROMOP_MAGIC		0x0ead0000
+#define PROMOP_MAGIC_MASK	0x0fff0000
+
+#define PROMOP_BIST_SHIFT       11
+#define PROMOP_BIST_MASK        (0x3 << 11)
+
+#define PROMOP_REG		PI_ERR_STACK_ADDR_A
+
+#define PROMOP_INVALID		(PROMOP_MAGIC | 0x00)
+#define PROMOP_HALT             (PROMOP_MAGIC | 0x10)
+#define PROMOP_POWERDOWN        (PROMOP_MAGIC | 0x20)
+#define PROMOP_RESTART          (PROMOP_MAGIC | 0x30)
+#define PROMOP_REBOOT           (PROMOP_MAGIC | 0x40)
+#define PROMOP_IMODE            (PROMOP_MAGIC | 0x50)
+
+#define PROMOP_CMD_MASK		0x00f0
+#define PROMOP_OPTIONS_MASK	0xfff0
+
+#define PROMOP_SKIP_DIAGS	0x0100		/* don't bother running diags */
+#define PROMOP_SKIP_MEMINIT	0x0200		/* don't bother initing memory */
+#define PROMOP_SKIP_DEVINIT	0x0400		/* don't bother initing devices */
+#define PROMOP_BIST1		0x0800		/* keep track of which BIST ran */
+#define PROMOP_BIST2		0x1000		/* keep track of which BIST ran */
+
+#endif /* __SYS_SN_GDA_H__ */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/io.h linux/include/asm-mips64/sn/io.h
--- v2.3.47/linux/include/asm-mips64/sn/io.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/io.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,22 @@
+/* $Id: io.h,v 1.1 2000/02/04 07:40:53 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Ralf Baechle
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SN_IO_H
+#define _ASM_SN_IO_H
+
+#include <asm/sn/sn0/addrs.h>
+
+#define IO_SPACE_BASE IO_BASE
+
+/* Because we only have PCI I/O ports.  */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* No isa_* versions, the Origin doesn't have ISA / EISA bridges.  */
+
+#endif /* _ASM_SN_IO_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/klconfig.h linux/include/asm-mips64/sn/klconfig.h
--- v2.3.47/linux/include/asm-mips64/sn/klconfig.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/klconfig.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,903 @@
+/* $Id: klconfig.h,v 1.2 2000/01/16 01:39:08 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/klconfig.h>.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef	_ASM_SN_KLCONFIG_H
+#define	_ASM_SN_KLCONFIG_H
+
+/*
+ * klconfig.h
+ */
+
+/*
+ * The KLCONFIG structures store info about the various BOARDs found
+ * during Hardware Discovery. In addition, it stores info about the
+ * components found on the BOARDs.
+ */
+
+/*
+ * WARNING:
+ *	Certain assembly language routines (notably xxxxx.s) in the IP27PROM 
+ *	will depend on the format of the data structures in this file.  In 
+ *      most cases, rearranging the fields can seriously break things.   
+ *      Adding fields in the beginning or middle can also break things.
+ *      Add fields if necessary, to the end of a struct in such a way
+ *      that offsets of existing fields do not change.
+ */
+
+#include <linux/types.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+//#include <sys/SN/router.h>
+// XXX Stolen from <sys/SN/router.h>:
+#define MAX_ROUTER_PORTS (6)	/* Max. number of ports on a router */
+#include <asm/sn/agent.h>
+//#include <sys/graph.h>
+#include <asm/arc/types.h>
+#include <asm/arc/hinv.h>
+//#include <sys/xtalk/xbow.h>
+#include <asm/sn/sn0/sn0_fru.h>
+
+
+#define KLCFGINFO_MAGIC	0xbeedbabe
+
+#ifdef FRUTEST
+typedef u64 klconf_off_t;
+#else
+typedef s32 klconf_off_t;
+#endif
+
+/*
+ * Some IMPORTANT OFFSETS. These are the offsets on all NODES.
+ */
+#if 0
+#define RAMBASE                 0
+#define ARCSSPB_OFF             0x1000 /* shift it to sys/arcs/spb.h */
+
+#define OFF_HWGRAPH 		0
+#endif
+
+#define	MAX_MODULE_ID		255
+#define SIZE_PAD		4096 /* 4k padding for structures */
+/* 
+ * 1 NODE brd, 2 Router brd (1 8p, 1 meta), 6 Widgets, 
+ * 2 Midplanes assuming no pci card cages 
+ */
+#define MAX_SLOTS_PER_NODE	(1 + 2 + 6 + 2) 
+
+/* XXX if each node is guranteed to have some memory */
+
+#define MAX_PCI_DEVS		8
+
+/* lboard_t->brd_flags fields */
+/* All bits in this field are currently used. Try the pad fields if
+   you need more flag bits */
+
+#define ENABLE_BOARD 		0x01
+#define FAILED_BOARD  		0x02
+#define DUPLICATE_BOARD 	0x04    /* Boards like midplanes/routers which
+                                   	   are discovered twice. Use one of them */
+#define VISITED_BOARD		0x08	/* Used for compact hub numbering. */
+#define LOCAL_MASTER_IO6	0x10 	/* master io6 for that node */
+#define GLOBAL_MASTER_IO6	0x20
+#define THIRD_NIC_PRESENT 	0x40  	/* for future use */
+#define SECOND_NIC_PRESENT 	0x80 	/* addons like MIO are present */
+
+/* klinfo->flags fields */
+
+#define KLINFO_ENABLE 		0x01    /* This component is enabled */
+#define KLINFO_FAILED   	0x02 	/* This component failed */
+#define KLINFO_DEVICE   	0x04 	/* This component is a device */
+#define KLINFO_VISITED  	0x08 	/* This component has been visited */
+#define KLINFO_CONTROLLER   	0x10 	/* This component is a device controller */
+#define KLINFO_INSTALL   	0x20  	/* Install a driver */
+#define	KLINFO_HEADLESS		0x40	/* Headless (or hubless) component */
+#define IS_CONSOLE_IOC3(i)	((((klinfo_t *)i)->flags) & KLINFO_INSTALL)
+
+#define GB2		0x80000000
+
+#define MAX_RSV_PTRS	32
+
+/* Structures to manage various data storage areas */
+/* The numbers must be contiguous since the array index i
+   is used in the code to allocate various areas. 
+*/
+
+#define BOARD_STRUCT 		0
+#define COMPONENT_STRUCT 	1
+#define ERRINFO_STRUCT 		2
+#define KLMALLOC_TYPE_MAX 	(ERRINFO_STRUCT + 1)
+#define DEVICE_STRUCT 		3
+
+
+typedef struct console_s {
+	unsigned long 	uart_base;
+	unsigned long 	config_base;
+	unsigned long 	memory_base;
+	short		baud;
+	short		flag;
+	int		type;
+	nasid_t		nasid;
+	char		wid;
+	char 		npci;
+	nic_t		baseio_nic;
+} console_t;
+
+typedef struct klc_malloc_hdr {
+        klconf_off_t km_base;
+        klconf_off_t km_limit;
+        klconf_off_t km_current;
+} klc_malloc_hdr_t;
+
+/* Functions/macros needed to use this structure */
+
+typedef struct kl_config_hdr {
+	u64		ch_magic;	/* set this to KLCFGINFO_MAGIC */
+	u32		ch_version;    /* structure version number */
+	klconf_off_t	ch_malloc_hdr_off; /* offset of ch_malloc_hdr */
+	klconf_off_t	ch_cons_off;       /* offset of ch_cons */
+	klconf_off_t	ch_board_info;	/* the link list of boards */
+	console_t	ch_cons_info;	/* address info of the console */
+	klc_malloc_hdr_t ch_malloc_hdr[KLMALLOC_TYPE_MAX];
+	confidence_t	ch_sw_belief;	/* confidence that software is bad*/
+	confidence_t	ch_sn0net_belief; /* confidence that sn0net is bad */
+} kl_config_hdr_t;
+
+
+#define KL_CONFIG_HDR(_nasid) 	((kl_config_hdr_t *)(KLCONFIG_ADDR(_nasid)))
+#if 0
+#define KL_CONFIG_MALLOC_HDR(_nasid) \
+                                (KL_CONFIG_HDR(_nasid)->ch_malloc_hdr)
+#endif
+#define KL_CONFIG_INFO_OFFSET(_nasid)					\
+        (KL_CONFIG_HDR(_nasid)->ch_board_info)
+#define KL_CONFIG_INFO_SET_OFFSET(_nasid, _off)				\
+        (KL_CONFIG_HDR(_nasid)->ch_board_info = (_off))
+
+#define KL_CONFIG_INFO(_nasid) 						\
+        (lboard_t *)((KL_CONFIG_HDR(_nasid)->ch_board_info) ?		\
+	 NODE_OFFSET_TO_K1((_nasid), KL_CONFIG_HDR(_nasid)->ch_board_info) : \
+	 0)
+#define KL_CONFIG_MAGIC(_nasid)		(KL_CONFIG_HDR(_nasid)->ch_magic)
+
+#define KL_CONFIG_CHECK_MAGIC(_nasid)					\
+        (KL_CONFIG_HDR(_nasid)->ch_magic == KLCFGINFO_MAGIC)
+
+#define KL_CONFIG_HDR_INIT_MAGIC(_nasid)	\
+                  (KL_CONFIG_HDR(_nasid)->ch_magic = KLCFGINFO_MAGIC)
+
+/* --- New Macros for the changed kl_config_hdr_t structure --- */
+
+#define PTR_CH_MALLOC_HDR(_k)   ((klc_malloc_hdr_t *)\
+			((unsigned long)_k + (_k->ch_malloc_hdr_off)))
+
+#define KL_CONFIG_CH_MALLOC_HDR(_n)   PTR_CH_MALLOC_HDR(KL_CONFIG_HDR(_n))
+
+#define PTR_CH_CONS_INFO(_k)	((console_t *)\
+			((unsigned long)_k + (_k->ch_cons_off)))
+
+#define KL_CONFIG_CH_CONS_INFO(_n)   PTR_CH_CONS_INFO(KL_CONFIG_HDR(_n))
+
+/* ------------------------------------------------------------- */
+
+#define KL_CONFIG_INFO_START(_nasid)	\
+        (klconf_off_t)(KLCONFIG_OFFSET(_nasid) + sizeof(kl_config_hdr_t))
+
+#define KL_CONFIG_BOARD_NASID(_brd)	((_brd)->brd_nasid)
+#define KL_CONFIG_BOARD_SET_NEXT(_brd, _off)	((_brd)->brd_next = (_off))
+
+#define KL_CONFIG_DUPLICATE_BOARD(_brd)	((_brd)->brd_flags & DUPLICATE_BOARD)
+
+#define XBOW_PORT_TYPE_HUB(_xbowp, _link) 	\
+               ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_flag & XBOW_PORT_HUB)
+#define XBOW_PORT_TYPE_IO(_xbowp, _link) 	\
+               ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_flag & XBOW_PORT_IO)
+
+#define XBOW_PORT_IS_ENABLED(_xbowp, _link) 	\
+               ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_flag & XBOW_PORT_ENABLE)
+#define XBOW_PORT_NASID(_xbowp, _link) 	\
+               ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_nasid)
+
+#define XBOW_PORT_IO     0x1
+#define XBOW_PORT_HUB    0x2
+#define XBOW_PORT_ENABLE 0x4
+
+#define	SN0_PORT_FENCE_SHFT	0
+#define	SN0_PORT_FENCE_MASK	(1 << SN0_PORT_FENCE_SHFT)
+
+/*
+ * The KLCONFIG area is organized as a LINKED LIST of BOARDs. A BOARD
+ * can be either 'LOCAL' or 'REMOTE'. LOCAL means it is attached to 
+ * the LOCAL/current NODE. REMOTE means it is attached to a different
+ * node.(TBD - Need a way to treat ROUTER boards.)
+ *
+ * There are 2 different structures to represent these boards -
+ * lboard - Local board, rboard - remote board. These 2 structures
+ * can be arbitrarily mixed in the LINKED LIST of BOARDs. (Refer
+ * Figure below). The first byte of the rboard or lboard structure
+ * is used to find out its type - no unions are used.
+ * If it is a lboard, then the config info of this board will be found
+ * on the local node. (LOCAL NODE BASE + offset value gives pointer to 
+ * the structure.
+ * If it is a rboard, the local structure contains the node number
+ * and the offset of the beginning of the LINKED LIST on the remote node.
+ * The details of the hardware on a remote node can be built locally,
+ * if required, by reading the LINKED LIST on the remote node and 
+ * ignoring all the rboards on that node.
+ *
+ * The local node uses the REMOTE NODE NUMBER + OFFSET to point to the 
+ * First board info on the remote node. The remote node list is 
+ * traversed as the local list, using the REMOTE BASE ADDRESS and not
+ * the local base address and ignoring all rboard values.
+ *
+ * 
+ KLCONFIG
+
+ +------------+      +------------+      +------------+      +------------+
+ |  lboard    |  +-->|   lboard   |  +-->|   rboard   |  +-->|   lboard   |
+ +------------+  |   +------------+  |   +------------+  |   +------------+
+ | board info |  |   | board info |  |   |errinfo,bptr|  |   | board info |
+ +------------+  |   +------------+  |   +------------+  |   +------------+
+ | offset     |--+   |  offset    |--+   |  offset    |--+   |offset=NULL |
+ +------------+      +------------+      +------------+      +------------+
+
+
+ +------------+
+ | board info |
+ +------------+       +--------------------------------+
+ | compt 1    |------>| type, rev, diaginfo, size ...  |  (CPU)
+ +------------+       +--------------------------------+
+ | compt 2    |--+
+ +------------+  |    +--------------------------------+
+ |  ...       |  +--->| type, rev, diaginfo, size ...  |  (MEM_BANK)
+ +------------+       +--------------------------------+
+ | errinfo    |--+
+ +------------+  |    +--------------------------------+
+                 +--->|r/l brd errinfo,compt err flags |
+                      +--------------------------------+
+
+ *
+ * Each BOARD consists of COMPONENTs and the BOARD structure has 
+ * pointers (offsets) to its COMPONENT structure.
+ * The COMPONENT structure has version info, size and speed info, revision,
+ * error info and the NIC info. This structure can accomodate any
+ * BOARD with arbitrary COMPONENT composition.
+ *
+ * The ERRORINFO part of each BOARD has error information
+ * that describes errors about the BOARD itself. It also has flags to
+ * indicate the COMPONENT(s) on the board that have errors. The error 
+ * information specific to the COMPONENT is present in the respective 
+ * COMPONENT structure.
+ *
+ * The ERRORINFO structure is also treated like a COMPONENT, ie. the 
+ * BOARD has pointers(offset) to the ERRORINFO structure. The rboard
+ * structure also has a pointer to the ERRORINFO structure. This is 
+ * the place to store ERRORINFO about a REMOTE NODE, if the HUB on
+ * that NODE is not working or if the REMOTE MEMORY is BAD. In cases where 
+ * only the CPU of the REMOTE NODE is disabled, the ERRORINFO pointer can
+ * be a NODE NUMBER, REMOTE OFFSET combination, pointing to error info 
+ * which is present on the REMOTE NODE.(TBD)
+ * REMOTE ERRINFO can be stored on any of the nearest nodes 
+ * or on all the nearest nodes.(TBD)
+ * Like BOARD structures, REMOTE ERRINFO structures can be built locally
+ * using the rboard errinfo pointer.
+ *
+ * In order to get useful information from this Data organization, a set of
+ * interface routines are provided (TBD). The important thing to remember while
+ * manipulating the structures, is that, the NODE number information should
+ * be used. If the NODE is non-zero (remote) then each offset should
+ * be added to the REMOTE BASE ADDR else it should be added to the LOCAL BASE ADDR. 
+ * This includes offsets for BOARDS, COMPONENTS and ERRORINFO.
+ * 
+ * Note that these structures do not provide much info about connectivity.
+ * That info will be part of HWGRAPH, which is an extension of the cfg_t
+ * data structure. (ref IP27prom/cfg.h) It has to be extended to include
+ * the IO part of the Network(TBD).
+ *
+ * The data structures below define the above concepts.
+ */
+
+/*
+ * Values for CPU types
+ */
+#define KL_CPU_R4000		0x1	/* Standard R4000 */
+#define KL_CPU_TFP		0x2	/* TFP processor */
+#define	KL_CPU_R10000		0x3	/* R10000 (T5) */
+#define KL_CPU_NONE		(-1)	/* no cpu present in slot */
+
+/*
+ * SN0 BOARD classes
+ */
+
+#define KLCLASS_MASK	0xf0   
+#define KLCLASS_NONE	0x00
+#define KLCLASS_NODE	0x10             /* CPU, Memory and HUB board */
+#define KLCLASS_CPU	KLCLASS_NODE	
+#define KLCLASS_IO	0x20             /* BaseIO, 4 ch SCSI, ethernet, FDDI 
+					    and the non-graphics widget boards */
+#define KLCLASS_ROUTER	0x30             /* Router board */
+#define KLCLASS_MIDPLANE 0x40            /* We need to treat this as a board
+                                            so that we can record error info */
+#define KLCLASS_GFX	0x50		/* graphics boards */
+
+#define KLCLASS_PSEUDO_GFX	0x60	/* HDTV type cards that use a gfx
+					 * hw ifc to xtalk and are not gfx
+					 * class for sw purposes */
+
+#define KLCLASS_MAX	6		/* Bump this if a new CLASS is added */
+#define KLTYPE_MAX	8		/* Bump this if a new CLASS is added */
+
+#define KLCLASS_UNKNOWN	0xf0
+
+#define KLCLASS(_x) ((_x) & KLCLASS_MASK)
+
+/*
+ * SN0 board types
+ */
+
+#define KLTYPE_MASK	0x0f
+#define KLTYPE_NONE	0x00
+#define KLTYPE_EMPTY	0x00
+
+#define KLTYPE_WEIRDCPU (KLCLASS_CPU | 0x0)
+#define KLTYPE_IP27	(KLCLASS_CPU | 0x1) /* 2 CPUs(R10K) per board */
+
+#define KLTYPE_WEIRDIO	(KLCLASS_IO  | 0x0)
+#define KLTYPE_BASEIO	(KLCLASS_IO  | 0x1) /* IOC3, SuperIO, Bridge, SCSI */
+#define KLTYPE_IO6	KLTYPE_BASEIO       /* Additional name */
+#define KLTYPE_4CHSCSI	(KLCLASS_IO  | 0x2)
+#define KLTYPE_MSCSI	KLTYPE_4CHSCSI      /* Additional name */
+#define KLTYPE_ETHERNET	(KLCLASS_IO  | 0x3)
+#define KLTYPE_MENET	KLTYPE_ETHERNET     /* Additional name */
+#define KLTYPE_FDDI  	(KLCLASS_IO  | 0x4)
+#define KLTYPE_UNUSED	(KLCLASS_IO  | 0x5) /* XXX UNUSED */
+#define KLTYPE_HAROLD   (KLCLASS_IO  | 0x6) /* PCI SHOE BOX */
+#define KLTYPE_PCI	KLTYPE_HAROLD
+#define KLTYPE_VME      (KLCLASS_IO  | 0x7) /* Any 3rd party VME card */
+#define KLTYPE_MIO   	(KLCLASS_IO  | 0x8)
+#define KLTYPE_FC    	(KLCLASS_IO  | 0x9)
+#define KLTYPE_LINC    	(KLCLASS_IO  | 0xA)
+#define KLTYPE_TPU    	(KLCLASS_IO  | 0xB) /* Tensor Processing Unit */
+#define KLTYPE_GSN_A   	(KLCLASS_IO  | 0xC) /* Main GSN board */
+#define KLTYPE_GSN_B   	(KLCLASS_IO  | 0xD) /* Auxiliary GSN board */
+
+#define KLTYPE_GFX	(KLCLASS_GFX | 0x0) /* unknown graphics type */
+#define KLTYPE_GFX_KONA (KLCLASS_GFX | 0x1) /* KONA graphics on SN0 */
+#define KLTYPE_GFX_MGRA (KLCLASS_GFX | 0x3) /* MGRAS graphics on SN0 */
+
+#define KLTYPE_WEIRDROUTER (KLCLASS_ROUTER | 0x0)
+#define KLTYPE_ROUTER     (KLCLASS_ROUTER | 0x1)
+#define KLTYPE_ROUTER2    KLTYPE_ROUTER		/* Obsolete! */
+#define KLTYPE_NULL_ROUTER (KLCLASS_ROUTER | 0x2)
+#define KLTYPE_META_ROUTER (KLCLASS_ROUTER | 0x3)
+
+#define KLTYPE_WEIRDMIDPLANE (KLCLASS_MIDPLANE | 0x0)
+#define KLTYPE_MIDPLANE8  (KLCLASS_MIDPLANE | 0x1) /* 8 slot backplane */
+#define KLTYPE_MIDPLANE    KLTYPE_MIDPLANE8
+
+/* The value of type should be more than 8 so that hinv prints
+ * out the board name from the NIC string. For values less than
+ * 8 the name of the board needs to be hard coded in a few places.
+ * When bringup started nic names had not standardized and so we
+ * had to hard code. (For people interested in history.) 
+ */
+#define KLTYPE_XTHD   	(KLCLASS_PSEUDO_GFX | 0x9)
+
+#define KLTYPE_UNKNOWN	(KLCLASS_UNKNOWN | 0xf)
+
+#define KLTYPE(_x) 	((_x) & KLTYPE_MASK)
+#define IS_MIO_PRESENT(l)	((l->brd_type == KLTYPE_BASEIO) && \
+				 (l->brd_flags & SECOND_NIC_PRESENT))
+#define IS_MIO_IOC3(l,n)	(IS_MIO_PRESENT(l) && (n > 2))
+
+/* 
+ * board structures
+ */
+
+#define MAX_COMPTS_PER_BRD 24
+
+#define LOCAL_BOARD 1
+#define REMOTE_BOARD 2
+
+#define LBOARD_STRUCT_VERSION 	2
+
+typedef struct lboard_s {
+	klconf_off_t 	brd_next;         /* Next BOARD */
+	unsigned char 	struct_type;      /* type of structure, local or remote */
+	unsigned char 	brd_type;         /* type+class */
+	unsigned char 	brd_sversion;     /* version of this structure */
+        unsigned char 	brd_brevision;    /* board revision */
+        unsigned char 	brd_promver;      /* board prom version, if any */
+ 	unsigned char 	brd_flags;        /* Enabled, Disabled etc */
+	unsigned char 	brd_slot;         /* slot number */
+	unsigned short	brd_debugsw;      /* Debug switches */
+	moduleid_t	brd_module;       /* module to which it belongs */
+	partid_t 	brd_partition;    /* Partition number */
+        unsigned short 	brd_diagval;      /* diagnostic value */
+        unsigned short 	brd_diagparm;     /* diagnostic parameter */
+        unsigned char 	brd_inventory;    /* inventory history */
+        unsigned char 	brd_numcompts;    /* Number of components */
+        nic_t         	brd_nic;          /* Number in CAN */
+	nasid_t		brd_nasid;        /* passed parameter */
+	klconf_off_t 	brd_compts[MAX_COMPTS_PER_BRD]; /* pointers to COMPONENTS */
+	klconf_off_t 	brd_errinfo;      /* Board's error information */
+	struct lboard_s *brd_parent;	  /* Logical parent for this brd */
+	vertex_hdl_t	brd_graph_link;   /* vertex hdl to connect extern compts */
+	confidence_t	brd_confidence;	  /* confidence that the board is bad */
+	nasid_t		brd_owner;        /* who owns this board */
+	unsigned char 	brd_nic_flags;    /* To handle 8 more NICs */
+	char		brd_name[32];
+} lboard_t;
+
+
+/*
+ *	Make sure we pass back the calias space address for local boards.
+ *	klconfig board traversal and error structure extraction defines.
+ */
+
+#define BOARD_SLOT(_brd)	((_brd)->brd_slot)
+
+#define KLCF_CLASS(_brd)	KLCLASS((_brd)->brd_type)
+#define KLCF_TYPE(_brd)		KLTYPE((_brd)->brd_type)
+#define KLCF_REMOTE(_brd)  	(((_brd)->struct_type & LOCAL_BOARD) ? 0 : 1)
+#define KLCF_NUM_COMPS(_brd)	((_brd)->brd_numcompts)
+#define KLCF_MODULE_ID(_brd)	((_brd)->brd_module)
+
+#ifdef FRUTEST
+
+#define KLCF_NEXT(_brd) 		((_brd)->brd_next ? (lboard_t *)((_brd)->brd_next):  NULL)
+#define KLCF_COMP(_brd, _ndx)   	(klinfo_t *)((_brd)->brd_compts[(_ndx)])
+#define KLCF_COMP_ERROR(_brd, _comp)   	(_brd = _brd , (_comp)->errinfo)
+
+#else
+
+#define KLCF_NEXT(_brd) 	\
+        ((_brd)->brd_next ? 	\
+	 (lboard_t *)(NODE_OFFSET_TO_K1(NASID_GET(_brd), (_brd)->brd_next)):\
+	 NULL)
+#define KLCF_COMP(_brd, _ndx)   \
+                (klinfo_t *)(NODE_OFFSET_TO_K1(NASID_GET(_brd),	\
+					       (_brd)->brd_compts[(_ndx)]))
+
+#define KLCF_COMP_ERROR(_brd, _comp)	\
+               (NODE_OFFSET_TO_K1(NASID_GET(_brd), (_comp)->errinfo))
+
+#endif
+
+#define KLCF_COMP_TYPE(_comp)	((_comp)->struct_type)
+#define KLCF_BRIDGE_W_ID(_comp)	((_comp)->physid)	/* Widget ID */
+
+
+
+/*
+ * Generic info structure. This stores common info about a 
+ * component.
+ */
+ 
+typedef struct klinfo_s {                  /* Generic info */
+        unsigned char   struct_type;       /* type of this structure */
+        unsigned char   struct_version;    /* version of this structure */
+        unsigned char   flags;            /* Enabled, disabled etc */
+        unsigned char   revision;         /* component revision */
+        unsigned short  diagval;          /* result of diagnostics */
+        unsigned short  diagparm;         /* diagnostic parameter */
+        unsigned char   inventory;        /* previous inventory status */
+	nic_t 		nic;              /* MUst be aligned properly */
+        unsigned char   physid;           /* physical id of component */
+        unsigned int    virtid;           /* virtual id as seen by system */
+	unsigned char	widid;	          /* Widget id - if applicable */
+	nasid_t		nasid;            /* node number - from parent */
+	char		pad1;		  /* pad out structure. */
+	char		pad2;		  /* pad out structure. */
+	COMPONENT	*arcs_compt;      /* ptr to the arcs struct for ease*/
+        klconf_off_t	errinfo;          /* component specific errors */
+        unsigned short  pad3;             /* pci fields have moved over to */
+        unsigned short  pad4;             /* klbri_t */
+} klinfo_t ;
+
+#define KLCONFIG_INFO_ENABLED(_i)	((_i)->flags & KLINFO_ENABLE)
+/*
+ * Component structures.
+ * Following are the currently identified components:
+ * 	CPU, HUB, MEM_BANK, 
+ * 	XBOW(consists of 16 WIDGETs, each of which can be HUB or GRAPHICS or BRIDGE)
+ * 	BRIDGE, IOC3, SuperIO, SCSI, FDDI 
+ * 	ROUTER
+ * 	GRAPHICS
+ */
+#define KLSTRUCT_UNKNOWN	0
+#define KLSTRUCT_CPU  		1
+#define KLSTRUCT_HUB  		2
+#define KLSTRUCT_MEMBNK 	3
+#define KLSTRUCT_XBOW 		4
+#define KLSTRUCT_BRI 		5
+#define KLSTRUCT_IOC3 		6
+#define KLSTRUCT_PCI 		7
+#define KLSTRUCT_VME 		8
+#define KLSTRUCT_ROU		9
+#define KLSTRUCT_GFX 		10
+#define KLSTRUCT_SCSI 		11
+#define KLSTRUCT_FDDI 		12
+#define KLSTRUCT_MIO 		13
+#define KLSTRUCT_DISK 		14
+#define KLSTRUCT_TAPE 		15
+#define KLSTRUCT_CDROM 		16
+#define KLSTRUCT_HUB_UART 	17
+#define KLSTRUCT_IOC3ENET 	18
+#define KLSTRUCT_IOC3UART 	19
+#define KLSTRUCT_UNUSED		20 /* XXX UNUSED */
+#define KLSTRUCT_IOC3PCKM       21
+#define KLSTRUCT_RAD        	22
+#define KLSTRUCT_HUB_TTY        23
+#define KLSTRUCT_IOC3_TTY 	24
+
+/* Early Access IO proms are compatible
+   only with KLSTRUCT values upto 24. */
+
+#define KLSTRUCT_FIBERCHANNEL 	25
+#define KLSTRUCT_MOD_SERIAL_NUM 26
+#define KLSTRUCT_IOC3MS         27
+#define KLSTRUCT_TPU            28
+#define KLSTRUCT_GSN_A          29
+#define KLSTRUCT_GSN_B          30
+#define KLSTRUCT_XTHD           31
+
+/*
+ * These are the indices of various components within a lboard structure.
+ */
+
+#define IP27_CPU0_INDEX 0
+#define IP27_CPU1_INDEX 1
+#define IP27_HUB_INDEX 2
+#define IP27_MEM_INDEX 3
+
+#define BASEIO_BRIDGE_INDEX 0
+#define BASEIO_IOC3_INDEX 1
+#define BASEIO_SCSI1_INDEX 2
+#define BASEIO_SCSI2_INDEX 3
+
+#define MIDPLANE_XBOW_INDEX 0
+#define ROUTER_COMPONENT_INDEX 0
+
+#define CH4SCSI_BRIDGE_INDEX 0
+
+/* Info holders for various hardware components */
+
+typedef u64 *pci_t;
+typedef u64 *vmeb_t;
+typedef u64 *vmed_t;
+typedef u64 *fddi_t;
+typedef u64 *scsi_t;
+typedef u64 *mio_t;
+typedef u64 *graphics_t;
+typedef u64 *router_t;
+
+/*
+ * The port info in ip27_cfg area translates to a lboart_t in the 
+ * KLCONFIG area. But since KLCONFIG does not use pointers, lboart_t
+ * is stored in terms of a nasid and a offset from start of KLCONFIG 
+ * area  on that nasid.
+ */
+typedef struct klport_s {
+	nasid_t		port_nasid;
+	unsigned char	port_flag;
+	klconf_off_t	port_offset;
+} klport_t;
+
+#if 0
+/*
+ * This is very similar to the klport_s but instead of having a componant
+ * offset it has a board offset.
+ */
+typedef struct klxbow_port_s {
+	nasid_t		port_nasid;
+	unsigned char	port_flag;
+	klconf_off_t	board_offset;
+} klxbow_port_t;
+#endif
+
+typedef struct klcpu_s {                          /* CPU */
+	klinfo_t 	cpu_info;
+	unsigned short 	cpu_prid;	/* Processor PRID value */
+	unsigned short 	cpu_fpirr;	/* FPU IRR value */
+    	unsigned short 	cpu_speed;	/* Speed in MHZ */
+    	unsigned short 	cpu_scachesz;	/* secondary cache size in MB */
+    	unsigned short 	cpu_scachespeed;/* secondary cache speed in MHz */
+} klcpu_t ;
+
+#define CPU_STRUCT_VERSION   2
+
+typedef struct klhub_s {			/* HUB */
+	klinfo_t 	hub_info;
+	uint 		hub_flags;		/* PCFG_HUB_xxx flags */
+	klport_t	hub_port;		/* hub is connected to this */
+	nic_t		hub_box_nic;		/* nic of containing box */
+	klconf_off_t	hub_mfg_nic;		/* MFG NIC string */
+	u64		hub_speed;		/* Speed of hub in HZ */
+} klhub_t ;
+
+typedef struct klhub_uart_s {			/* HUB */
+	klinfo_t 	hubuart_info;
+	uint 		hubuart_flags;		/* PCFG_HUB_xxx flags */
+	nic_t		hubuart_box_nic;	/* nic of containing box */
+} klhub_uart_t ;
+
+#define MEMORY_STRUCT_VERSION   2
+
+typedef struct klmembnk_s {			/* MEMORY BANK */
+	klinfo_t 	membnk_info;
+    	short 		membnk_memsz;		/* Total memory in megabytes */
+	short		membnk_dimm_select; /* bank to physical addr mapping*/
+	short		membnk_bnksz[MD_MEM_BANKS]; /* Memory bank sizes */
+	short		membnk_attr;
+} klmembnk_t ;
+
+#define KLCONFIG_MEMBNK_SIZE(_info, _bank)	\
+                            ((_info)->membnk_bnksz[(_bank)])
+
+
+#define MEMBNK_PREMIUM 1
+#define KLCONFIG_MEMBNK_PREMIUM(_info, _bank)	\
+                            ((_info)->membnk_attr & (MEMBNK_PREMIUM << (_bank)))
+
+#define MAX_SERIAL_NUM_SIZE 10
+
+typedef struct klmod_serial_num_s {
+      klinfo_t        snum_info;
+      union {
+              char snum_str[MAX_SERIAL_NUM_SIZE];
+              unsigned long long       snum_int;
+      } snum;
+} klmod_serial_num_t;
+
+/* Macros needed to access serial number structure in lboard_t.
+   Hard coded values are necessary since we cannot treat 
+   serial number struct as a component without losing compatibility
+   between prom versions. */
+
+#define GET_SNUM_COMP(_l) 	((klmod_serial_num_t *)\
+				KLCF_COMP(_l, _l->brd_numcompts))
+
+#define MAX_XBOW_LINKS 16
+
+typedef struct klxbow_s {                          /* XBOW */
+	klinfo_t 	xbow_info ;
+    	klport_t	xbow_port_info[MAX_XBOW_LINKS] ; /* Module number */
+        int		xbow_master_hub_link;
+        /* type of brd connected+component struct ptr+flags */
+} klxbow_t ;
+
+#define MAX_PCI_SLOTS 8
+
+typedef struct klpci_device_s {
+	s32	pci_device_id;	/* 32 bits of vendor/device ID. */
+	s32	pci_device_pad;	/* 32 bits of padding. */
+} klpci_device_t;
+
+#define BRIDGE_STRUCT_VERSION	2
+
+typedef struct klbri_s {                          /* BRIDGE */
+	klinfo_t 	bri_info ;
+    	unsigned char	bri_eprominfo ;    /* IO6prom connected to bridge */
+    	unsigned char	bri_bustype ;      /* PCI/VME BUS bridge/GIO */
+    	pci_t    	pci_specific  ;    /* PCI Board config info */
+	klpci_device_t	bri_devices[MAX_PCI_DEVS] ;	/* PCI IDs */
+	klconf_off_t	bri_mfg_nic ;
+} klbri_t ;
+
+#define MAX_IOC3_TTY	2
+
+typedef struct klioc3_s {                          /* IOC3 */
+	klinfo_t 	ioc3_info ;
+    	unsigned char	ioc3_ssram ;        /* Info about ssram */
+    	unsigned char	ioc3_nvram ;        /* Info about nvram */
+    	klinfo_t	ioc3_superio ;      /* Info about superio */
+	klconf_off_t	ioc3_tty_off ;
+	klinfo_t	ioc3_enet ;
+	klconf_off_t	ioc3_enet_off ;
+	klconf_off_t	ioc3_kbd_off ;
+} klioc3_t ;
+
+#define MAX_VME_SLOTS 8
+
+typedef struct klvmeb_s {                          /* VME BRIDGE - PCI CTLR */
+	klinfo_t 	vmeb_info ;
+	vmeb_t		vmeb_specific ;
+    	klconf_off_t   	vmeb_brdinfo[MAX_VME_SLOTS]   ;    /* VME Board config info */
+} klvmeb_t ;
+
+typedef struct klvmed_s {                          /* VME DEVICE - VME BOARD */
+	klinfo_t	vmed_info ;
+	vmed_t		vmed_specific ;
+    	klconf_off_t   	vmed_brdinfo[MAX_VME_SLOTS]   ;    /* VME Board config info */
+} klvmed_t ;
+
+#define ROUTER_VECTOR_VERS	2
+
+/* XXX - Don't we need the number of ports here?!? */
+typedef struct klrou_s {                          /* ROUTER */
+	klinfo_t 	rou_info ;
+	uint		rou_flags ;           /* PCFG_ROUTER_xxx flags */
+	nic_t		rou_box_nic ;         /* nic of the containing module */
+    	klport_t 	rou_port[MAX_ROUTER_PORTS + 1] ; /* array index 1 to 6 */
+	klconf_off_t	rou_mfg_nic ;     /* MFG NIC string */
+	u64	rou_vector;	  /* vector from master node */
+} klrou_t ;
+
+/*
+ *  Graphics Controller/Device
+ *
+ *  (IP27/IO6) Prom versions 6.13 (and 6.5.1 kernels) and earlier
+ *  used a couple different structures to store graphics information.
+ *  For compatibility reasons, the newer data structure preserves some
+ *  of the layout so that fields that are used in the old versions remain
+ *  in the same place (with the same info).  Determination of what version
+ *  of this structure we have is done by checking the cookie field.
+ */
+#define KLGFX_COOKIE	0x0c0de000
+
+typedef struct klgfx_s {		/* GRAPHICS Device */
+	klinfo_t 	gfx_info;
+	klconf_off_t    old_gndevs;	/* for compatibility with older proms */
+	klconf_off_t    old_gdoff0;	/* for compatibility with older proms */
+	uint		cookie;		/* for compatibility with older proms */
+	uint		moduleslot;
+	struct klgfx_s	*gfx_next_pipe;
+	graphics_t	gfx_specific;
+	klconf_off_t    pad0;		/* for compatibility with older proms */
+	klconf_off_t    gfx_mfg_nic;
+} klgfx_t;
+
+typedef struct klxthd_s {   
+	klinfo_t 	xthd_info ;
+	klconf_off_t	xthd_mfg_nic ;        /* MFG NIC string */
+} klxthd_t ;
+
+typedef struct kltpu_s {                     /* TPU board */
+	klinfo_t 	tpu_info ;
+	klconf_off_t	tpu_mfg_nic ;        /* MFG NIC string */
+} kltpu_t ;
+
+typedef struct klgsn_s {                     /* GSN board */
+	klinfo_t 	gsn_info ;
+	klconf_off_t	gsn_mfg_nic ;        /* MFG NIC string */
+} klgsn_t ;
+
+#define MAX_SCSI_DEVS 16
+
+/*
+ * NOTE: THis is the max sized kl* structure and is used in klmalloc.c
+ * to allocate space of type COMPONENT. Make sure that if the size of
+ * any other component struct becomes more than this, then redefine
+ * that as the size to be klmalloced.
+ */
+
+typedef struct klscsi_s {                          /* SCSI Controller */
+	klinfo_t 	scsi_info ;
+    	scsi_t       	scsi_specific   ; 
+	unsigned char 	scsi_numdevs ;
+	klconf_off_t	scsi_devinfo[MAX_SCSI_DEVS] ; 
+} klscsi_t ;
+
+typedef struct klscdev_s {                          /* SCSI device */
+	klinfo_t 	scdev_info ;
+	struct scsidisk_data *scdev_cfg ; /* driver fills up this */
+} klscdev_t ;
+
+typedef struct klttydev_s {                          /* TTY device */
+	klinfo_t 	ttydev_info ;
+	struct terminal_data *ttydev_cfg ; /* driver fills up this */
+} klttydev_t ;
+
+typedef struct klenetdev_s {                          /* ENET device */
+	klinfo_t 	enetdev_info ;
+	struct net_data *enetdev_cfg ; /* driver fills up this */
+} klenetdev_t ;
+
+typedef struct klkbddev_s {                          /* KBD device */
+	klinfo_t 	kbddev_info ;
+	struct keyboard_data *kbddev_cfg ; /* driver fills up this */
+} klkbddev_t ;
+
+typedef struct klmsdev_s {                          /* mouse device */
+        klinfo_t        msdev_info ;
+        void 		*msdev_cfg ; 
+} klmsdev_t ;
+
+#define MAX_FDDI_DEVS 10 /* XXX Is this true */
+
+typedef struct klfddi_s {                          /* FDDI */
+	klinfo_t 	fddi_info ;
+    	fddi_t        	fddi_specific ;       
+	klconf_off_t	fddi_devinfo[MAX_FDDI_DEVS] ;
+} klfddi_t ;
+
+typedef struct klmio_s {                          /* MIO */
+	klinfo_t 	mio_info ;
+    	mio_t       	mio_specific   ; 
+} klmio_t ;
+
+
+typedef union klcomp_s {
+	klcpu_t		kc_cpu;
+	klhub_t		kc_hub;
+	klmembnk_t 	kc_mem;
+	klxbow_t  	kc_xbow;
+	klbri_t		kc_bri;
+	klioc3_t	kc_ioc3;
+	klvmeb_t	kc_vmeb;
+	klvmed_t	kc_vmed;
+	klrou_t		kc_rou;
+	klgfx_t		kc_gfx;
+	klscsi_t	kc_scsi;
+	klscdev_t	kc_scsi_dev;
+	klfddi_t	kc_fddi;
+	klmio_t		kc_mio;
+	klmod_serial_num_t kc_snum ;
+} klcomp_t;
+
+typedef union kldev_s {      /* for device structure allocation */
+	klscdev_t	kc_scsi_dev ;
+	klttydev_t	kc_tty_dev ;
+	klenetdev_t	kc_enet_dev ;
+	klkbddev_t 	kc_kbd_dev ;
+} kldev_t ;
+
+/* Data structure interface routines. TBD */
+
+/* Include launch info in this file itself? TBD */
+
+/*
+ * TBD - Can the ARCS and device driver related info also be included in the
+ * KLCONFIG area. On the IO4PROM, prom device driver info is part of cfgnode_t 
+ * structure, viz private to the IO4prom.
+ */
+
+/* 
+ * TBD - Allocation issues. 
+ *
+ * Do we need to Mark off sepatate heaps for lboard_t, rboard_t, component, 
+ * errinfo and allocate from them, or have a single heap and allocate all 
+ * structures from it. Debug is easier in the former method since we can
+ * dump all similar structs in one command, but there will be lots of holes, 
+ * in memory and max limits are needed for number of structures.
+ * Another way to make it organized, is to have a union of all components
+ * and allocate a aligned chunk of memory greater than the biggest
+ * component.
+ */
+
+typedef union {
+	lboard_t *lbinfo ;
+} biptr_t ;
+
+
+#define BRI_PER_XBOW 6
+#define PCI_PER_BRI  8
+#define DEV_PER_PCI  16
+
+
+/* Virtual dipswitch values (starting from switch "7"): */
+
+#define VDS_NOGFX		0x8000	/* Don't enable gfx and autoboot */
+#define VDS_NOMP		0x100	/* Don't start slave processors */
+#define VDS_MANUMODE		0x80	/* Manufacturing mode */
+#define VDS_NOARB		0x40	/* No bootmaster arbitration */
+#define VDS_PODMODE		0x20	/* Go straight to POD mode */
+#define VDS_NO_DIAGS		0x10	/* Don't run any diags after BM arb */
+#define VDS_DEFAULTS		0x08	/* Use default environment values */
+#define VDS_NOMEMCLEAR		0x04	/* Don't run mem cfg code */
+#define VDS_2ND_IO4		0x02	/* Boot from the second IO4 */
+#define VDS_DEBUG_PROM		0x01	/* Print PROM debugging messages */
+
+/* external declarations of Linux kernel functions. */
+
+extern lboard_t *find_lboard(unsigned int type);
+
+#endif /* _ASM_SN_KLCONFIG_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/kldir.h linux/include/asm-mips64/sn/kldir.h
--- v2.3.47/linux/include/asm-mips64/sn/kldir.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/kldir.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,217 @@
+/* $Id: kldir.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/kldir.h>, revision 1.21.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SN_KLDIR_H
+#define _ASM_SN_KLDIR_H
+
+/*
+ * The kldir memory area resides at a fixed place in each node's memory and
+ * provides pointers to most other SN0 memory areas.  This allows us to
+ * resize and/or relocate memory areas at a later time without breaking all
+ * firmware and kernels that use them.  Indices in the array are
+ * permanently dedicated to areas listed below.  Some memory areas (marked
+ * below) reside at a permanently fixed location, but are included in the
+ * directory for completeness.
+ */
+
+#define KLDIR_MAGIC		0x434d5f53505f5357
+
+/*
+ * The upper portion of the memory map applies during boot
+ * only and is overwritten by IRIX/SYMMON.
+ *
+ *                                    MEMORY MAP PER NODE
+ *
+ * 0x2000000 (32M)         +-----------------------------------------+
+ *                         |      IO6 BUFFERS FOR FLASH ENET IOC3    |
+ * 0x1F80000 (31.5M)       +-----------------------------------------+
+ *                         |      IO6 TEXT/DATA/BSS/stack            |
+ * 0x1C00000 (30M)         +-----------------------------------------+
+ *                         |      IO6 PROM DEBUG TEXT/DATA/BSS/stack |
+ * 0x0800000 (28M)         +-----------------------------------------+
+ *                         |      IP27 PROM TEXT/DATA/BSS/stack      |
+ * 0x1B00000 (27M)         +-----------------------------------------+
+ *                         |      IP27 CFG                           |
+ * 0x1A00000 (26M)         +-----------------------------------------+
+ *                         |      Graphics PROM                      |
+ * 0x1800000 (24M)         +-----------------------------------------+
+ *                         |      3rd Party PROM drivers             |
+ * 0x1600000 (22M)         +-----------------------------------------+
+ *                         |                                         |
+ *                         |      Free                               |
+ *                         |                                         |
+ *                         +-----------------------------------------+
+ *                         |      UNIX DEBUG Version                 |
+ * 0x190000 (2M--)         +-----------------------------------------+
+ *                         |      SYMMON                             |
+ *                         |      (For UNIX Debug only)              |
+ * 0x34000 (208K)          +-----------------------------------------+
+ *                         |      SYMMON STACK [NUM_CPU_PER_NODE]    |
+ *                         |      (For UNIX Debug only)              |
+ * 0x25000 (148K)          +-----------------------------------------+
+ *                         |      KLCONFIG - II (temp)               |
+ *                         |                                         |
+ *                         |    ----------------------------         |
+ *                         |                                         |
+ *                         |      UNIX NON-DEBUG Version             |
+ * 0x19000 (100K)          +-----------------------------------------+
+ *
+ *
+ * The lower portion of the memory map contains information that is
+ * permanent and is used by the IP27PROM, IO6PROM and IRIX.
+ *
+ * 0x19000 (100K)          +-----------------------------------------+
+ *                         |                                         |
+ *                         |      PI Error Spools (32K)              |
+ *                         |                                         |
+ * 0x12000 (72K)           +-----------------------------------------+
+ *                         |      Unused                             |
+ * 0x11c00 (71K)           +-----------------------------------------+
+ *                         |      CPU 1 NMI Eframe area       	     |
+ * 0x11a00 (70.5K)         +-----------------------------------------+
+ *                         |      CPU 0 NMI Eframe area       	     |
+ * 0x11800 (70K)           +-----------------------------------------+
+ *                         |      CPU 1 NMI Register save area       |
+ * 0x11600 (69.5K)         +-----------------------------------------+
+ *                         |      CPU 0 NMI Register save area       |
+ * 0x11400 (69K)           +-----------------------------------------+
+ *                         |      GDA (1k)                           |
+ * 0x11000 (68K)           +-----------------------------------------+
+ *                         |      Early cache Exception stack        |
+ *                         |             and/or                      |
+ *			   |      kernel/io6prom nmi registers	     |
+ * 0x10800  (66k)	   +-----------------------------------------+
+ *			   |      cache error eframe   	 	     |
+ * 0x10400 (65K)           +-----------------------------------------+
+ *                         |      Exception Handlers (UALIAS copy)   |
+ * 0x10000 (64K)           +-----------------------------------------+
+ *                         |                                         |
+ *                         |                                         |
+ *                         |      KLCONFIG - I (permanent) (48K)     |
+ *                         |                                         |
+ *                         |                                         |
+ *                         |                                         |
+ * 0x4000 (16K)            +-----------------------------------------+
+ *                         |      NMI Handler (Protected Page)       |
+ * 0x3000 (12K)            +-----------------------------------------+
+ *                         |      ARCS PVECTORS (master node only)   |
+ * 0x2c00 (11K)            +-----------------------------------------+
+ *                         |      ARCS TVECTORS (master node only)   |
+ * 0x2800 (10K)            +-----------------------------------------+
+ *                         |      LAUNCH [NUM_CPU]                   |
+ * 0x2400 (9K)             +-----------------------------------------+
+ *                         |      Low memory directory (KLDIR)       |
+ * 0x2000 (8K)             +-----------------------------------------+
+ *                         |      ARCS SPB (1K)                      |
+ * 0x1000 (4K)             +-----------------------------------------+
+ *                         |      Early cache Exception stack        |
+ *                         |             and/or                      |
+ *			   |      kernel/io6prom nmi registers	     |
+ * 0x800  (2k)	           +-----------------------------------------+
+ *			   |      cache error eframe   	 	     |
+ * 0x400 (1K)              +-----------------------------------------+
+ *                         |      Exception Handlers                 |
+ * 0x0   (0K)              +-----------------------------------------+
+ */
+
+#ifdef LANGUAGE_ASSEMBLY
+#define KLDIR_OFF_MAGIC			0x00
+#define KLDIR_OFF_OFFSET		0x08
+#define KLDIR_OFF_POINTER		0x10
+#define KLDIR_OFF_SIZE			0x18
+#define KLDIR_OFF_COUNT			0x20
+#define KLDIR_OFF_STRIDE		0x28
+#endif /* LANGUAGE_ASSEMBLY */
+
+/*
+ * This is defined here because IP27_SYMMON_STK_SIZE must be at least what
+ * we define here.  Since it's set up in the prom.  We can't redefine it later
+ * and expect more space to be allocated.  The way to find out the true size
+ * of the symmon stacks is to divide SYMMON_STK_SIZE by SYMMON_STK_STRIDE
+ * for a particular node.
+ */
+#define SYMMON_STACK_SIZE		0x8000
+
+#if defined (PROM) || defined (SABLE)
+
+/*
+ * These defines are prom version dependent.  No code other than the IP27
+ * prom should attempt to use these values.
+ */
+#define IP27_LAUNCH_OFFSET		0x2400
+#define IP27_LAUNCH_SIZE		0x400
+#define IP27_LAUNCH_COUNT		2
+#define IP27_LAUNCH_STRIDE		0x200
+
+#define IP27_KLCONFIG_OFFSET		0x4000
+#define IP27_KLCONFIG_SIZE		0xc000
+#define IP27_KLCONFIG_COUNT		1
+#define IP27_KLCONFIG_STRIDE		0
+
+#define IP27_NMI_OFFSET			0x3000
+#define IP27_NMI_SIZE			0x40
+#define IP27_NMI_COUNT			2
+#define IP27_NMI_STRIDE			0x40
+
+#define IP27_PI_ERROR_OFFSET		0x12000
+#define IP27_PI_ERROR_SIZE		0x4000
+#define IP27_PI_ERROR_COUNT		1
+#define IP27_PI_ERROR_STRIDE		0
+
+#define IP27_SYMMON_STK_OFFSET		0x25000
+#define IP27_SYMMON_STK_SIZE		0xe000
+#define IP27_SYMMON_STK_COUNT		2
+/* IP27_SYMMON_STK_STRIDE must be >= SYMMON_STACK_SIZE */
+#define IP27_SYMMON_STK_STRIDE		0x7000
+
+#define IP27_FREEMEM_OFFSET		0x19000
+#define IP27_FREEMEM_SIZE		-1
+#define IP27_FREEMEM_COUNT		1
+#define IP27_FREEMEM_STRIDE		0
+
+#endif /* PROM || SABLE*/
+/*
+ * There will be only one of these in a partition so the IO6 must set it up.
+ */
+#define IO6_GDA_OFFSET			0x11000
+#define IO6_GDA_SIZE			0x400
+#define IO6_GDA_COUNT			1
+#define IO6_GDA_STRIDE			0
+
+/*
+ * save area of kernel nmi regs in the prom format
+ */
+#define IP27_NMI_KREGS_OFFSET		0x11400
+#define IP27_NMI_KREGS_CPU_SIZE		0x200
+/*
+ * save area of kernel nmi regs in eframe format 
+ */
+#define IP27_NMI_EFRAME_OFFSET		0x11800
+#define IP27_NMI_EFRAME_SIZE		0x200
+
+#define KLDIR_ENT_SIZE			0x40
+#define KLDIR_MAX_ENTRIES		(0x400 / 0x40)
+
+#ifdef _LANGUAGE_C
+typedef struct kldir_ent_s {
+	u64		magic;		/* Indicates validity of entry      */
+	off_t		offset;		/* Offset from start of node space  */
+	unsigned long	pointer;	/* Pointer to area in some cases    */
+	size_t		size;		/* Size in bytes 		    */
+	u64		count;		/* Repeat count if array, 1 if not  */
+	size_t		stride;		/* Stride if array, 0 if not        */
+	char		rsvd[16];	/* Pad entry to 0x40 bytes          */
+	/* NOTE: These 16 bytes are used in the Partition KLDIR
+	   entry to store partition info. Refer to klpart.h for this. */
+} kldir_ent_t;
+#endif /* _LANGUAGE_C */
+
+#endif /* _ASM_SN_KLDIR_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/sn0/addrs.h linux/include/asm-mips64/sn/sn0/addrs.h
--- v2.3.47/linux/include/asm-mips64/sn/sn0/addrs.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/sn0/addrs.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,377 @@
+/* $Id: addrs.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/addrs.h>, revision 1.126.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SN_SN0_ADDRS_H
+#define _ASM_SN_SN0_ADDRS_H
+
+#include <linux/config.h>
+
+/*
+ * SN0 (on a T5) Address map
+ *
+ * This file contains a set of definitions and macros which are used
+ * to reference into the major address spaces (CAC, HSPEC, IO, MSPEC,
+ * and UNCAC) used by the SN0 architecture.  It also contains addresses
+ * for "major" statically locatable PROM/Kernel data structures, such as
+ * the partition table, the configuration data structure, etc.
+ * We make an implicit assumption that the processor using this file
+ * follows the R10K's provisions for specifying uncached attributes;
+ * should this change, the base registers may very well become processor-
+ * dependent.
+ *
+ * For more information on the address spaces, see the "Local Resources"
+ * chapter of the Hub specification.
+ *
+ * NOTE: This header file is included both by C and by assembler source
+ *	 files.  Please bracket any language-dependent definitions
+ *	 appropriately.
+ */
+
+/*
+ * Some of the macros here need to be casted to appropriate types when used
+ * from C.  They definitely must not be casted from assembly language so we
+ * use some new ANSI preprocessor stuff to paste these on where needed.
+ */
+
+#define CAC_BASE		0xa800000000000000
+
+#define HSPEC_BASE		0x9000000000000000
+#define IO_BASE			0x9200000000000000
+#define MSPEC_BASE		0x9400000000000000
+#define UNCAC_BASE		0x9600000000000000
+
+#define TO_PHYS(x)		(	      ((x) & TO_PHYS_MASK))
+#define TO_CAC(x)		(CAC_BASE   | ((x) & TO_PHYS_MASK))
+#define TO_UNCAC(x)		(UNCAC_BASE | ((x) & TO_PHYS_MASK))
+#define TO_MSPEC(x)		(MSPEC_BASE | ((x) & TO_PHYS_MASK))
+#define TO_HSPEC(x)		(HSPEC_BASE | ((x) & TO_PHYS_MASK))
+
+
+/*
+ * The following couple of definitions will eventually need to be variables,
+ * since the amount of address space assigned to each node depends on
+ * whether the system is running in N-mode (more nodes with less memory)
+ * or M-mode (fewer nodes with more memory).  We expect that it will
+ * be a while before we need to make this decision dynamically, though,
+ * so for now we just use defines bracketed by an ifdef.
+ */
+
+#ifdef CONFIG_SGI_SN0_N_MODE
+
+#define NODE_SIZE_BITS		31
+#define BWIN_SIZE_BITS		28
+
+#define NASID_BITS		9
+#define NASID_BITMASK		(0x1ffLL)
+#define NASID_SHFT		31
+#define NASID_META_BITS		5
+#define NASID_LOCAL_BITS	4
+
+#define BDDIR_UPPER_MASK	(UINT64_CAST 0x7ffff << 10)
+#define BDECC_UPPER_MASK	(UINT64_CAST 0x3ffffff << 3)
+
+#else /* !defined(CONFIG_SGI_SN0_N_MODE), assume that M-mode is desired */
+
+#define NODE_SIZE_BITS		32
+#define BWIN_SIZE_BITS		29
+
+#define NASID_BITMASK		(0xffLL)
+#define NASID_BITS		8
+#define NASID_SHFT		32
+#define NASID_META_BITS		4
+#define NASID_LOCAL_BITS	4
+
+#define BDDIR_UPPER_MASK	(UINT64_CAST 0xfffff << 10)
+#define BDECC_UPPER_MASK	(UINT64_CAST 0x7ffffff << 3)
+
+#endif /* !defined(CONFIG_SGI_SN0_N_MODE) */
+
+#define NODE_ADDRSPACE_SIZE	(UINT64_CAST 1 << NODE_SIZE_BITS)
+
+#define NASID_MASK		(UINT64_CAST NASID_BITMASK << NASID_SHFT)
+#define NASID_GET(_pa)		(int) ((UINT64_CAST (_pa) >>		\
+					NASID_SHFT) & NASID_BITMASK)
+
+#if _LANGUAGE_C && !defined(_STANDALONE)
+#define NODE_SWIN_BASE(nasid, widget)					\
+	((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN)		\
+	: RAW_NODE_SWIN_BASE(nasid, widget))
+#else
+#define NODE_SWIN_BASE(nasid, widget) \
+     (NODE_IO_BASE(nasid) + (UINT64_CAST (widget) << SWIN_SIZE_BITS))
+#endif /* _LANGUAGE_C */
+
+/*
+ * The following definitions pertain to the IO special address
+ * space.  They define the location of the big and little windows
+ * of any given node.
+ */
+
+#define BWIN_INDEX_BITS		3
+#define BWIN_SIZE		(UINT64_CAST 1 << BWIN_SIZE_BITS)
+#define	BWIN_SIZEMASK		(BWIN_SIZE - 1)
+#define	BWIN_WIDGET_MASK	0x7
+#define NODE_BWIN_BASE0(nasid)	(NODE_IO_BASE(nasid) + BWIN_SIZE)
+#define NODE_BWIN_BASE(nasid, bigwin)	(NODE_BWIN_BASE0(nasid) + 	\
+			(UINT64_CAST (bigwin) << BWIN_SIZE_BITS))
+
+#define	BWIN_WIDGETADDR(addr)	((addr) & BWIN_SIZEMASK)
+#define	BWIN_WINDOWNUM(addr)	(((addr) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK)
+/*
+ * Verify if addr belongs to large window address of node with "nasid"
+ *
+ *
+ * NOTE: "addr" is expected to be XKPHYS address, and NOT physical
+ * address
+ *
+ *
+ */
+
+#define	NODE_BWIN_ADDR(nasid, addr)	\
+		(((addr) >= NODE_BWIN_BASE0(nasid)) && \
+		 ((addr) < (NODE_BWIN_BASE(nasid, HUB_NUM_BIG_WINDOW) + \
+				BWIN_SIZE)))
+
+/*
+ * The following define the major position-independent aliases used
+ * in SN0.
+ *	CALIAS -- Varies in size, points to the first n bytes of memory
+ *		  	on the reader's node.
+ */
+
+#define CALIAS_BASE		CAC_BASE
+
+
+
+#define BRIDGE_REG_PTR(_base, _off)	((volatile bridgereg_t *) \
+	((__psunsigned_t)(_base) + (__psunsigned_t)(_off)))
+
+#define SN0_WIDGET_BASE(_nasid, _wid)	(NODE_SWIN_BASE((_nasid), (_wid)))
+
+/* Turn on sable logging for the processors whose bits are set. */
+#ifdef SABLE
+#define SABLE_LOG_TRIGGER(_map)	\
+		*((volatile hubreg_t *)(IO_BASE + 0x17ffff0)) = (_map)
+#else
+#define SABLE_LOG_TRIGGER(_map)
+#endif /* SABLE */
+
+#if _LANGUAGE_C
+#define KERN_NMI_ADDR(nasid, slice)					\
+                    TO_NODE_UNCAC((nasid), IP27_NMI_KREGS_OFFSET + 	\
+				  (IP27_NMI_KREGS_CPU_SIZE * (slice)))
+#endif /* _LANGUAGE_C */
+
+#ifdef PROM
+
+#define MISC_PROM_BASE		PHYS_TO_K0(0x01300000)
+#define MISC_PROM_SIZE		0x200000
+
+#define DIAG_BASE		PHYS_TO_K0(0x01500000)
+#define DIAG_SIZE		0x300000
+
+#define ROUTE_BASE		PHYS_TO_K0(0x01800000)
+#define ROUTE_SIZE		0x200000
+
+#define IP27PROM_FLASH_HDR	PHYS_TO_K0(0x01300000)
+#define IP27PROM_FLASH_DATA	PHYS_TO_K0(0x01301000)
+#define IP27PROM_CORP_MAX	32
+#define IP27PROM_CORP		PHYS_TO_K0(0x01800000)
+#define IP27PROM_CORP_SIZE	0x10000
+#define IP27PROM_CORP_STK	PHYS_TO_K0(0x01810000)
+#define IP27PROM_CORP_STKSIZE	0x2000
+#define IP27PROM_DECOMP_BUF	PHYS_TO_K0(0x01900000)
+#define IP27PROM_DECOMP_SIZE	0xfff00
+
+#define IP27PROM_BASE		PHYS_TO_K0(0x01a00000)
+#define IP27PROM_BASE_MAPPED	(K2BASE | 0x1fc00000)
+#define IP27PROM_SIZE_MAX	0x100000
+
+#define IP27PROM_PCFG		PHYS_TO_K0(0x01b00000)
+#define IP27PROM_PCFG_SIZE	0xd0000
+#define IP27PROM_ERRDMP		PHYS_TO_K1(0x01bd0000)
+#define IP27PROM_ERRDMP_SIZE	0xf000
+
+#define IP27PROM_INIT_START	PHYS_TO_K1(0x01bd0000)
+#define IP27PROM_CONSOLE	PHYS_TO_K1(0x01bdf000)
+#define IP27PROM_CONSOLE_SIZE	0x200
+#define IP27PROM_NETUART	PHYS_TO_K1(0x01bdf200)
+#define IP27PROM_NETUART_SIZE	0x100
+#define IP27PROM_UNUSED1	PHYS_TO_K1(0x01bdf300)
+#define IP27PROM_UNUSED1_SIZE	0x500
+#define IP27PROM_ELSC_BASE_A	PHYS_TO_K0(0x01bdf800)
+#define IP27PROM_ELSC_BASE_B	PHYS_TO_K0(0x01bdfc00)
+#define IP27PROM_STACK_A	PHYS_TO_K0(0x01be0000)
+#define IP27PROM_STACK_B	PHYS_TO_K0(0x01bf0000)
+#define IP27PROM_STACK_SHFT	16
+#define IP27PROM_STACK_SIZE	(1 << IP27PROM_STACK_SHFT)
+#define IP27PROM_INIT_END	PHYS_TO_K0(0x01c00000)
+
+#define SLAVESTACK_BASE		PHYS_TO_K0(0x01580000)
+#define SLAVESTACK_SIZE		0x40000
+
+#define ENETBUFS_BASE		PHYS_TO_K0(0x01f80000)
+#define ENETBUFS_SIZE		0x20000
+
+#define IO6PROM_BASE		PHYS_TO_K0(0x01c00000)
+#define IO6PROM_SIZE		0x400000
+#define	IO6PROM_BASE_MAPPED	(K2BASE | 0x11c00000)
+#define IO6DPROM_BASE		PHYS_TO_K0(0x01c00000)
+#define IO6DPROM_SIZE		0x200000
+
+#define NODEBUGUNIX_ADDR	PHYS_TO_K0(0x00019000)
+#define DEBUGUNIX_ADDR		PHYS_TO_K0(0x00100000)
+
+#define IP27PROM_INT_LAUNCH	10	/* and 11 */
+#define IP27PROM_INT_NETUART	12	/* through 17 */
+
+#endif /* PROM */
+
+/*
+ * needed by symmon so it needs to be outside #if PROM
+ */
+#define IP27PROM_ELSC_SHFT	10
+#define IP27PROM_ELSC_SIZE	(1 << IP27PROM_ELSC_SHFT)
+
+/*
+ * This address is used by IO6PROM to build MemoryDescriptors of
+ * free memory. This address is important since unix gets loaded
+ * at this address, and this memory has to be FREE if unix is to
+ * be loaded.
+ */
+
+#define FREEMEM_BASE		PHYS_TO_K0(0x2000000)
+
+#define IO6PROM_STACK_SHFT	14	/* stack per cpu */
+#define IO6PROM_STACK_SIZE	(1 << IO6PROM_STACK_SHFT)
+
+/*
+ * IP27 PROM vectors
+ */
+
+#define IP27PROM_ENTRY		PHYS_TO_COMPATK1(0x1fc00000)
+#define IP27PROM_RESTART	PHYS_TO_COMPATK1(0x1fc00008)
+#define IP27PROM_SLAVELOOP	PHYS_TO_COMPATK1(0x1fc00010)
+#define IP27PROM_PODMODE	PHYS_TO_COMPATK1(0x1fc00018)
+#define IP27PROM_IOC3UARTPOD	PHYS_TO_COMPATK1(0x1fc00020)
+#define IP27PROM_FLASHLEDS	PHYS_TO_COMPATK1(0x1fc00028)
+#define IP27PROM_REPOD		PHYS_TO_COMPATK1(0x1fc00030)
+#define IP27PROM_LAUNCHSLAVE	PHYS_TO_COMPATK1(0x1fc00038)
+#define IP27PROM_WAITSLAVE	PHYS_TO_COMPATK1(0x1fc00040)
+#define IP27PROM_POLLSLAVE	PHYS_TO_COMPATK1(0x1fc00048)
+
+#define KL_UART_BASE	LOCAL_HUB_ADDR(MD_UREG0_0)	/* base of UART regs */
+#define KL_UART_CMD	LOCAL_HUB_ADDR(MD_UREG0_0)	/* UART command reg */
+#define KL_UART_DATA	LOCAL_HUB_ADDR(MD_UREG0_1)	/* UART data reg */
+#define KL_I2C_REG	MD_UREG0_0			/* I2C reg */
+
+#if !_LANGUAGE_ASSEMBLY
+/* Address 0x400 to 0x1000 ualias points to cache error eframe + misc
+ * CACHE_ERR_SP_PTR could either contain an address to the stack, or
+ * the stack could start at CACHE_ERR_SP_PTR
+ */
+#if defined (HUB_ERR_STS_WAR)
+#define CACHE_ERR_EFRAME	0x480
+#else /* HUB_ERR_STS_WAR */
+#define CACHE_ERR_EFRAME	0x400
+#endif /* HUB_ERR_STS_WAR */
+
+#define CACHE_ERR_ECCFRAME	(CACHE_ERR_EFRAME + EF_SIZE)
+#define CACHE_ERR_SP_PTR	(0x1000 - 32)	/* why -32? TBD */
+#define CACHE_ERR_IBASE_PTR	(0x1000 - 40)
+#define CACHE_ERR_SP		(CACHE_ERR_SP_PTR - 16)
+#define CACHE_ERR_AREA_SIZE	(ARCS_SPB_OFFSET - CACHE_ERR_EFRAME)
+
+#endif	/* !_LANGUAGE_ASSEMBLY */
+
+#define _ARCSPROM
+
+#ifdef _STANDALONE
+
+/*
+ * The PROM needs to pass the device base address and the
+ * device pci cfg space address to the device drivers during
+ * install. The COMPONENT->Key field is used for this purpose.
+ * Macros needed by SN0 device drivers to convert the
+ * COMPONENT->Key field to the respective base address.
+ * Key field looks as follows:
+ *
+ *  +----------------------------------------------------+
+ *  |devnasid | widget  |pciid |hubwidid|hstnasid | adap |
+ *  |   2     |   1     |  1   |   1    |    2    |   1  |
+ *  +----------------------------------------------------+
+ *  |         |         |      |        |         |      |
+ *  64        48        40     32       24        8      0
+ *
+ * These are used by standalone drivers till the io infrastructure
+ * is in place.
+ */
+
+#if _LANGUAGE_C
+
+#define uchar unsigned char
+
+#define KEY_DEVNASID_SHFT  48
+#define KEY_WIDID_SHFT	   40
+#define KEY_PCIID_SHFT	   32
+#define KEY_HUBWID_SHFT	   24
+#define KEY_HSTNASID_SHFT  8
+
+#define MK_SN0_KEY(nasid, widid, pciid) \
+			((((__psunsigned_t)nasid)<< KEY_DEVNASID_SHFT |\
+				((__psunsigned_t)widid) << KEY_WIDID_SHFT) |\
+				((__psunsigned_t)pciid) << KEY_PCIID_SHFT)
+
+#define ADD_HUBWID_KEY(key,hubwid)\
+			(key|=((__psunsigned_t)hubwid << KEY_HUBWID_SHFT))
+
+#define ADD_HSTNASID_KEY(key,hstnasid)\
+			(key|=((__psunsigned_t)hstnasid << KEY_HSTNASID_SHFT))
+
+#define GET_DEVNASID_FROM_KEY(key)	((short)(key >> KEY_DEVNASID_SHFT))
+#define GET_WIDID_FROM_KEY(key)		((uchar)(key >> KEY_WIDID_SHFT))
+#define GET_PCIID_FROM_KEY(key)		((uchar)(key >> KEY_PCIID_SHFT))
+#define GET_HUBWID_FROM_KEY(key)	((uchar)(key >> KEY_HUBWID_SHFT))
+#define GET_HSTNASID_FROM_KEY(key)	((short)(key >> KEY_HSTNASID_SHFT))
+
+#define PCI_64_TARGID_SHFT		60
+
+#define GET_PCIBASE_FROM_KEY(key)  (NODE_SWIN_BASE(GET_DEVNASID_FROM_KEY(key),\
+					GET_WIDID_FROM_KEY(key))\
+					| BRIDGE_DEVIO(GET_PCIID_FROM_KEY(key)))
+
+#define GET_PCICFGBASE_FROM_KEY(key) \
+			(NODE_SWIN_BASE(GET_DEVNASID_FROM_KEY(key),\
+			      GET_WIDID_FROM_KEY(key))\
+			| BRIDGE_TYPE0_CFG_DEV(GET_PCIID_FROM_KEY(key)))
+
+#define GET_WIDBASE_FROM_KEY(key) \
+                        (NODE_SWIN_BASE(GET_DEVNASID_FROM_KEY(key),\
+                              GET_WIDID_FROM_KEY(key)))
+
+#define PUT_INSTALL_STATUS(c,s)		c->Revision = s
+#define GET_INSTALL_STATUS(c)		c->Revision
+
+#endif /* LANGUAGE_C */
+
+#endif /* _STANDALONE */
+
+#if defined (HUB_ERR_STS_WAR)
+
+#define ERR_STS_WAR_REGISTER	IIO_IIBUSERR
+#define ERR_STS_WAR_ADDR	LOCAL_HUB_ADDR(IIO_IIBUSERR)
+#define ERR_STS_WAR_PHYSADDR	TO_PHYS((__psunsigned_t)ERR_STS_WAR_ADDR)
+				/* Used to match addr in error reg. */
+#define OLD_ERR_STS_WAR_OFFSET	((MD_MEM_BANKS * MD_BANK_SIZE) - 0x100)
+
+#endif /* HUB_ERR_STS_WAR */
+
+#endif /* _ASM_SN_SN0_ADDRS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/sn0/arch.h linux/include/asm-mips64/sn/sn0/arch.h
--- v2.3.47/linux/include/asm-mips64/sn/sn0/arch.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/sn0/arch.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,86 @@
+/* $Id: arch.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SGI IP27 specific setup.
+ *
+ * Copyright (C) 1995 - 1997, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_SN_SN0_ARCH_H
+#define _ASM_SN_SN0_ARCH_H
+
+#include <linux/config.h>
+
+#ifndef SABLE
+
+#ifndef SN0XXL  /* 128 cpu SMP max */
+/*
+ * This is the maximum number of nodes that can be part of a kernel.
+ * Effectively, it's the maximum number of compact node ids (cnodeid_t).
+ */
+#define MAX_COMPACT_NODES       64
+
+/*
+ * MAXCPUS refers to the maximum number of CPUs in a single kernel.
+ * This is not necessarily the same as MAXNODES * CPUS_PER_NODE
+ */
+#define MAXCPUS                 128
+
+#else /* SN0XXL system */
+
+#define MAX_COMPACT_NODES       128
+#define MAXCPUS                 256
+
+#endif /* SN0XXL */
+
+/*
+ * This is the maximum number of NASIDS that can be present in a system.
+ * (Highest NASID plus one.)
+ */
+#define MAX_NASIDS		256
+
+/*
+ * MAX_REGIONS refers to the maximum number of hardware partitioned regions.
+ */
+#define	MAX_REGIONS		64
+#define MAX_NONPREMIUM_REGIONS  16
+#define MAX_PREMIUM_REGIONS     MAX_REGIONS
+
+/*
+ * MAX_PARITIONS refers to the maximum number of logically defined 
+ * partitions the system can support.
+ */
+#define MAX_PARTITIONS		MAX_REGIONS
+
+
+#else
+
+#define MAX_COMPACT_NODES	4
+#define MAX_NASIDS		4
+#define MAXCPUS			8
+
+#endif
+
+#define NASID_MASK_BYTES	((MAX_NASIDS + 7) / 8)
+
+/*
+ * Slot constants for SN0
+ */
+#ifdef CONFIG_SGI_SN0_N_MODE
+#define MAX_MEM_SLOTS   16                      /* max slots per node */
+#else /* !CONFIG_SGI_SN0_N_MODE, assume M_MODE */
+#define MAX_MEM_SLOTS   32                      /* max slots per node */
+#endif /* defined(N_MODE) */
+
+#if SABLE_RTL
+#define SLOT_SHIFT      	(28)
+#define SLOT_MIN_MEM_SIZE	(16*1024*1024)
+#else
+#define SLOT_SHIFT      	(27)
+#define SLOT_MIN_MEM_SIZE	(32*1024*1024)
+#endif
+
+#endif /* _ASM_SN_SN0_ARCH_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/sn0/hub.h linux/include/asm-mips64/sn/sn0/hub.h
--- v2.3.47/linux/include/asm-mips64/sn/sn0/hub.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/sn0/hub.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,45 @@
+/* $Id: hub.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SN_SN0_HUB_H
+#define _ASM_SN_SN0_HUB_H
+
+/* The secret password; used to release protection */
+#define HUB_PASSWORD		0x53474972756c6573ull
+
+#define CHIPID_HUB		0
+#define CHIPID_ROUTER		1
+
+#define HUB_REV_1_0		1
+#define HUB_REV_2_0		2
+#define HUB_REV_2_1		3
+#define HUB_REV_2_2		4
+#define HUB_REV_2_3             5
+#define HUB_REV_2_4             6
+
+#define MAX_HUB_PATH		80
+
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubpi.h>
+#include <asm/sn/sn0/hubmd.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/sn0/hubni.h>
+//#include <asm/sn/sn0/hubcore.h>
+
+#ifdef SABLE
+#define IP27_NO_HUBUART_INT	1
+#endif
+
+/* Translation of uncached attributes */
+#define	UATTR_HSPEC	0
+#define	UATTR_IO	1
+#define	UATTR_MSPEC	2
+#define	UATTR_UNCAC	3
+
+#endif /* _ASM_SN_SN0_HUB_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/sn0/hubio.h linux/include/asm-mips64/sn/sn0/hubio.h
--- v2.3.47/linux/include/asm-mips64/sn/sn0/hubio.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/sn0/hubio.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,987 @@
+/* $Id: hubio.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/hubio.h>, Revision 1.80.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef	_ASM_SGI_SN_SN0_HUBIO_H
+#define	_ASM_SGI_SN_SN0_HUBIO_H
+
+/*
+ * Hub I/O interface registers
+ *
+ * All registers in this file are subject to change until Hub chip tapeout.
+ * In general, the longer software name should be used when available.
+ */
+
+/* 
+ * Slightly friendlier names for some common registers.
+ * The hardware definitions follow.
+ */
+#define IIO_WIDGET		IIO_WID      /* Widget identification */
+#define IIO_WIDGET_STAT		IIO_WSTAT    /* Widget status register */
+#define IIO_WIDGET_CTRL		IIO_WCR	     /* Widget control register */
+#define IIO_WIDGET_TOUT		IIO_WRTO     /* Widget request timeout */
+#define IIO_WIDGET_FLUSH	IIO_WTFR     /* Widget target flush */ 
+#define IIO_PROTECT		IIO_ILAPR    /* IO interface protection */
+#define IIO_PROTECT_OVRRD	IIO_ILAPO    /* IO protect override */
+#define IIO_OUTWIDGET_ACCESS	IIO_IOWA     /* Outbound widget access */
+#define IIO_INWIDGET_ACCESS	IIO_IIWA     /* Inbound widget access */
+#define IIO_INDEV_ERR_MASK	IIO_IIDEM    /* Inbound device error mask */
+#define IIO_LLP_CSR		IIO_ILCSR    /* LLP control and status */
+#define IIO_LLP_LOG		IIO_ILLR     /* LLP log */
+#define IIO_XTALKCC_TOUT	IIO_IXCC     /* Xtalk credit count timeout*/
+#define IIO_XTALKTT_TOUT	IIO_IXTT     /* Xtalk tail timeout */
+#define IIO_IO_ERR_CLR		IIO_IECLR    /* IO error clear */
+#define IIO_BTE_CRB_CNT         IIO_IBCN     /* IO BTE CRB count */
+
+#define IIO_LLP_CSR_IS_UP		0x00002000
+#define	IIO_LLP_CSR_LLP_STAT_MASK	0x00003000
+#define	IIO_LLP_CSR_LLP_STAT_SHFT	12
+
+/* key to IIO_PROTECT_OVRRD */
+#define IIO_PROTECT_OVRRD_KEY	0x53474972756c6573ull	/* "SGIrules" */
+
+/* BTE register names */
+#define IIO_BTE_STAT_0		IIO_IBLS_0   /* Also BTE length/status 0 */
+#define IIO_BTE_SRC_0		IIO_IBSA_0   /* Also BTE source address  0 */
+#define IIO_BTE_DEST_0		IIO_IBDA_0   /* Also BTE dest. address 0 */
+#define IIO_BTE_CTRL_0		IIO_IBCT_0   /* Also BTE control/terminate 0 */
+#define IIO_BTE_NOTIFY_0 	IIO_IBNA_0   /* Also BTE notification 0 */
+#define IIO_BTE_INT_0		IIO_IBIA_0   /* Also BTE interrupt 0 */
+#define IIO_BTE_OFF_0		0	     /* Base offset from BTE 0 regs. */
+#define IIO_BTE_OFF_1	IIO_IBLS_1 - IIO_IBLS_0 /* Offset from base to BTE 1 */
+
+/* BTE register offsets from base */
+#define BTEOFF_STAT		0
+#define BTEOFF_SRC		(IIO_BTE_SRC_0 - IIO_BTE_STAT_0)
+#define BTEOFF_DEST		(IIO_BTE_DEST_0 - IIO_BTE_STAT_0)
+#define BTEOFF_CTRL		(IIO_BTE_CTRL_0 - IIO_BTE_STAT_0)
+#define BTEOFF_NOTIFY		(IIO_BTE_NOTIFY_0 - IIO_BTE_STAT_0)
+#define BTEOFF_INT		(IIO_BTE_INT_0 - IIO_BTE_STAT_0)
+
+
+/*
+ * The following definitions use the names defined in the IO interface
+ * document for ease of reference.  When possible, software should 
+ * generally use the the longer but clearer names defined above.
+ */
+
+#define IIO_BASE	0x400000
+#define IIO_BASE_BTE0	0x410000
+#define IIO_BASE_BTE1	0x420000
+#define IIO_BASE_PERF	0x430000
+#define IIO_PERF_CNT	0x430008
+
+#define IO_PERF_SETS	32
+
+#define IIO_WID		0x400000	/* Widget identification */
+#define IIO_WSTAT	0x400008	/* Widget status */
+#define IIO_WCR		0x400020	/* Widget control */
+
+#define	IIO_WSTAT_ECRAZY	(1ULL << 32)	/* Hub gone crazy */
+#define	IIO_WSTAT_TXRETRY	(1ULL << 9)	/* Hub Tx Retry timeout */
+#define	IIO_WSTAT_TXRETRY_MASK	(0x7F)
+#define	IIO_WSTAT_TXRETRY_SHFT	(16)
+#define	IIO_WSTAT_TXRETRY_CNT(w)	(((w) >> IIO_WSTAT_TXRETRY_SHFT) & \
+					  IIO_WSTAT_TXRETRY_MASK)
+
+#define IIO_ILAPR	0x400100	/* Local Access Protection */
+#define IIO_ILAPO	0x400108	/* Protection override */
+#define IIO_IOWA	0x400110	/* outbound widget access */
+#define IIO_IIWA	0x400118	/* inbound widget access */
+#define IIO_IIDEM	0x400120	/* Inbound Device Error Mask */
+#define IIO_ILCSR	0x400128	/* LLP control and status */
+#define IIO_ILLR	0x400130	/* LLP Log */
+#define IIO_IIDSR	0x400138	/* Interrupt destination */
+
+#define IIO_IIBUSERR	0x1400208	/* Reads here cause a bus error. */
+
+/* IO Interrupt Destination Register */
+#define IIO_IIDSR_SENT_SHIFT	28
+#define IIO_IIDSR_SENT_MASK	0x10000000
+#define IIO_IIDSR_ENB_SHIFT	24
+#define IIO_IIDSR_ENB_MASK	0x01000000
+#define IIO_IIDSR_NODE_SHIFT	8
+#define IIO_IIDSR_NODE_MASK	0x0000ff00
+#define IIO_IIDSR_LVL_SHIFT	0
+#define IIO_IIDSR_LVL_MASK	0x0000003f
+
+
+/* GFX Flow Control Node/Widget Register */
+#define IIO_IGFX_0	0x400140	/* gfx node/widget register 0 */
+#define IIO_IGFX_1	0x400148	/* gfx node/widget register 1 */
+#define IIO_IGFX_W_NUM_BITS	4	/* size of widget num field */
+#define IIO_IGFX_W_NUM_MASK	((1<<IIO_IGFX_W_NUM_BITS)-1)
+#define IIO_IGFX_W_NUM_SHIFT	0
+#define IIO_IGFX_N_NUM_BITS	9	/* size of node num field */
+#define IIO_IGFX_N_NUM_MASK	((1<<IIO_IGFX_N_NUM_BITS)-1)
+#define IIO_IGFX_N_NUM_SHIFT	4
+#define IIO_IGFX_P_NUM_BITS	1	/* size of processor num field */
+#define IIO_IGFX_P_NUM_MASK	((1<<IIO_IGFX_P_NUM_BITS)-1)
+#define IIO_IGFX_P_NUM_SHIFT	16
+#define IIO_IGFX_VLD_BITS	1	/* size of valid field */
+#define IIO_IGFX_VLD_MASK	((1<<IIO_IGFX_VLD_BITS)-1)
+#define IIO_IGFX_VLD_SHIFT	20
+#define IIO_IGFX_INIT(widget, node, cpu, valid)				(\
+	(((widget) & IIO_IGFX_W_NUM_MASK) << IIO_IGFX_W_NUM_SHIFT) |	 \
+	(((node)   & IIO_IGFX_N_NUM_MASK) << IIO_IGFX_N_NUM_SHIFT) |	 \
+	(((cpu)    & IIO_IGFX_P_NUM_MASK) << IIO_IGFX_P_NUM_SHIFT) |	 \
+	(((valid)  & IIO_IGFX_VLD_MASK)   << IIO_IGFX_VLD_SHIFT)	 )
+
+/* Scratch registers (not all bits available) */
+#define IIO_SCRATCH_REG0	0x400150
+#define	IIO_SCRATCH_REG1	0x400158
+#define IIO_SCRATCH_MASK	0x0000000f00f11fff
+
+#define IIO_SCRATCH_BIT0_0	0x0000000800000000
+#define IIO_SCRATCH_BIT0_1	0x0000000400000000
+#define IIO_SCRATCH_BIT0_2	0x0000000200000000
+#define IIO_SCRATCH_BIT0_3	0x0000000100000000
+#define IIO_SCRATCH_BIT0_4	0x0000000000800000
+#define IIO_SCRATCH_BIT0_5	0x0000000000400000
+#define IIO_SCRATCH_BIT0_6	0x0000000000200000
+#define IIO_SCRATCH_BIT0_7	0x0000000000100000
+#define IIO_SCRATCH_BIT0_8	0x0000000000010000
+#define IIO_SCRATCH_BIT0_9	0x0000000000001000
+#define IIO_SCRATCH_BIT0_R	0x0000000000000fff
+
+/* IO Translation Table Entries */
+#define IIO_NUM_ITTES	7		/* ITTEs numbered 0..6 */
+					/* Hw manuals number them 1..7! */
+
+/*
+ * As a permanent workaround for a bug in the PI side of the hub, we've
+ * redefined big window 7 as small window 0.
+ */
+#define HUB_NUM_BIG_WINDOW	IIO_NUM_ITTES - 1
+
+/*
+ * Use the top big window as a surrogate for the first small window
+ */
+#define SWIN0_BIGWIN		HUB_NUM_BIG_WINDOW
+
+#define ILCSR_WARM_RESET	0x100
+/*
+ * The IO LLP control status register and widget control register
+ */
+#ifdef _LANGUAGE_C
+
+typedef union hubii_wid_u {
+	u64	wid_reg_value;
+	struct {
+		u64 	wid_rsvd: 	32,	/* unused */
+                   	wid_rev_num:	 4,	/* revision number */
+                   	wid_part_num:	16,	/* the widget type: hub=c101 */
+                   	wid_mfg_num:	11,	/* Manufacturer id (IBM) */
+                   	wid_rsvd1:	 1;	/* Reserved */
+        } wid_fields_s;
+} hubii_wid_t;
+
+
+typedef union hubii_wcr_u {
+	u64	wcr_reg_value;
+	struct {
+		u64 	wcr_rsvd: 	41,	/* unused */
+                   	wcr_e_thresh:	 5,	/* elasticity threshold */
+			wcr_dir_con:	 1,	/* widget direct connect */
+                   	wcr_f_bad_pkt:	 1,	/* Force bad llp pkt enable */
+                   	wcr_xbar_crd:	 3,	/* LLP crossbar credit */
+                   	wcr_rsvd1:	 8,	/* Reserved */
+			wcr_tag_mode:    1,	/* Tag mode */
+                   	wcr_widget_id:	 4;	/* LLP crossbar credit */
+        } wcr_fields_s;
+} hubii_wcr_t;
+
+#define	iwcr_dir_con	wcr_fields_s.wcr_dir_con
+	    
+typedef union hubii_wstat_u {
+	u64      reg_value;
+	struct {
+		u64	rsvd1:		31,
+			crazy:		 1,	/* Crazy bit		*/
+			rsvd2:		 8,
+			llp_tx_cnt:	 8, 	/* LLP Xmit retry counter */
+			rsvd3:		 6,
+			tx_max_rtry:	 1,	/* LLP Retry Timeout Signal */
+			rsvd4:		 2,
+			xt_tail_to:	 1,	/* Xtalk Tail Timeout	*/
+			xt_crd_to:	 1,	/* Xtalk Credit Timeout	*/
+			pending:	 4;	/* Pending Requests	*/
+	} wstat_fields_s;
+} hubii_wstat_t;
+
+		
+typedef union hubii_ilcsr_u {
+	u64	icsr_reg_value;
+	struct {
+		u64 	icsr_rsvd: 	22,	/* unused */
+                   	icsr_max_burst:	10,	/* max burst */
+                        icsr_rsvd4:	 6,	/* reserved */	          
+                   	icsr_max_retry:	10,	/* max retry */
+                        icsr_rsvd3:	 2,	/* reserved */
+                        icsr_lnk_stat:	 2,	/* link status */
+                        icsr_bm8:	 1,	/* Bit mode 8 */
+                        icsr_llp_en:	 1,	/* LLP enable bit */
+                 	icsr_rsvd2:	 1,     /* reserver */
+                        icsr_wrm_reset:	 1,	/* Warm reset bit */
+    			icsr_rsvd1:	 2,	/* Data ready offset */
+                        icsr_null_to:	 6;	/* Null timeout   */
+
+        } icsr_fields_s;
+} hubii_ilcsr_t;
+
+
+typedef union hubii_iowa_u {
+	u64	iowa_reg_value;
+	struct {
+		u64 	iowa_rsvd: 	48,	/* unused */
+                       	iowa_wxoac:	 8,	/* xtalk widget access bits */
+                   	iowa_rsvd1:	 7,	/* xtalk widget access bits */
+                  	iowa_w0oac:	 1;	/* xtalk widget access bits */
+        } iowa_fields_s;
+} hubii_iowa_t;
+
+typedef union hubii_iiwa_u {
+	u64	iiwa_reg_value;
+	struct {
+		u64 	iiwa_rsvd: 	48,	/* unused */
+			iiwa_wxiac:	 8,	/* hub wid access bits */
+			iiwa_rsvd1:	 7,	/* reserved */
+			iiwa_w0iac:	 1;	/* hub wid0 access */
+        } iiwa_fields_s;
+} hubii_iiwa_t;
+
+typedef union	hubii_illr_u {
+	u64	illr_reg_value;
+	struct {
+		u64 	illr_rsvd: 	32,	/* unused */
+			illr_cb_cnt:	16,	/* checkbit error count */
+                   	illr_sn_cnt:	16;	/* sequence number count */
+        } illr_fields_s;
+} hubii_illr_t;
+
+/* The structures below are defined to extract and modify the ii
+performance registers */
+
+/* io_perf_sel allows the caller to specify what tests will be
+   performed */
+typedef union io_perf_sel {
+	u64 perf_sel_reg;
+	struct {
+		u64 	perf_rsvd  : 48,
+		        perf_icct  :  8,
+		        perf_ippr1 :  4,
+  		        perf_ippr0 :  4;
+	} perf_sel_bits;
+} io_perf_sel_t;
+
+/* io_perf_cnt is to extract the count from the hub registers. Due to
+   hardware problems there is only one counter, not two. */
+
+typedef union io_perf_cnt {
+	u64	perf_cnt;
+	struct { 
+		u64	perf_rsvd1 : 32,
+  			        perf_rsvd2 : 12,
+  			        perf_cnt   : 20;
+	} perf_cnt_bits;
+} io_perf_cnt_t;
+
+#endif
+
+
+#define LNK_STAT_WORKING	0x2
+
+#define IIO_LLP_CB_MAX	0xffff
+#define IIO_LLP_SN_MAX	0xffff
+	    
+/* IO PRB Entries */
+#define	IIO_NUM_IPRBS	(9)		
+#define IIO_IOPRB_0	0x400198	/* PRB entry 0 */
+#define IIO_IOPRB_8	0x4001a0	/* PRB entry 8 */
+#define IIO_IOPRB_9	0x4001a8	/* PRB entry 9 */
+#define IIO_IOPRB_A	0x4001b0	/* PRB entry a */
+#define IIO_IOPRB_B	0x4001b8	/* PRB entry b */
+#define IIO_IOPRB_C	0x4001c0	/* PRB entry c */
+#define IIO_IOPRB_D	0x4001c8	/* PRB entry d */
+#define IIO_IOPRB_E	0x4001d0	/* PRB entry e */
+#define IIO_IOPRB_F	0x4001d8	/* PRB entry f */
+
+
+#define IIO_IXCC	0x4001e0	/* Crosstalk credit count timeout */
+#define IIO_IXTCC	IIO_IXCC
+#define IIO_IMEM	0x4001e8	/* Miscellaneous Enable Mask */
+#define IIO_IXTT	0x4001f0	/* Crosstalk tail timeout */
+#define IIO_IECLR	0x4001f8	/* IO error clear */
+#define IIO_IBCN        0x400200        /* IO BTE CRB count */
+
+/* 
+ * IIO_IMEM Register fields.
+ */
+#define IIO_IMEM_W0ESD  0x1             /* Widget 0 shut down due to error */
+#define IIO_IMEM_B0ESD  (1 << 4)        /* BTE 0 shut down due to error */
+#define IIO_IMEM_B1ESD  (1 << 8)        /* BTE 1 Shut down due to error */
+
+/* PIO Read address Table Entries */
+#define IIO_IPCA	0x400300	/* PRB Counter adjust */
+#define IIO_NUM_PRTES	8		/* Total number of PRB table entries */
+#define IIO_PRTE_0	0x400308	/* PIO Read address table entry 0 */
+#define IIO_PRTE(_x)	(IIO_PRTE_0 + (8 * (_x)))
+#define	IIO_WIDPRTE(x)	IIO_PRTE(((x) - 8)) /* widget ID to its PRTE num */
+#define IIO_IPDR	0x400388	/* PIO table entry deallocation */
+#define IIO_ICDR	0x400390	/* CRB Entry Deallocation */
+#define IIO_IFDR	0x400398	/* IOQ FIFO Depth */
+#define IIO_IIAP	0x4003a0	/* IIQ Arbitration Parameters */
+#define IIO_IMMR	IIO_IIAP
+#define IIO_ICMR	0x4003a8	/* CRB Managment Register */
+#define IIO_ICCR	0x4003b0	/* CRB Control Register */
+#define IIO_ICTO	0x4003b8	/* CRB Time Out Register */
+#define IIO_ICTP	0x4003c0	/* CRB Time Out Prescalar */
+
+
+/*
+ * ICMR register fields
+ */
+#define IIO_ICMR_PC_VLD_SHFT	36
+#define IIO_ICMR_PC_VLD_MASK	(0x7fffUL << IIO_ICMR_PC_VLD_SHFT)
+
+#define IIO_ICMR_CRB_VLD_SHFT	20
+#define IIO_ICMR_CRB_VLD_MASK	(0x7fffUL << IIO_ICMR_CRB_VLD_SHFT)
+
+#define IIO_ICMR_FC_CNT_SHFT	16
+#define IIO_ICMR_FC_CNT_MASK	(0xf << IIO_ICMR_FC_CNT_SHFT)
+
+#define IIO_ICMR_C_CNT_SHFT	4
+#define IIO_ICMR_C_CNT_MASK	(0xf << IIO_ICMR_C_CNT_SHFT)
+
+#define IIO_ICMR_P_CNT_SHFT	0
+#define IIO_ICMR_P_CNT_MASK	(0xf << IIO_ICMR_P_CNT_SHFT)
+
+#define IIO_ICMR_PRECISE	(1UL << 52)
+#define IIO_ICMR_CLR_RPPD	(1UL << 13)
+#define IIO_ICMR_CLR_RQPD	(1UL << 12)
+
+/* 
+ * IIO PIO Deallocation register field masks : (IIO_IPDR)
+ */
+#define	IIO_IPDR_PND	(1 << 4)
+
+/*
+ * IIO CRB deallocation register field masks: (IIO_ICDR)
+ */
+#define	IIO_ICDR_PND	(1 << 4)
+
+/*
+ * IIO CRB control register Fields: IIO_ICCR 
+ */
+#define	IIO_ICCR_PENDING	(0x10000)
+#define	IIO_ICCR_CMD_MASK	(0xFF)
+#define	IIO_ICCR_CMD_SHFT	(7)
+#define	IIO_ICCR_CMD_NOP	(0x0)	/* No Op */
+#define	IIO_ICCR_CMD_WAKE	(0x100) /* Reactivate CRB entry and process */
+#define	IIO_ICCR_CMD_TIMEOUT	(0x200)	/* Make CRB timeout & mark invalid */
+#define	IIO_ICCR_CMD_EJECT	(0x400)	/* Contents of entry written to memory 
+					 * via a WB
+					 */
+#define	IIO_ICCR_CMD_FLUSH	(0x800)
+
+/*
+ * CRB manipulation macros
+ *	The CRB macros are slightly complicated, since there are up to
+ * 	four registers associated with each CRB entry.
+ */
+#define IIO_NUM_CRBS		15	/* Number of CRBs */
+#define IIO_NUM_NORMAL_CRBS     12	/* Number of regular CRB entries */
+#define IIO_NUM_PC_CRBS 	4	/* Number of partial cache CRBs */
+#define IIO_ICRB_OFFSET		8
+#define IIO_ICRB_0		0x400400
+/* XXX - This is now tuneable:
+	#define IIO_FIRST_PC_ENTRY 12
+ */
+
+#define IIO_ICRB_A(_x)	(IIO_ICRB_0 + (4 * IIO_ICRB_OFFSET * (_x)))
+#define IIO_ICRB_B(_x)  (IIO_ICRB_A(_x) + 1*IIO_ICRB_OFFSET)
+#define IIO_ICRB_C(_x)	(IIO_ICRB_A(_x) + 2*IIO_ICRB_OFFSET)
+#define IIO_ICRB_D(_x)  (IIO_ICRB_A(_x) + 3*IIO_ICRB_OFFSET)
+
+/* XXX - IBUE register coming for Hub 2 */
+
+/*
+ *
+ * CRB Register description.
+ *
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ *
+ * Many of the fields in CRB are status bits used by hardware
+ * for implementation of the protocol. It's very dangerous to
+ * mess around with the CRB registers. 
+ * 
+ * It's OK to read the CRB registers and try to make sense out of the
+ * fields in CRB. 
+ *
+ * Updating CRB requires all activities in Hub IIO to be quiesced. 
+ * otherwise, a write to CRB could corrupt other CRB entries.
+ * CRBs are here only as a back door peek to hub IIO's status.
+ * Quiescing implies  no dmas no PIOs 
+ * either directly from the cpu or from sn0net.
+ * this is not something that can be done easily. So, AVOID updating
+ * CRBs.
+ */
+
+/*
+ * Fields in CRB Register A
+ */
+#ifdef _LANGUAGE_C
+typedef union icrba_u {
+	u64	reg_value;
+	struct {
+		u64 	resvd: 	6,
+			stall_bte0: 1,	/* Stall BTE 0 */
+			stall_bte1: 1,	/* Stall BTE 1 */
+			error:	1,	/* CRB has an error	*/
+			ecode:	3,	/* Error Code 		*/
+			lnetuce: 1,	/* SN0net Uncorrectable error */
+			mark:	1,	/* CRB Has been marked 	*/
+			xerr:	1,	/* Error bit set in xtalk header */
+			sidn:	4,	/* SIDN field from xtalk	*/
+			tnum: 	5,	/* TNUM field in xtalk		*/
+			addr:	38,	/* Address of request	*/
+			valid:	1,	/* Valid status		*/
+			iow:	1;	/* IO Write operation	*/
+	} icrba_fields_s;
+} icrba_t;
+
+/* This is an alternate typedef for the HUB1 CRB A in order to allow
+   runtime selection of the format based on the REV_ID field of the
+   NI_STATUS_REV_ID register. */
+typedef union h1_icrba_u {
+	u64	reg_value;
+	
+	struct {
+		u64 	resvd: 	6,
+			unused:	1,	/* Unused but RW!!	*/
+			error:	1,	/* CRB has an error	*/
+			ecode:	4,	/* Error Code 		*/
+			lnetuce: 1,	/* SN0net Uncorrectable error */
+			mark:	1,	/* CRB Has been marked 	*/
+			xerr:	1,	/* Error bit set in xtalk header */
+			sidn:	4,	/* SIDN field from xtalk	*/
+			tnum: 	5,	/* TNUM field in xtalk		*/
+			addr:	38,	/* Address of request	*/
+			valid:	1,	/* Valid status		*/
+			iow:	1;	/* IO Write operation	*/
+	} h1_icrba_fields_s;
+} h1_icrba_t;
+
+/* XXX - Is this still right?  Check the spec. */
+#define ICRBN_A_CERR_SHFT	54
+#define ICRBN_A_ERR_MASK	0x3ff
+
+/*
+ * Easy access macros.
+ */
+#define	a_error		icrba_fields_s.error
+#define	a_ecode		icrba_fields_s.ecode
+#define	a_lnetuce	icrba_fields_s.lnetuce
+#define	a_mark		icrba_fields_s.mark
+#define	a_xerr		icrba_fields_s.xerr
+#define	a_sidn		icrba_fields_s.sidn
+#define	a_tnum		icrba_fields_s.tnum
+#define	a_addr		icrba_fields_s.addr
+#define	a_valid		icrba_fields_s.valid
+#define	a_iow		icrba_fields_s.iow
+
+#endif /* LANGUAGE_C */
+
+#define	IIO_ICRB_ADDR_SHFT	2	/* Shift to get proper address */
+
+/*
+ * values for "ecode" field 
+ */
+#define	IIO_ICRB_ECODE_DERR	0	/* Directory error due to IIO access */
+#define	IIO_ICRB_ECODE_PERR	1	/* Poison error on IO access */
+#define	IIO_ICRB_ECODE_WERR	2	/* Write error by IIO access 
+					 * e.g. WINV to a Read only line.
+					 */
+#define	IIO_ICRB_ECODE_AERR	3	/* Access error caused by IIO access */
+#define	IIO_ICRB_ECODE_PWERR	4	/* Error on partial write	*/
+#define	IIO_ICRB_ECODE_PRERR	5	/* Error on partial read	*/
+#define	IIO_ICRB_ECODE_TOUT	6	/* CRB timeout before deallocating */
+#define	IIO_ICRB_ECODE_XTERR	7	/* Incoming xtalk pkt had error bit */
+
+
+
+/*
+ * Fields in CRB Register B
+ */
+#ifdef _LANGUAGE_C
+typedef union icrbb_u {
+	u64	reg_value;
+	struct {
+	    u64	rsvd1:	5,
+		btenum:	1,	/* BTE to which entry belongs to */
+		cohtrans: 1,	/* Coherent transaction	*/
+		xtsize:	2,	/* Xtalk operation size
+				 * 0: Double Word
+				 * 1: 32 Bytes.
+				 * 2: 128 Bytes,
+				 * 3: Reserved.
+				 */
+		srcnode: 9,	/* Source Node ID		*/
+		srcinit: 2,	/* Source Initiator: 
+				 * See below for field values.
+				 */
+		useold:	1,	/* Use OLD command for processing */
+		imsgtype: 2,	/* Incoming message type
+				 * see below for field values 
+				 */
+		imsg: 	8,	/* Incoming message 	*/
+		initator: 3,	/* Initiator of original request 
+				 * See below for field values.
+				 */
+		reqtype: 5,	/* Identifies type of request
+				 * See below for field values.
+				 */
+		rsvd2:	7,
+		ackcnt:	11,	/* Invalidate ack count	*/
+		resp:	1,	/* data response  given to processor */
+		ack: 	1,	/* indicates data ack received 	*/
+		hold:	1,	/* entry is gathering inval acks */
+		wb_pend:1,	/* waiting for writeback to complete */
+		intvn: 	1,	/* Intervention */
+		stall_ib: 1,	/* Stall Ibuf (from crosstalk) */
+		stall_intr: 1;	/* Stall internal interrupts */
+	} icrbb_field_s;
+} icrbb_t;
+
+/* This is an alternate typedef for the HUB1 CRB B in order to allow
+   runtime selection of the format based on the REV_ID field of the
+   NI_STATUS_REV_ID register. */
+typedef union h1_icrbb_u {
+	u64	reg_value;
+	struct {
+		u64	rsvd1:	5,
+			btenum:	1,	/* BTE to which entry belongs to */
+			cohtrans: 1,	/* Coherent transaction	*/
+			xtsize:	2,	/* Xtalk operation size
+					 * 0: Double Word
+					 * 1: 32 Bytes.
+					 * 2: 128 Bytes,
+					 * 3: Reserved.
+					 */
+			srcnode: 9,	/* Source Node ID		*/
+			srcinit: 2,	/* Source Initiator: 
+					 * See below for field values.
+					 */
+			useold:	1,	/* Use OLD command for processing */
+			imsgtype: 2,	/* Incoming message type
+					 * see below for field values 
+					 */
+			imsg: 	8,	/* Incoming message 	*/
+			initator: 3,	/* Initiator of original request 
+					 * See below for field values.
+					 */
+			rsvd2: 	1,	
+			pcache: 1,	/* entry belongs to partial cache */
+			reqtype: 5,	/* Identifies type of request
+					 * See below for field values.
+					 */
+			stl_ib:	1,	/* stall Ibus coming from xtalk	*/
+			stl_intr: 1,	/* Stall internal interrupts */
+			stl_bte0: 1,	/* Stall BTE 0 	*/
+			stl_bte1: 1,	/* Stall BTE 1	*/
+			intrvn:	1,	/* Req was target of intervention */
+			ackcnt:	11,	/* Invalidate ack count	*/
+			resp:	1,	/* data response  given to processor */
+			ack: 	1,	/* indicates data ack received 	*/
+			hold:	1,	/* entry is gathering inval acks */
+			wb_pend:1,	/* waiting for writeback to complete */
+			sleep: 	1,	/* xtalk req sleeping till IO-sync */
+			pnd_reply: 1,	/* replies not issed due to IOQ full */
+			pnd_req: 1;	/* reqs not issued due to IOQ full */
+	} h1_icrbb_field_s;
+} h1_icrbb_t;
+
+
+#define	b_imsgtype	icrbb_field_s.imsgtype
+#define	b_btenum	icrbb_field_s.btenum
+#define	b_cohtrans	icrbb_field_s.cohtrans
+#define	b_xtsize	icrbb_field_s.xtsize
+#define	b_srcnode	icrbb_field_s.srcnode
+#define	b_srcinit	icrbb_field_s.srcinit
+#define	b_imsgtype	icrbb_field_s.imsgtype
+#define	b_imsg		icrbb_field_s.imsg
+#define	b_initiator	icrbb_field_s.initiator
+
+#endif /* LANGUAGE_C */
+
+/*
+ * values for field xtsize
+ */
+#define	IIO_ICRB_XTSIZE_DW	0	/* Xtalk operation size is 8 bytes  */
+#define	IIO_ICRB_XTSIZE_32	1	/* Xtalk operation size is 32 bytes */
+#define	IIO_ICRB_XTSIZE_128	2	/* Xtalk operation size is 128 bytes */
+
+/*
+ * values for field srcinit
+ */
+#define	IIO_ICRB_PROC0		0	/* Source of request is Proc 0 */
+#define	IIO_ICRB_PROC1		1	/* Source of request is Proc 1 */
+#define	IIO_ICRB_GB_REQ		2	/* Source is Guranteed BW request */
+#define	IIO_ICRB_IO_REQ		3	/* Source is Normal IO request	*/
+
+/*
+ * Values for field imsgtype
+ */
+#define	IIO_ICRB_IMSGT_XTALK	0	/* Incoming Meessage from Xtalk	*/
+#define	IIO_ICRB_IMSGT_BTE	1	/* Incoming message from BTE 	*/
+#define	IIO_ICRB_IMSGT_SN0NET	2	/* Incoming message from SN0 net */
+#define	IIO_ICRB_IMSGT_CRB	3	/* Incoming message from CRB ???  */
+
+/*
+ * values for field initiator.
+ */
+#define	IIO_ICRB_INIT_XTALK	0	/* Message originated in xtalk	*/
+#define	IIO_ICRB_INIT_BTE0	0x1	/* Message originated in BTE 0	*/
+#define	IIO_ICRB_INIT_SN0NET	0x2	/* Message originated in SN0net */
+#define	IIO_ICRB_INIT_CRB	0x3	/* Message originated in CRB ? 	*/
+#define	IIO_ICRB_INIT_BTE1	0x5	/* MEssage originated in BTE 1	*/
+
+/*
+ * Values for field reqtype.
+ */
+/* XXX - Need to fix this for Hub 2 */
+#define	IIO_ICRB_REQ_DWRD	0	/* Request type double word	*/
+#define	IIO_ICRB_REQ_QCLRD	1	/* Request is Qrtr Caceh line Rd */
+#define	IIO_ICRB_REQ_BLKRD	2	/* Request is block read	*/
+#define	IIO_ICRB_REQ_RSHU	6	/* Request is BTE block read	*/
+#define	IIO_ICRB_REQ_REXU	7	/* request is BTE Excl Read	*/
+#define	IIO_ICRB_REQ_RDEX	8	/* Request is Read Exclusive	*/
+#define	IIO_ICRB_REQ_WINC	9	/* Request is Write Invalidate 	*/
+#define	IIO_ICRB_REQ_BWINV	10	/* Request is BTE Winv		*/
+#define	IIO_ICRB_REQ_PIORD	11	/* Request is PIO read		*/
+#define	IIO_ICRB_REQ_PIOWR	12	/* Request is PIO Write 	*/
+#define	IIO_ICRB_REQ_PRDM	13	/* Request is Fetch&Op		*/
+#define	IIO_ICRB_REQ_PWRM	14	/* Request is Store &Op		*/
+#define	IIO_ICRB_REQ_PTPWR	15	/* Request is Peer to peer	*/
+#define	IIO_ICRB_REQ_WB		16	/* Request is Write back	*/
+#define	IIO_ICRB_REQ_DEX	17	/* Retained DEX Cache line	*/
+
+/* 
+ * Fields in CRB Register C 
+ */
+
+#ifdef _LANGUAGE_C
+
+typedef union icrbc_s {
+	u64	reg_value;
+	struct {
+		u64	rsvd:	6,
+			sleep:	1,
+			pricnt: 4,	/* Priority count sent with Read req */
+			pripsc: 4,	/* Priority Pre scalar 	*/
+			bteop:	1,	/* BTE Operation 	*/
+			push_be: 34,	/* Push address Byte enable 
+					 * Holds push addr, if CRB is for BTE
+					 * If CRB belongs to Partial cache,
+					 * this contains byte enables bits
+					 * ([47:46] = 0)
+					 */
+			suppl:	11,	/* Supplemental field	*/
+			barrop: 1,	/* Barrier Op bit set in xtalk req */
+			doresp: 1,	/* Xtalk req needs a response 	*/
+			gbr:	1;	/* GBR bit set in xtalk packet 	*/
+	} icrbc_field_s;
+} icrbc_t;
+
+#define	c_pricnt	icrbc_field_s.pricnt
+#define	c_pripsc	icrbc_field_s.pripsc
+#define	c_bteop		icrbc_field_s.bteop
+#define	c_bteaddr	icrbc_field_s.push_be	/* push_be field has 2 names */
+#define c_benable 	icrbc_field_s.push_be	/* push_be field has 2 names */
+#define	c_suppl		icrbc_field_s.suppl
+#define	c_barrop	icrbc_field_s.barrop
+#define	c_doresp	icrbc_field_s.doresp
+#define	c_gbr	icrbc_field_s.gbr
+#endif /* LANGUAGE_C */
+
+/*
+ * Fields in CRB Register D
+ */
+
+#ifdef _LANGUAGE_C
+typedef union icrbd_s {
+	u64	reg_value;
+	struct {
+	    u64	rsvd:	38,
+		toutvld: 1,	/* Timeout in progress for this CRB */
+		ctxtvld: 1,	/* Context field below is valid	*/
+		rsvd2:	1,	
+		context: 15, 	/* Bit vector:
+				 * Has a bit set for each CRB entry
+				 * which needs to be deallocated
+				 * before this CRB entry is processed.
+				 * Set only for barrier operations.
+				 */
+		timeout: 8;	/* Timeout Upper 8 bits	*/
+	} icrbd_field_s;
+} icrbd_t;
+
+#define	icrbd_toutvld	icrbd_field_s.toutvld
+#define	icrbd_ctxtvld	icrbd_field_s.ctxtvld
+#define	icrbd_context	icrbd_field_s.context
+
+
+typedef union hubii_ifdr_u {
+	u64	hi_ifdr_value;
+	struct {
+		u64	ifdr_rsvd:	49,
+	                ifdr_maxrp:	 7,
+	                ifdr_rsvd1:	 1,
+                      	ifdr_maxrq:	 7;
+	} hi_ifdr_fields;
+} hubii_ifdr_t;
+
+#endif /* LANGUAGE_C */
+
+/*
+ * Hardware designed names for the BTE control registers.
+ */
+#define IIO_IBLS_0	0x410000	/* BTE length/status 0 */
+#define IIO_IBSA_0	0x410008	/* BTE source address 0 */
+#define IIO_IBDA_0	0x410010	/* BTE destination address 0 */
+#define IIO_IBCT_0	0x410018	/* BTE control/terminate 0 */
+#define IIO_IBNA_0	0x410020	/* BTE notification address 0 */
+#define IIO_IBNR_0	IIO_IBNA_0
+#define IIO_IBIA_0	0x410028	/* BTE interrupt address 0 */	
+
+#define IIO_IBLS_1	0x420000	/* BTE length/status 1 */
+#define IIO_IBSA_1	0x420008	/* BTE source address 1 */
+#define IIO_IBDA_1	0x420010	/* BTE destination address 1 */
+#define IIO_IBCT_1	0x420018	/* BTE control/terminate 1 */
+#define IIO_IBNA_1	0x420020	/* BTE notification address 1 */
+#define IIO_IBNR_1	IIO_IBNA_1
+#define IIO_IBIA_1	0x420028	/* BTE interrupt address 1 */	
+
+/*
+ * More miscellaneous registers
+ */
+#define IIO_IPCR	0x430000	/* Performance Control */
+#define IIO_IPPR	0x430008	/* Performance Profiling */
+
+/*
+ * IO Error Clear register bit field definitions
+ */
+#define IECLR_BTE1		(1 << 18)  /* clear bte error 1 ??? */
+#define IECLR_BTE0		(1 << 17)  /* clear bte error 0 ??? */
+#define IECLR_CRAZY		(1 << 16)  /* clear crazy bit in wstat reg */
+#define IECLR_PRB_F		(1 << 15)  /* clear err bit in PRB_F reg */
+#define IECLR_PRB_E		(1 << 14)  /* clear err bit in PRB_E reg */
+#define IECLR_PRB_D		(1 << 13)  /* clear err bit in PRB_D reg */
+#define IECLR_PRB_C		(1 << 12)  /* clear err bit in PRB_C reg */
+#define IECLR_PRB_B		(1 << 11)  /* clear err bit in PRB_B reg */
+#define IECLR_PRB_A		(1 << 10)  /* clear err bit in PRB_A reg */
+#define IECLR_PRB_9		(1 << 9)   /* clear err bit in PRB_9 reg */
+#define IECLR_PRB_8		(1 << 8)   /* clear err bit in PRB_8 reg */
+#define IECLR_PRB_0		(1 << 0)   /* clear err bit in PRB_0 reg */
+
+/*
+ * IO PIO Read Table Entry format 
+ */
+
+#ifdef	_LANGUAGE_C
+
+typedef union iprte_a {
+	u64	entry;
+	struct {
+	    u64	rsvd1     : 7,  /* Reserved field 		*/
+		valid     : 1,	/* Maps to a timeout entry	*/
+		rsvd2     : 1,
+		srcnode   : 9,	/* Node which did this PIO	*/
+		initiator : 2,	/* If T5A or T5B or IO 		*/
+		rsvd3     : 3,
+		addr      : 38,	/* Physical address of PIO	*/
+		rsvd4     : 3;
+	} iprte_fields;
+} iprte_a_t;
+
+#define	iprte_valid	iprte_fields.valid
+#define	iprte_timeout	iprte_fields.timeout
+#define	iprte_srcnode	iprte_fields.srcnode
+#define	iprte_init	iprte_fields.initiator
+#define	iprte_addr	iprte_fields.addr
+
+#endif /* _LANGUAGE_C */
+
+#define	IPRTE_ADDRSHFT	3
+
+/*
+ * Hub IIO PRB Register format.
+ */
+
+#ifdef	_LANGUAGE_C
+/*
+ * Note: Fields bnakctr, anakctr, xtalkctrmode, ovflow fields are 
+ * "Status" fields, and should only be used in case of clean up after errors.
+ */
+
+typedef union iprb_u {
+	u64	reg_value;
+	struct {
+	    u64	rsvd1:	15,
+		error:	1,	/* Widget rcvd wr resp pkt w/ error */
+		ovflow:	5,	/* Over flow count. perf measurement */
+		fire_and_forget: 1, /* Launch Write without response */
+		mode:	2,	/* Widget operation Mode	*/
+		rsvd2:	2,
+		bnakctr: 14,
+		rsvd3: 	2,
+		anakctr: 14,
+		xtalkctr: 8;
+	} iprb_fields_s;
+} iprb_t;
+
+#define iprb_regval	reg_value
+
+#define	iprb_error	iprb_fields_s.error
+#define	iprb_ovflow	iprb_fields_s.ovflow
+#define	iprb_ff		iprb_fields_s.fire_and_forget
+#define	iprb_mode	iprb_fields_s.mode
+#define	iprb_bnakctr	iprb_fields_s.bnakctr
+#define	iprb_anakctr	iprb_fields_s.anakctr
+#define	iprb_xtalkctr	iprb_fields_s.xtalkctr
+
+#endif	/* _LANGUAGE_C */
+
+/*
+ * values for mode field in iprb_t.
+ * For details of the meanings of NAK and Accept, refer the PIO flow
+ * document
+ */
+#define	IPRB_MODE_NORMAL	(0)
+#define	IPRB_MODE_COLLECT_A	(1)	/* PRB in collect A mode */
+#define	IPRB_MODE_SERVICE_A	(2)	/* NAK B and Accept A */
+#define	IPRB_MODE_SERVICE_B	(3)	/* NAK A and Accept B */
+
+/*
+ * IO CRB entry C_A to E_A : Partial (cache) CRBS
+ */
+#ifdef _LANGUAGE_C
+typedef union icrbp_a {
+	u64   ip_reg;	    /* the entire register value	*/
+	struct {
+	     u64 error:	1,  /*    63, error occurred		*/
+		ln_uce:	1,  /*    62: uncorrectable memory 	*/
+		ln_ae:	1,  /*    61: protection violation 	*/
+		ln_werr:1,  /*    60: write access error 	*/
+		ln_aerr:1,  /*    59: sn0net: Address error	*/
+		ln_perr:1,  /*    58: sn0net: poison error	*/
+		timeout:1,  /*    57: CRB timed out		*/
+		l_bdpkt:1,  /*    56: truncated pkt on sn0net	*/
+		c_bdpkt:1,  /*    55: truncated pkt on xtalk	*/
+		c_err:	1,  /*    54: incoming xtalk req, err set*/
+		rsvd1: 12,  /* 53-42: reserved			*/
+		valid:	1,  /*    41: Valid status		*/
+		sidn:	4,  /* 40-37: SIDN field of xtalk rqst	*/
+		tnum:	5,  /* 36-32: TNUM of xtalk request	*/
+		bo:	1,  /*    31: barrier op set in xtalk rqst*/
+		resprqd:1,  /*    30: xtalk rqst requires response*/
+		gbr:	1,  /*    29: gbr bit set in xtalk rqst	*/
+		size:	2,  /* 28-27: size of xtalk request	*/
+		excl:	4,  /* 26-23: exclusive bit(s)		*/
+		stall:	3,  /* 22-20: stall (xtalk, bte 0/1)	*/
+		intvn:	1,  /*    19: rqst target of intervention*/
+		resp:	1,  /*    18: Data response given to t5	*/
+		ack:	1,  /*    17: Data ack received.	*/
+		hold:	1,  /*    16: crb gathering invalidate acks*/
+		wb:	1,  /*    15: writeback pending.	*/
+		ack_cnt:11, /* 14-04: counter of invalidate acks*/
+		tscaler:4;  /* 03-00: Timeout prescaler		*/
+	} ip_fmt;
+} icrbp_a_t;
+
+#endif /* _LANGUAGE_C */
+
+/*
+ * A couple of defines to go with the above structure.
+ */
+#define ICRBP_A_CERR_SHFT	54
+#define ICRBP_A_ERR_MASK	0x3ff
+
+#ifdef _LANGUAGE_C
+typedef union hubii_idsr {
+	u64 iin_reg;
+	struct {
+		u64 rsvd1 : 35,
+	            isent : 1,
+	            rsvd2 : 3,
+	            ienable: 1,
+	            rsvd  : 7,
+	            node  : 9,
+	            rsvd4 : 1,
+	            level : 7;
+	} iin_fmt;
+} hubii_idsr_t;
+#endif /* LANGUAGE_C */
+	
+/* 
+ * IO BTE Length/Status (IIO_IBLS) register bit field definitions
+ */
+#define IBLS_BUSY		(0x1 << 20)
+#define IBLS_ERROR_SHFT		16
+#define IBLS_ERROR		(0x1 << IBLS_ERROR_SHFT)
+#define IBLS_LENGTH_MASK	0xffff
+
+/*
+ * IO BTE Control/Terminate register (IBCT) register bit field definitions
+ */
+#define IBCT_POISON		(0x1 << 8)
+#define IBCT_NOTIFY		(0x1 << 4)
+#define IBCT_ZFIL_MODE		(0x1 << 0)
+
+/*
+ * IO BTE Interrupt Address Register (IBIA) register bit field definitions
+ */
+#define IBIA_LEVEL_SHFT		16
+#define IBIA_LEVEL_MASK		(0x7f << IBIA_LEVEL_SHFT)
+#define IBIA_NODE_ID_SHFT	0
+#define IBIA_NODE_ID_MASK	(0x1ff)
+
+/*
+ * Miscellaneous hub constants
+ */
+
+/* Number of widgets supported by hub */
+#define HUB_NUM_WIDGET		9
+#define HUB_WIDGET_ID_MIN	0x8
+#define HUB_WIDGET_ID_MAX	0xf
+
+#define HUB_WIDGET_PART_NUM	0xc101	
+#define MAX_HUBS_PER_XBOW	2
+
+/* 
+ * Get a hub's widget id from widget control register 
+ */
+#define IIO_WCR_WID_GET(nasid)	(REMOTE_HUB_L(nasid, III_WCR) & 0xf) 
+#define IIO_WST_ERROR_MASK	(UINT64_CAST 1 << 32) /* Widget status error */
+
+/*
+ * Number of credits Hub widget has while sending req/response to
+ * xbow. 
+ * Value of 3 is required by Xbow 1.1
+ * We may be able to increase this to 4 with Xbow 1.2.
+ */
+#define       HUBII_XBOW_CREDIT       3
+#define	      HUBII_XBOW_REV2_CREDIT  4
+
+#endif /* _ASM_SGI_SN_SN0_HUBIO_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/sn0/hubmd.h linux/include/asm-mips64/sn/sn0/hubmd.h
--- v2.3.47/linux/include/asm-mips64/sn/sn0/hubmd.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/sn0/hubmd.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,792 @@
+/* $Id: hubmd.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/hubmd.h>, revision 1.59.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef	_ASM_SN_SN0_HUBMD_H
+#define	_ASM_SN_SN0_HUBMD_H
+
+/*
+ * Hub Memory/Directory interface registers
+ */
+#define CACHE_SLINE_SIZE        128	/* Secondary cache line size on SN0 */
+
+#define	MAX_REGIONS		64
+
+/* Hardware page size and shift */
+
+#define MD_PAGE_SIZE		4096	 /* Page size in bytes		    */
+#define MD_PAGE_NUM_SHFT	12	 /* Address to page number shift    */
+
+/* Register offsets from LOCAL_HUB or REMOTE_HUB */
+
+#define MD_BASE			0x200000
+#define MD_BASE_PERF		0x210000
+#define MD_BASE_JUNK		0x220000
+
+#define MD_IO_PROTECT		0x200000 /* MD and core register protection */
+#define MD_IO_PROT_OVRRD	0x200008 /* Clear my bit in MD_IO_PROTECT   */
+#define MD_HSPEC_PROTECT	0x200010 /* BDDIR, LBOOT, RBOOT protection  */
+#define MD_MEMORY_CONFIG	0x200018 /* Memory/Directory DIMM control   */
+#define	MD_REFRESH_CONTROL	0x200020 /* Memory/Directory refresh ctrl   */
+#define	MD_FANDOP_CAC_STAT	0x200028 /* Fetch-and-op cache status 	    */
+#define	MD_MIG_DIFF_THRESH	0x200030 /* Page migr. count diff thresh.   */
+#define	MD_MIG_VALUE_THRESH	0x200038 /* Page migr. count abs. thresh.   */
+#define	MD_MIG_CANDIDATE	0x200040 /* Latest page migration candidate */
+#define	MD_MIG_CANDIDATE_CLR	0x200048 /* Clear page migration candidate  */
+#define MD_DIR_ERROR		0x200050 /* Directory DIMM error 	    */
+#define MD_DIR_ERROR_CLR	0x200058 /* Directory DIMM error clear 	    */
+#define MD_PROTOCOL_ERROR	0x200060 /* Directory protocol error 	    */
+#define MD_PROTOCOL_ERROR_CLR	0x200068 /* Directory protocol error clear  */
+#define MD_MEM_ERROR		0x200070 /* Memory DIMM error 		    */
+#define MD_MEM_ERROR_CLR	0x200078 /* Memory DIMM error clear 	    */
+#define MD_MISC_ERROR		0x200080 /* Miscellaneous MD error 	    */
+#define MD_MISC_ERROR_CLR	0x200088 /* Miscellaneous MD error clear    */
+#define MD_MEM_DIMM_INIT	0x200090 /* Memory DIMM mode initization.   */
+#define MD_DIR_DIMM_INIT	0x200098 /* Directory DIMM mode init. 	    */
+#define MD_MOQ_SIZE		0x2000a0 /* MD outgoing queue size 	    */
+#define MD_MLAN_CTL		0x2000a8 /* NIC (Microlan) control register */
+
+#define MD_PERF_SEL		0x210000 /* Select perf monitor events 	    */
+#define MD_PERF_CNT0		0x210010 /* Performance counter 0 	    */
+#define MD_PERF_CNT1		0x210018 /* Performance counter 1 	    */
+#define MD_PERF_CNT2		0x210020 /* Performance counter 2 	    */
+#define MD_PERF_CNT3		0x210028 /* Performance counter 3 	    */
+#define MD_PERF_CNT4		0x210030 /* Performance counter 4 	    */
+#define MD_PERF_CNT5		0x210038 /* Performance counter 5 	    */
+
+#define MD_UREG0_0		0x220000 /* uController/UART 0 register     */
+#define MD_UREG0_1		0x220008 /* uController/UART 0 register     */
+#define MD_UREG0_2		0x220010 /* uController/UART 0 register     */
+#define MD_UREG0_3		0x220018 /* uController/UART 0 register     */
+#define MD_UREG0_4		0x220020 /* uController/UART 0 register     */
+#define MD_UREG0_5		0x220028 /* uController/UART 0 register     */
+#define MD_UREG0_6		0x220030 /* uController/UART 0 register     */
+#define MD_UREG0_7		0x220038 /* uController/UART 0 register     */
+
+#define MD_SLOTID_USTAT		0x220048 /* Hub slot ID & UART/uCtlr status */
+#define MD_LED0			0x220050 /* Eight-bit LED for CPU A 	    */
+#define MD_LED1			0x220058 /* Eight-bit LED for CPU B 	    */
+
+#define MD_UREG1_0		0x220080 /* uController/UART 1 register     */
+#define MD_UREG1_1		0x220088 /* uController/UART 1 register     */
+#define MD_UREG1_2		0x220090 /* uController/UART 1 register     */
+#define MD_UREG1_3		0x220098 /* uController/UART 1 register     */
+#define MD_UREG1_4		0x2200a0 /* uController/UART 1 register     */
+#define MD_UREG1_5		0x2200a8 /* uController/UART 1 register     */
+#define MD_UREG1_6		0x2200b0 /* uController/UART 1 register     */
+#define MD_UREG1_7		0x2200b8 /* uController/UART 1 register     */
+#define MD_UREG1_8		0x2200c0 /* uController/UART 1 register     */
+#define MD_UREG1_9		0x2200c8 /* uController/UART 1 register     */
+#define MD_UREG1_10		0x2200d0 /* uController/UART 1 register     */
+#define MD_UREG1_11		0x2200d8 /* uController/UART 1 register     */
+#define MD_UREG1_12		0x2200e0 /* uController/UART 1 register     */
+#define MD_UREG1_13		0x2200e8 /* uController/UART 1 register     */
+#define MD_UREG1_14		0x2200f0 /* uController/UART 1 register     */
+#define MD_UREG1_15		0x2200f8 /* uController/UART 1 register     */
+
+#ifdef CONFIG_SGI_SN0_N_MODE
+#define MD_MEM_BANKS		4	 /* 4 banks of memory max in N mode */
+#else
+#define MD_MEM_BANKS		8	 /* 8 banks of memory max in M mode */
+#endif
+
+/*
+ * MD_MEMORY_CONFIG fields
+ *
+ *   MD_SIZE_xxx are useful for representing the size of a SIMM or bank
+ *   (SIMM pair).  They correspond to the values needed for the bit
+ *   triplets (MMC_BANK_MASK) in the MD_MEMORY_CONFIG register for bank size.
+ *   Bits not used by the MD are used by software.
+ */
+
+#define MD_SIZE_EMPTY		0	/* Valid in MEMORY_CONFIG           */
+#define MD_SIZE_8MB		1
+#define MD_SIZE_16MB		2
+#define MD_SIZE_32MB		3	/* Broken in Hub 1		    */
+#define MD_SIZE_64MB		4	/* Valid in MEMORY_CONFIG           */
+#define MD_SIZE_128MB		5	/* Valid in MEMORY_CONFIG           */
+#define MD_SIZE_256MB		6
+#define MD_SIZE_512MB		7	/* Valid in MEMORY_CONFIG           */
+#define MD_SIZE_1GB		8
+#define MD_SIZE_2GB		9
+#define MD_SIZE_4GB		10
+
+#define MD_SIZE_BYTES(size)	((size) == 0 ? 0 : 0x400000L << (size))
+#define MD_SIZE_MBYTES(size)	((size) == 0 ? 0 :   4	     << (size))
+
+#define MMC_FPROM_CYC_SHFT	49	/* Have to use UINT64_CAST, instead */
+#define MMC_FPROM_CYC_MASK	(UINT64_CAST 31 << 49)	/* of 'L' suffix,   */
+#define MMC_FPROM_WR_SHFT	44			/* for assembler    */
+#define MMC_FPROM_WR_MASK	(UINT64_CAST 31 << 44)
+#define MMC_UCTLR_CYC_SHFT	39
+#define MMC_UCTLR_CYC_MASK	(UINT64_CAST 31 << 39)
+#define MMC_UCTLR_WR_SHFT	34
+#define MMC_UCTLR_WR_MASK	(UINT64_CAST 31 << 34)
+#define MMC_DIMM0_SEL_SHFT	32
+#define MMC_DIMM0_SEL_MASK	(UINT64_CAST 3 << 32)
+#define MMC_IO_PROT_EN_SHFT	31
+#define MMC_IO_PROT_EN_MASK	(UINT64_CAST 1 << 31)
+#define MMC_IO_PROT		(UINT64_CAST 1 << 31)
+#define MMC_ARB_MLSS_SHFT	30
+#define MMC_ARB_MLSS_MASK	(UINT64_CAST 1 << 30)
+#define MMC_ARB_MLSS		(UINT64_CAST 1 << 30)
+#define MMC_IGNORE_ECC_SHFT	29
+#define MMC_IGNORE_ECC_MASK	(UINT64_CAST 1 << 29)
+#define MMC_IGNORE_ECC		(UINT64_CAST 1 << 29)
+#define MMC_DIR_PREMIUM_SHFT	28
+#define MMC_DIR_PREMIUM_MASK	(UINT64_CAST 1 << 28)
+#define MMC_DIR_PREMIUM		(UINT64_CAST 1 << 28)
+#define MMC_REPLY_GUAR_SHFT	24
+#define MMC_REPLY_GUAR_MASK	(UINT64_CAST 15 << 24)
+#define MMC_BANK_SHFT(_b)	((_b) * 3)
+#define MMC_BANK_MASK(_b)	(UINT64_CAST 7 << MMC_BANK_SHFT(_b))
+#define MMC_BANK_ALL_MASK	0xffffff
+#define MMC_RESET_DEFAULTS	(UINT64_CAST 0x0f << MMC_FPROM_CYC_SHFT | \
+				 UINT64_CAST 0x07 << MMC_FPROM_WR_SHFT | \
+				 UINT64_CAST 0x1f << MMC_UCTLR_CYC_SHFT | \
+				 UINT64_CAST 0x0f << MMC_UCTLR_WR_SHFT | \
+				 MMC_IGNORE_ECC | MMC_DIR_PREMIUM | \
+				 UINT64_CAST 0x0f << MMC_REPLY_GUAR_SHFT | \
+				 MMC_BANK_ALL_MASK)
+
+/* MD_REFRESH_CONTROL fields */
+
+#define MRC_ENABLE_SHFT		63
+#define MRC_ENABLE_MASK		(UINT64_CAST 1 << 63)
+#define MRC_ENABLE		(UINT64_CAST 1 << 63)
+#define MRC_COUNTER_SHFT	12
+#define MRC_COUNTER_MASK	(UINT64_CAST 0xfff << 12)
+#define MRC_CNT_THRESH_MASK	0xfff
+#define MRC_RESET_DEFAULTS	(UINT64_CAST 0x400)
+
+/* MD_MEM_DIMM_INIT and MD_DIR_DIMM_INIT fields */
+
+#define MDI_SELECT_SHFT		32
+#define MDI_SELECT_MASK		(UINT64_CAST 0x0f << 32)
+#define MDI_DIMM_MODE_MASK	(UINT64_CAST 0xfff)
+
+/* MD_MOQ_SIZE fields */
+
+#define MMS_RP_SIZE_SHFT	8
+#define MMS_RP_SIZE_MASK	(UINT64_CAST 0x3f << 8)
+#define MMS_RQ_SIZE_SHFT	0
+#define MMS_RQ_SIZE_MASK	(UINT64_CAST 0x1f)
+#define MMS_RESET_DEFAULTS	(0x32 << 8 | 0x12)
+
+/* MD_FANDOP_CAC_STAT fields */
+
+#define MFC_VALID_SHFT		63
+#define MFC_VALID_MASK		(UINT64_CAST 1 << 63)
+#define MFC_VALID		(UINT64_CAST 1 << 63)
+#define MFC_ADDR_SHFT		6
+#define MFC_ADDR_MASK		(UINT64_CAST 0x3ffffff)
+
+/* MD_MLAN_CTL fields */
+
+#define MLAN_PHI1_SHFT		27
+#define MLAN_PHI1_MASK		(UINT64_CAST 0x7f << 27)
+#define MLAN_PHI0_SHFT		20
+#define MLAN_PHI0_MASK		(UINT64_CAST 0x7f << 27)
+#define MLAN_PULSE_SHFT		10
+#define MLAN_PULSE_MASK		(UINT64_CAST 0x3ff << 10)
+#define MLAN_SAMPLE_SHFT	2
+#define MLAN_SAMPLE_MASK	(UINT64_CAST 0xff << 2)
+#define MLAN_DONE_SHFT		1
+#define MLAN_DONE_MASK		2
+#define MLAN_DONE		(UINT64_CAST 0x02)
+#define MLAN_RD_DATA		(UINT64_CAST 0x01)
+#define MLAN_RESET_DEFAULTS	(UINT64_CAST 0x31 << MLAN_PHI1_SHFT | \
+				 UINT64_CAST 0x31 << MLAN_PHI0_SHFT)
+
+/* MD_SLOTID_USTAT bit definitions */
+
+#define MSU_CORECLK_TST_SHFT	7	/* You don't wanna know             */
+#define MSU_CORECLK_TST_MASK	(UINT64_CAST 1 << 7)
+#define MSU_CORECLK_TST		(UINT64_CAST 1 << 7)
+#define MSU_CORECLK_SHFT	6	/* You don't wanna know             */
+#define MSU_CORECLK_MASK	(UINT64_CAST 1 << 6)
+#define MSU_CORECLK		(UINT64_CAST 1 << 6)
+#define MSU_NETSYNC_SHFT	5	/* You don't wanna know             */
+#define MSU_NETSYNC_MASK	(UINT64_CAST 1 << 5)
+#define MSU_NETSYNC		(UINT64_CAST 1 << 5)
+#define MSU_FPROMRDY_SHFT	4	/* Flash PROM ready bit 	    */
+#define MSU_FPROMRDY_MASK	(UINT64_CAST 1 << 4)
+#define MSU_FPROMRDY		(UINT64_CAST 1 << 4)
+#define MSU_I2CINTR_SHFT		3	/* I2C interrupt bit   */
+#define MSU_I2CINTR_MASK		(UINT64_CAST 1 << 3)
+#define MSU_I2CINTR		(UINT64_CAST 1 << 3)
+#define MSU_SLOTID_MASK		0xff
+#define MSU_SN0_SLOTID_SHFT	0	/* Slot ID			    */
+#define MSU_SN0_SLOTID_MASK	(UINT64_CAST 7)
+#define MSU_SN00_SLOTID_SHFT	7
+#define MSU_SN00_SLOTID_MASK	(UINT64_CAST 0x80)
+	
+#define	MSU_PIMM_PSC_SHFT	4
+#define	MSU_PIMM_PSC_MASK	(0xf << MSU_PIMM_PSC_SHFT)
+
+/* MD_MIG_DIFF_THRESH bit definitions */
+
+#define MD_MIG_DIFF_THRES_VALID_MASK (UINT64_CAST 0x1 << 63)
+#define MD_MIG_DIFF_THRES_VALID_SHFT 63
+#define MD_MIG_DIFF_THRES_VALUE_MASK (UINT64_CAST 0xfffff)
+
+/* MD_MIG_VALUE_THRESH bit definitions */
+
+#define MD_MIG_VALUE_THRES_VALID_MASK (UINT64_CAST 0x1 << 63)
+#define MD_MIG_VALUE_THRES_VALID_SHFT 63
+#define MD_MIG_VALUE_THRES_VALUE_MASK (UINT64_CAST 0xfffff)
+
+/* MD_MIG_CANDIDATE bit definitions */
+
+#define MD_MIG_CANDIDATE_VALID_MASK (UINT64_CAST 0x1 << 63)
+#define MD_MIG_CANDIDATE_VALID_SHFT 63
+#define MD_MIG_CANDIDATE_TYPE_MASK (UINT64_CAST 0x1 << 30)
+#define MD_MIG_CANDIDATE_TYPE_SHFT 30
+#define MD_MIG_CANDIDATE_OVERRUN_MASK (UINT64_CAST 0x1 << 29)
+#define MD_MIG_CANDIDATE_OVERRUN_SHFT 29
+#define MD_MIG_CANDIDATE_INITIATOR_MASK (UINT64_CAST 0x7ff << 18)
+#define MD_MIG_CANDIDATE_INITIATOR_SHFT 18
+#define MD_MIG_CANDIDATE_NODEID_MASK (UINT64_CAST 0x1ff << 20)
+#define MD_MIG_CANDIDATE_NODEID_SHFT 20
+#define MD_MIG_CANDIDATE_ADDR_MASK (UINT64_CAST 0x3ffff)
+#define MD_MIG_CANDIDATE_ADDR_SHFT 14  /* The address starts at bit 14 */
+
+/* Other MD definitions */
+
+#define MD_BANK_SHFT		29			/* log2(512 MB)     */
+#define MD_BANK_MASK		(UINT64_CAST 7 << 29)
+#define MD_BANK_SIZE		(UINT64_CAST 1 << MD_BANK_SHFT)	  /* 512 MB */
+#define MD_BANK_OFFSET(_b)	(UINT64_CAST (_b) << MD_BANK_SHFT)
+
+/*
+ * The following definitions cover the bit field definitions for the
+ * various MD registers.  For multi-bit registers, we define both
+ * a shift amount and a mask value.  By convention, if you want to
+ * isolate a field, you should mask the field and then shift it down,
+ * since this makes the masks useful without a shift.
+ */
+
+/* Directory entry states for both premium and standard SIMMs. */
+
+#define MD_DIR_SHARED		(UINT64_CAST 0x0)	/* 000 */
+#define MD_DIR_POISONED		(UINT64_CAST 0x1)	/* 001 */
+#define MD_DIR_EXCLUSIVE	(UINT64_CAST 0x2)	/* 010 */
+#define MD_DIR_BUSY_SHARED	(UINT64_CAST 0x3)	/* 011 */
+#define MD_DIR_BUSY_EXCL	(UINT64_CAST 0x4)	/* 100 */
+#define MD_DIR_WAIT		(UINT64_CAST 0x5)	/* 101 */
+#define MD_DIR_UNOWNED		(UINT64_CAST 0x7)	/* 111 */
+
+/*
+ * The MD_DIR_FORCE_ECC bit can be added directory entry write data
+ * to forcing the ECC to be written as-is instead of recalculated.
+ */
+
+#define MD_DIR_FORCE_ECC	(UINT64_CAST 1 << 63)
+
+/*
+ * Premium SIMM directory entry shifts and masks.  Each is valid only in the
+ * context(s) indicated, where A, B, and C indicate the directory entry format
+ * as shown, and low and/or high indicates which double-word of the entry.
+ *
+ * Format A:  STATE = shared, FINE = 1
+ * Format B:  STATE = shared, FINE = 0
+ * Format C:  STATE != shared (FINE must be 0)
+ */
+
+#define MD_PDIR_MASK		0xffffffffffff		/* Whole entry 	    */
+#define MD_PDIR_ECC_SHFT	0			/* ABC low or high  */
+#define MD_PDIR_ECC_MASK	0x7f
+#define MD_PDIR_PRIO_SHFT	8			/* ABC low 	    */
+#define MD_PDIR_PRIO_MASK	(0xf << 8)
+#define MD_PDIR_AX_SHFT		7			/* ABC low 	    */
+#define MD_PDIR_AX_MASK		(1 << 7)
+#define MD_PDIR_AX		(1 << 7)
+#define MD_PDIR_FINE_SHFT	12			/* ABC low 	    */
+#define MD_PDIR_FINE_MASK	(1 << 12)
+#define MD_PDIR_FINE		(1 << 12)
+#define MD_PDIR_OCT_SHFT	13			/* A low 	    */
+#define MD_PDIR_OCT_MASK	(7 << 13)
+#define MD_PDIR_STATE_SHFT	13			/* BC low 	    */
+#define MD_PDIR_STATE_MASK	(7 << 13)
+#define MD_PDIR_ONECNT_SHFT	16			/* BC low 	    */
+#define MD_PDIR_ONECNT_MASK	(0x3f << 16)
+#define MD_PDIR_PTR_SHFT	22			/* C low 	    */
+#define MD_PDIR_PTR_MASK	(UINT64_CAST 0x7ff << 22)
+#define MD_PDIR_VECMSB_SHFT	22			/* AB low 	    */
+#define MD_PDIR_VECMSB_BITMASK	0x3ffffff
+#define MD_PDIR_VECMSB_BITSHFT	27
+#define MD_PDIR_VECMSB_MASK	(UINT64_CAST MD_PDIR_VECMSB_BITMASK << 22)
+#define MD_PDIR_CWOFF_SHFT	7			/* C high 	    */
+#define MD_PDIR_CWOFF_MASK	(7 << 7)
+#define MD_PDIR_VECLSB_SHFT	10			/* AB high 	    */
+#define MD_PDIR_VECLSB_BITMASK	(UINT64_CAST 0x3fffffffff)
+#define MD_PDIR_VECLSB_BITSHFT	0
+#define MD_PDIR_VECLSB_MASK	(MD_PDIR_VECLSB_BITMASK << 10)
+
+/*
+ * Directory initialization values
+ */
+
+#define MD_PDIR_INIT_LO		(MD_DIR_UNOWNED << MD_PDIR_STATE_SHFT | \
+				 MD_PDIR_AX)
+#define MD_PDIR_INIT_HI		0
+#define MD_PDIR_INIT_PROT	(MD_PROT_RW << MD_PPROT_IO_SHFT | \
+				 MD_PROT_RW << MD_PPROT_SHFT)
+
+/*
+ * Standard SIMM directory entry shifts and masks.  Each is valid only in the
+ * context(s) indicated, where A and C indicate the directory entry format
+ * as shown, and low and/or high indicates which double-word of the entry.
+ *
+ * Format A:  STATE == shared
+ * Format C:  STATE != shared
+ */
+
+#define MD_SDIR_MASK		0xffff			/* Whole entry 	    */
+#define MD_SDIR_ECC_SHFT	0			/* AC low or high   */
+#define MD_SDIR_ECC_MASK	0x1f
+#define MD_SDIR_PRIO_SHFT	6			/* AC low 	    */
+#define MD_SDIR_PRIO_MASK	(1 << 6)
+#define MD_SDIR_AX_SHFT		5			/* AC low 	    */
+#define MD_SDIR_AX_MASK		(1 << 5)
+#define MD_SDIR_AX		(1 << 5)
+#define MD_SDIR_STATE_SHFT	7			/* AC low 	    */
+#define MD_SDIR_STATE_MASK	(7 << 7)
+#define MD_SDIR_PTR_SHFT	10			/* C low 	    */
+#define MD_SDIR_PTR_MASK	(0x3f << 10)
+#define MD_SDIR_CWOFF_SHFT	5			/* C high 	    */
+#define MD_SDIR_CWOFF_MASK	(7 << 5)
+#define MD_SDIR_VECMSB_SHFT	11			/* A low 	    */
+#define MD_SDIR_VECMSB_BITMASK	0x1f
+#define MD_SDIR_VECMSB_BITSHFT	7
+#define MD_SDIR_VECMSB_MASK	(MD_SDIR_VECMSB_BITMASK << 11)
+#define MD_SDIR_VECLSB_SHFT	5			/* A high 	    */
+#define MD_SDIR_VECLSB_BITMASK	0x7ff
+#define MD_SDIR_VECLSB_BITSHFT	0
+#define MD_SDIR_VECLSB_MASK	(MD_SDIR_VECLSB_BITMASK << 5)
+
+/*
+ * Directory initialization values
+ */
+
+#define MD_SDIR_INIT_LO		(MD_DIR_UNOWNED << MD_SDIR_STATE_SHFT | \
+				 MD_SDIR_AX)
+#define MD_SDIR_INIT_HI		0
+#define MD_SDIR_INIT_PROT	(MD_PROT_RW << MD_SPROT_SHFT)
+
+/* Protection and migration field values */
+
+#define MD_PROT_RW		(UINT64_CAST 0x6)
+#define MD_PROT_RO		(UINT64_CAST 0x3)
+#define MD_PROT_NO		(UINT64_CAST 0x0)
+#define MD_PROT_BAD		(UINT64_CAST 0x5)
+
+/* Premium SIMM protection entry shifts and masks. */
+
+#define MD_PPROT_SHFT		0			/* Prot. field 	    */
+#define MD_PPROT_MASK		7
+#define MD_PPROT_MIGMD_SHFT	3			/* Migration mode   */
+#define MD_PPROT_MIGMD_MASK	(3 << 3)
+#define MD_PPROT_REFCNT_SHFT	5			/* Reference count  */
+#define MD_PPROT_REFCNT_WIDTH	0x7ffff
+#define MD_PPROT_REFCNT_MASK	(MD_PPROT_REFCNT_WIDTH << 5)
+
+#define MD_PPROT_IO_SHFT	45			/* I/O Prot field   */
+#define MD_PPROT_IO_MASK	(UINT64_CAST 7 << 45)
+
+/* Standard SIMM protection entry shifts and masks. */
+
+#define MD_SPROT_SHFT		0			/* Prot. field 	    */
+#define MD_SPROT_MASK		7
+#define MD_SPROT_MIGMD_SHFT	3			/* Migration mode   */
+#define MD_SPROT_MIGMD_MASK	(3 << 3)
+#define MD_SPROT_REFCNT_SHFT	5			/* Reference count  */
+#define MD_SPROT_REFCNT_WIDTH	0x7ff
+#define MD_SPROT_REFCNT_MASK	(MD_SPROT_REFCNT_WIDTH << 5)
+
+/* Migration modes used in protection entries */
+
+#define MD_PROT_MIGMD_IREL	(UINT64_CAST 0x3 << 3)
+#define MD_PROT_MIGMD_IABS	(UINT64_CAST 0x2 << 3)
+#define MD_PROT_MIGMD_PREL	(UINT64_CAST 0x1 << 3)
+#define MD_PROT_MIGMD_OFF	(UINT64_CAST 0x0 << 3)
+
+
+/*
+ * Operations on page migration threshold register
+ */
+
+#if _LANGUAGE_C
+#ifndef _STANDALONE
+
+/*
+ * LED register macros
+ */
+
+#define CPU_LED_ADDR(_nasid, _slice)					   \
+	(private.p_sn00 ?						   \
+	 REMOTE_HUB_ADDR((_nasid), MD_UREG1_0 +	((_slice) << 5)) :	   \
+	 REMOTE_HUB_ADDR((_nasid), MD_LED0    + ((_slice) << 3)))
+
+#define SET_CPU_LEDS(_nasid, _slice,  _val)				   \
+	(HUB_S(CPU_LED_ADDR(_nasid, _slice), (_val)))
+
+#define SET_MY_LEDS(_v) 						   \
+	SET_CPU_LEDS(get_nasid(), get_slice(), (_v))
+
+/*
+ * Operations on Memory/Directory DIMM control register
+ */
+
+#define DIRTYPE_PREMIUM 1
+#define DIRTYPE_STANDARD 0
+#define MD_MEMORY_CONFIG_DIR_TYPE_GET(region) (\
+	(REMOTE_HUB_L(region, MD_MEMORY_CONFIG) & MMC_DIR_PREMIUM_MASK) >> \
+	MMC_DIR_PREMIUM_SHFT)
+
+
+/*
+ * Operations on page migration count difference and absolute threshold
+ * registers
+ */
+
+#define MD_MIG_DIFF_THRESH_GET(region) ( \
+	REMOTE_HUB_L((region), MD_MIG_DIFF_THRESH) & \
+	MD_MIG_DIFF_THRES_VALUE_MASK)
+
+#define MD_MIG_DIFF_THRESH_SET(region, value) (				\
+	REMOTE_HUB_S((region), MD_MIG_DIFF_THRESH,			\
+		MD_MIG_DIFF_THRES_VALID_MASK | (value)))
+
+#define MD_MIG_DIFF_THRESH_DISABLE(region) (			\
+	REMOTE_HUB_S((region), MD_MIG_DIFF_THRESH,			\
+		REMOTE_HUB_L((region), MD_MIG_DIFF_THRESH)		\
+			     & ~MD_MIG_DIFF_THRES_VALID_MASK))
+
+#define MD_MIG_DIFF_THRESH_ENABLE(region) (			\
+	REMOTE_HUB_S((region), MD_MIG_DIFF_THRESH,			\
+		REMOTE_HUB_L((region), MD_MIG_DIFF_THRESH)		\
+			     | MD_MIG_DIFF_THRES_VALID_MASK))
+
+#define MD_MIG_DIFF_THRESH_IS_ENABLED(region) (				\
+	REMOTE_HUB_L((region), MD_MIG_DIFF_THRESH) &			\
+	       MD_MIG_DIFF_THRES_VALID_MASK)
+
+#define MD_MIG_VALUE_THRESH_GET(region) (				\
+	REMOTE_HUB_L((region), MD_MIG_VALUE_THRESH) &  \
+	MD_MIG_VALUE_THRES_VALUE_MASK)
+
+#define MD_MIG_VALUE_THRESH_SET(region, value) (			\
+	REMOTE_HUB_S((region), MD_MIG_VALUE_THRESH,			\
+		MD_MIG_VALUE_THRES_VALID_MASK | (value)))
+
+#define MD_MIG_VALUE_THRESH_DISABLE(region) (			\
+	REMOTE_HUB_S((region), MD_MIG_VALUE_THRESH,			\
+		REMOTE_HUB_L(region, MD_MIG_VALUE_THRESH)		\
+			     & ~MD_MIG_VALUE_THRES_VALID_MASK))
+
+#define MD_MIG_VALUE_THRESH_ENABLE(region) (			\
+	REMOTE_HUB_S((region), MD_MIG_VALUE_THRESH,			\
+		REMOTE_HUB_L((region), MD_MIG_VALUE_THRESH)		\
+			     | MD_MIG_VALUE_THRES_VALID_MASK))
+
+#define MD_MIG_VALUE_THRESH_IS_ENABLED(region) (			\
+	REMOTE_HUB_L((region), MD_MIG_VALUE_THRESH) &			 \
+	       MD_MIG_VALUE_THRES_VALID_MASK)
+
+/*
+ * Operations on page migration candidate register
+ */
+
+#define MD_MIG_CANDIDATE_GET(my_region_id) ( \
+	REMOTE_HUB_L((my_region_id), MD_MIG_CANDIDATE_CLR))
+
+#define MD_MIG_CANDIDATE_HWPFN(value) ((value) & MD_MIG_CANDIDATE_ADDR_MASK)
+
+#define MD_MIG_CANDIDATE_NODEID(value) ( \
+	((value) & MD_MIG_CANDIDATE_NODEID_MASK) >> MD_MIG_CANDIDATE_NODEID_SHFT)
+
+#define MD_MIG_CANDIDATE_TYPE(value) ( \
+	((value) & MD_MIG_CANDIDATE_TYPE_MASK) >> MD_MIG_CANDIDATE_TYPE_SHFT)
+
+#define MD_MIG_CANDIDATE_VALID(value) ( \
+	((value) & MD_MIG_CANDIDATE_VALID_MASK) >> MD_MIG_CANDIDATE_VALID_SHFT)
+
+/*
+ * Macros to retrieve fields in the protection entry
+ */
+
+/* for Premium SIMM */
+#define MD_PPROT_REFCNT_GET(value) ( \
+	((value) & MD_PPROT_REFCNT_MASK) >> MD_PPROT_REFCNT_SHFT)
+
+#define MD_PPROT_MIGMD_GET(value) ( \
+	((value) & MD_PPROT_MIGMD_MASK) >> MD_PPROT_MIGMD_SHFT)
+
+/* for Standard SIMM */
+#define MD_SPROT_REFCNT_GET(value) ( \
+	((value) & MD_SPROT_REFCNT_MASK) >> MD_SPROT_REFCNT_SHFT)
+
+#define MD_SPROT_MIGMD_GET(value) ( \
+	((value) & MD_SPROT_MIGMD_MASK) >> MD_SPROT_MIGMD_SHFT)
+
+#endif /* _STANDALONE */
+
+/*
+ * Format of dir_error, mem_error, protocol_error and misc_error registers
+ */
+
+struct dir_error_reg {
+	u64	uce_vld:   1,	/*    63: valid directory uce 	*/
+		ae_vld:	   1,	/*    62: valid dir prot ecc error */
+		ce_vld:	   1,	/*    61: valid correctable ECC err*/
+		rsvd1:	  19,	/* 60-42: reserved		*/
+		bad_prot:  3,	/* 41-39: encoding, bad access rights*/
+		bad_syn:   7,	/* 38-32: bad dir syndrome	*/
+		rsvd2:	   2,	/* 31-30: reserved		*/
+		hspec_addr:27,	/* 29-03: bddir space bad entry */
+		uce_ovr:   1,	/*     2: multiple dir uce's	*/
+		ae_ovr:	   1,	/*     1: multiple prot ecc errs*/
+		ce_ovr:	   1;	/*     0: multiple correctable errs */
+};
+
+typedef union md_dir_error {
+	u64	derr_reg;	/* the entire register 		*/
+	struct dir_error_reg derr_fmt;	/* the register format		*/
+} md_dir_error_t;
+
+
+struct mem_error_reg {
+	u64	uce_vld:   1,	/*    63: valid memory uce 	*/
+		ce_vld:	   1,	/*    62: valid correctable ECC err*/
+		rsvd1:	  22,	/* 61-40: reserved		*/
+		bad_syn:   8,	/* 39-32: bad mem ecc syndrome	*/
+		address:  29,	/* 31-03: bad entry pointer	*/
+		rsvd2:	   1,	/*     2: reserved		*/
+		uce_ovr:   1,	/*     1: multiple mem uce's	*/
+		ce_ovr:	   1;	/*     0: multiple correctable errs */
+};
+
+
+typedef union md_mem_error {
+	u64	merr_reg;	/* the entire register 		*/
+	struct mem_error_reg  merr_fmt; /* format of the mem_error reg  */
+} md_mem_error_t;
+
+
+struct proto_error_reg {
+	u64	valid:	   1,	/*    63: valid protocol error	*/
+		rsvd1:	   2,	/* 62-61: reserved		*/
+		initiator:11,	/* 60-50: id of request initiator*/
+		backoff:   2,	/* 49-48: backoff control	*/
+		msg_type:  8,	/* 47-40: type of request	*/
+		access:	   2,	/* 39-38: access rights of initiator*/
+		priority:  1,	/*    37: priority level of requestor*/
+		dir_state: 4,	/* 36-33: state of directory	*/
+		pointer_me:1,	/*    32: initiator same as dir ptr */
+		address:  29,	/* 31-03: request address	*/
+		rsvd2:	   2,	/* 02-01: reserved		*/
+		overrun:   1;	/*     0: multiple protocol errs */
+};
+
+typedef union md_proto_error {
+	u64	perr_reg;	/* the entire register 		*/
+	struct proto_error_reg	perr_fmt; /* format of the register	*/
+} md_proto_error_t;
+
+
+struct md_sdir_high_fmt {
+	unsigned short sd_hi_bvec : 11,
+		       sd_hi_ecc  : 5;
+};
+
+
+typedef union md_sdir_high {
+	/* The 16 bits of standard directory, upper word */
+	unsigned short sd_hi_val;
+	struct	md_sdir_high_fmt sd_hi_fmt;
+}md_sdir_high_t;
+
+
+struct md_sdir_low_shared_fmt {
+	/* The meaning of lower directory, shared */
+	unsigned short	sds_lo_bvec  : 5,
+			sds_lo_unused: 1,
+			sds_lo_state : 3,
+			sds_lo_prio  : 1,
+			sds_lo_ax    : 1,
+			sds_lo_ecc   : 5;
+};
+
+struct md_sdir_low_exclusive_fmt {
+	/* The meaning of lower directory, exclusive */
+	unsigned short	sde_lo_ptr   : 6,
+			sde_lo_state : 3,
+			sde_lo_prio  : 1,
+			sde_lo_ax    : 1,
+			sde_lo_ecc   : 5;
+};
+
+
+typedef union md_sdir_low {
+	/* The 16 bits of standard directory, lower word */
+	unsigned short	sd_lo_val;
+	struct	md_sdir_low_exclusive_fmt sde_lo_fmt;
+	struct	md_sdir_low_shared_fmt sds_lo_fmt;
+}md_sdir_low_t;
+
+
+
+struct md_pdir_high_fmt {
+	u64	pd_hi_unused   : 16,
+		pd_hi_bvec     : 38,
+		pd_hi_unused1  : 3,
+		pd_hi_ecc      : 7;
+};
+
+
+typedef union md_pdir_high {
+	/* The 48 bits of standard directory, upper word */
+	u64	pd_hi_val;
+	struct md_pdir_high_fmt pd_hi_fmt;
+}md_pdir_high_t;
+
+
+struct md_pdir_low_shared_fmt {
+	/* The meaning of lower directory, shared */
+	u64	pds_lo_unused	: 16,
+		pds_lo_bvec	: 26,
+		pds_lo_cnt	:  6,
+		pds_lo_state	:  3,
+		pds_lo_ste	:  1,
+		pds_lo_prio	:  4,
+		pds_lo_ax	:  1,
+		pds_lo_ecc	:  7;
+};
+
+struct md_pdir_low_exclusive_fmt {
+	/* The meaning of lower directory, exclusive */
+	u64	pde_lo_unused	: 31,
+		pde_lo_ptr	: 11,
+		pde_lo_unused1	:  6,
+		pde_lo_state	:  3,
+		pde_lo_ste	:  1,
+		pde_lo_prio	:  4,
+		pde_lo_ax	:  1,
+		pde_lo_ecc	:  7;
+};
+
+
+typedef union md_pdir_loent {
+	/* The 48 bits of premium directory, lower word */
+	u64	pd_lo_val;
+	struct md_pdir_low_exclusive_fmt pde_lo_fmt;
+	struct md_pdir_low_shared_fmt	pds_lo_fmt;
+}md_pdir_low_t;
+
+
+/*
+ *   the following two "union" definitions and two
+ *   "struct" definitions are used in vmdump.c to
+ *   represent directory memory information.
+ */
+
+typedef	union	md_dir_high	{
+        md_sdir_high_t	md_sdir_high;
+        md_pdir_high_t	md_pdir_high;
+} md_dir_high_t;
+
+typedef	union	md_dir_low	{
+        md_sdir_low_t	md_sdir_low;
+        md_pdir_low_t	md_pdir_low;
+} md_dir_low_t;
+
+typedef	struct	bddir_entry	{
+        md_dir_low_t	md_dir_low;
+        md_dir_high_t	md_dir_high;
+} bddir_entry_t;
+
+typedef struct	dir_mem_entry	{
+        u64		prcpf[MAX_REGIONS];
+        bddir_entry_t	directory_words[MD_PAGE_SIZE/CACHE_SLINE_SIZE];
+} dir_mem_entry_t;
+
+
+
+typedef union md_perf_sel {
+	u64 	perf_sel_reg;
+	struct	{
+		u64	perf_rsvd : 60,
+		        perf_en   :  1,
+			perf_sel  :  3;
+	} perf_sel_bits;
+} md_perf_sel_t;
+
+typedef union md_perf_cnt {
+	u64	perf_cnt;
+	struct	{
+		u64	perf_rsvd : 44,
+	                perf_cnt  : 20;
+	} perf_cnt_bits;
+} md_perf_cnt_t;
+
+
+#endif /* _LANGUAGE_C */
+
+
+#define DIR_ERROR_VALID_MASK	0xe000000000000000
+#define DIR_ERROR_VALID_SHFT	61
+#define DIR_ERROR_VALID_UCE	0x8000000000000000
+#define DIR_ERROR_VALID_AE	0x4000000000000000
+#define DIR_ERROR_VALID_CE	0x2000000000000000
+
+#define MEM_ERROR_VALID_MASK	0xc000000000000000
+#define MEM_ERROR_VALID_SHFT	62
+#define MEM_ERROR_VALID_UCE	0x8000000000000000
+#define MEM_ERROR_VALID_CE	0x4000000000000000
+
+#define PROTO_ERROR_VALID_MASK	0x8000000000000000
+
+#define MISC_ERROR_VALID_MASK	0x3ff
+
+/*
+ * Mask for hspec address that is stored in the dir error register.
+ * This represents bits 29 through 3.
+ */
+#define DIR_ERR_HSPEC_MASK	0x3ffffff8
+#define ERROR_HSPEC_MASK	0x3ffffff8
+#define ERROR_HSPEC_SHFT	3
+#define ERROR_ADDR_MASK		0xfffffff8
+#define ERROR_ADDR_SHFT		3
+
+/*
+ * MD_MISC_ERROR register defines.
+ */
+
+#define MMCE_VALID_MASK		0x3ff
+#define MMCE_ILL_MSG_SHFT	8
+#define MMCE_ILL_MSG_MASK	(UINT64_CAST 0x03 << MMCE_ILL_MSG_SHFT)
+#define MMCE_ILL_REV_SHFT	6
+#define MMCE_ILL_REV_MASK	(UINT64_CAST 0x03 << MMCE_ILL_REV_SHFT)
+#define MMCE_LONG_PACK_SHFT	4
+#define MMCE_LONG_PACK_MASK	(UINT64_CAST 0x03 << MMCE_lONG_PACK_SHFT)
+#define MMCE_SHORT_PACK_SHFT	2
+#define MMCE_SHORT_PACK_MASK	(UINT64_CAST 0x03 << MMCE_SHORT_PACK_SHFT)
+#define MMCE_BAD_DATA_SHFT	0
+#define MMCE_BAD_DATA_MASK	(UINT64_CAST 0x03 << MMCE_BAD_DATA_SHFT)
+
+
+#define MD_PERF_COUNTERS	6
+#define MD_PERF_SETS		6
+
+#define MEM_DIMM_MASK				0xe0000000
+#define MEM_DIMM_SHFT				29
+
+#endif /* _ASM_SN_SN0_HUBMD_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/sn0/hubni.h linux/include/asm-mips64/sn/sn0/hubni.h
--- v2.3.47/linux/include/asm-mips64/sn/sn0/hubni.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/sn0/hubni.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,256 @@
+/* $Id: hubni.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/hubni.h>, Revision 1.27.
+ *
+ * Copyright (C) 1992-1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SGI_SN0_HUBNI_H
+#define _ASM_SGI_SN0_HUBNI_H
+
+#ifdef _LANGUAGE_C
+#include <linux/types.h>
+#endif
+
+/*
+ * Hub Network Interface registers
+ *
+ * All registers in this file are subject to change until Hub chip tapeout.
+ */
+
+#define NI_BASE			0x600000
+#define NI_BASE_TABLES		0x630000
+
+#define NI_STATUS_REV_ID	0x600000 /* Hub network status, rev, and ID */
+#define NI_PORT_RESET		0x600008 /* Reset the network interface     */
+#define NI_PROTECTION		0x600010 /* NI register access permissions  */
+#define NI_GLOBAL_PARMS		0x600018 /* LLP parameters 		    */
+#define NI_SCRATCH_REG0		0x600100 /* Scratch register 0 (64 bits)    */
+#define NI_SCRATCH_REG1		0x600108 /* Scratch register 1 (64 bits)    */
+#define NI_DIAG_PARMS		0x600110 /* Parameters for diags	    */
+
+#define NI_VECTOR_PARMS		0x600200 /* Vector PIO routing parameters   */
+#define NI_VECTOR		0x600208 /* Vector PIO route 		    */
+#define NI_VECTOR_DATA		0x600210 /* Vector PIO data 		    */
+#define NI_VECTOR_STATUS	0x600300 /* Vector PIO return status 	    */
+#define NI_RETURN_VECTOR	0x600308 /* Vector PIO return vector 	    */
+#define NI_VECTOR_READ_DATA	0x600310 /* Vector PIO read data 	    */
+#define NI_VECTOR_CLEAR		0x600380 /* Vector PIO read & clear status  */
+
+#define NI_IO_PROTECT		0x600400 /* PIO protection bits 	    */
+#define NI_IO_PROT_OVRRD	0x600408 /* PIO protection bit override     */
+
+#define NI_AGE_CPU0_MEMORY	0x600500 /* CPU 0 memory age control 	    */
+#define NI_AGE_CPU0_PIO		0x600508 /* CPU 0 PIO age control 	    */
+#define NI_AGE_CPU1_MEMORY	0x600510 /* CPU 1 memory age control 	    */
+#define NI_AGE_CPU1_PIO		0x600518 /* CPU 1 PIO age control 	    */
+#define NI_AGE_GBR_MEMORY	0x600520 /* GBR memory age control 	    */
+#define NI_AGE_GBR_PIO		0x600528 /* GBR PIO age control 	    */
+#define NI_AGE_IO_MEMORY	0x600530 /* IO memory age control 	    */
+#define NI_AGE_IO_PIO		0x600538 /* IO PIO age control 		    */
+#define NI_AGE_REG_MIN		NI_AGE_CPU0_MEMORY
+#define NI_AGE_REG_MAX		NI_AGE_IO_PIO
+
+#define NI_PORT_PARMS		0x608000 /* LLP Parameters 		    */
+#define NI_PORT_ERROR		0x608008 /* LLP Errors 			    */
+#define NI_PORT_ERROR_CLEAR	0x608088 /* Clear the error bits 	    */
+
+#define NI_META_TABLE0		0x638000 /* First meta routing table entry  */
+#define NI_META_TABLE(_x)	(NI_META_TABLE0 + (8 * (_x)))
+#define NI_META_ENTRIES		32
+
+#define NI_LOCAL_TABLE0		0x638100 /* First local routing table entry */
+#define NI_LOCAL_TABLE(_x)	(NI_LOCAL_TABLE0 + (8 * (_x)))
+#define NI_LOCAL_ENTRIES	16
+
+/*
+ * NI_STATUS_REV_ID mask and shift definitions
+ * Have to use UINT64_CAST instead of 'L' suffix, for assembler.
+ */
+
+#define NSRI_8BITMODE_SHFT	30
+#define NSRI_8BITMODE_MASK	(UINT64_CAST 0x1 << 30)
+#define NSRI_LINKUP_SHFT	29
+#define NSRI_LINKUP_MASK	(UINT64_CAST 0x1 << 29)
+#define NSRI_DOWNREASON_SHFT	28		/* 0=failed, 1=never came   */
+#define NSRI_DOWNREASON_MASK	(UINT64_CAST 0x1 << 28)	/*    out of reset. */
+#define NSRI_MORENODES_SHFT	18
+#define NSRI_MORENODES_MASK	(UINT64_CAST 1 << 18)	/* Max. # of nodes  */
+#define	 MORE_MEMORY		0
+#define	 MORE_NODES		1
+#define NSRI_REGIONSIZE_SHFT	17
+#define NSRI_REGIONSIZE_MASK	(UINT64_CAST 1 << 17)	/* Granularity 	    */
+#define	 REGIONSIZE_FINE	1
+#define	 REGIONSIZE_COARSE	0
+#define NSRI_NODEID_SHFT	8
+#define NSRI_NODEID_MASK	(UINT64_CAST 0x1ff << 8)/* Node (Hub) ID    */
+#define NSRI_REV_SHFT		4
+#define NSRI_REV_MASK		(UINT64_CAST 0xf << 4)	/* Chip Revision    */
+#define NSRI_CHIPID_SHFT	0
+#define NSRI_CHIPID_MASK	(UINT64_CAST 0xf)	/* Chip type ID     */
+
+/*
+ * In fine mode, each node is a region.  In coarse mode, there are
+ * eight nodes per region.
+ */
+#define NASID_TO_FINEREG_SHFT	0
+#define NASID_TO_COARSEREG_SHFT	3
+
+/* NI_PORT_RESET mask definitions */
+
+#define NPR_PORTRESET		(UINT64_CAST 1 << 7)	/* Send warm reset  */
+#define NPR_LINKRESET		(UINT64_CAST 1 << 1)	/* Send link reset  */
+#define NPR_LOCALRESET		(UINT64_CAST 1)		/* Reset entire hub */
+
+/* NI_PROTECTION mask and shift definitions */
+
+#define NPROT_RESETOK		(UINT64_CAST 1)
+
+/* NI_GLOBAL_PARMS mask and shift definitions */
+
+#define NGP_MAXRETRY_SHFT	48		/* Maximum retries  	    */
+#define NGP_MAXRETRY_MASK	(UINT64_CAST 0x3ff << 48)
+#define NGP_TAILTOWRAP_SHFT	32		/* Tail timeout wrap 	    */
+#define NGP_TAILTOWRAP_MASK	(UINT64_CAST 0xffff << 32)
+
+#define NGP_CREDITTOVAL_SHFT	16		/* Tail timeout wrap 	    */
+#define NGP_CREDITTOVAL_MASK	(UINT64_CAST 0xf << 16)
+#define NGP_TAILTOVAL_SHFT	4		/* Tail timeout value 	    */
+#define NGP_TAILTOVAL_MASK	(UINT64_CAST 0xf << 4)
+
+/* NI_DIAG_PARMS mask and shift definitions */
+
+#define NDP_PORTTORESET		(UINT64_CAST 1 << 18)	/* Port tmout reset */
+#define NDP_LLP8BITMODE		(UINT64_CAST 1 << 12)	/* LLP 8-bit mode   */
+#define NDP_PORTDISABLE		(UINT64_CAST 1 <<  6)	/* Port disable     */
+#define NDP_SENDERROR		(UINT64_CAST 1)		/* Send data error  */
+
+/*
+ * NI_VECTOR_PARMS mask and shift definitions.
+ * TYPE may be any of the first four PIOTYPEs defined under NI_VECTOR_STATUS.
+ */
+
+#define NVP_PIOID_SHFT		40
+#define NVP_PIOID_MASK		(UINT64_CAST 0x3ff << 40)
+#define NVP_WRITEID_SHFT	32
+#define NVP_WRITEID_MASK	(UINT64_CAST 0xff << 32)
+#define NVP_ADDRESS_MASK	(UINT64_CAST 0xffff8)	/* Bits 19:3 	    */
+#define NVP_TYPE_SHFT		0
+#define NVP_TYPE_MASK		(UINT64_CAST 0x3)
+
+/* NI_VECTOR_STATUS mask and shift definitions */
+
+#define NVS_VALID		(UINT64_CAST 1 << 63)
+#define NVS_OVERRUN		(UINT64_CAST 1 << 62)
+#define NVS_TARGET_SHFT		51
+#define NVS_TARGET_MASK		(UINT64_CAST 0x3ff << 51)
+#define NVS_PIOID_SHFT		40
+#define NVS_PIOID_MASK		(UINT64_CAST 0x3ff << 40)
+#define NVS_WRITEID_SHFT	32
+#define NVS_WRITEID_MASK	(UINT64_CAST 0xff << 32)
+#define NVS_ADDRESS_MASK	(UINT64_CAST 0xfffffff8)   /* Bits 31:3     */
+#define NVS_TYPE_SHFT		0
+#define NVS_TYPE_MASK		(UINT64_CAST 0x7)
+#define NVS_ERROR_MASK		(UINT64_CAST 0x4)  /* bit set means error */
+
+
+#define	 PIOTYPE_READ		0	/* VECTOR_PARMS and VECTOR_STATUS   */
+#define	 PIOTYPE_WRITE		1	/* VECTOR_PARMS and VECTOR_STATUS   */
+#define	 PIOTYPE_UNDEFINED	2	/* VECTOR_PARMS and VECTOR_STATUS   */
+#define	 PIOTYPE_EXCHANGE	3	/* VECTOR_PARMS and VECTOR_STATUS   */
+#define	 PIOTYPE_ADDR_ERR	4	/* VECTOR_STATUS only 		    */
+#define	 PIOTYPE_CMD_ERR	5	/* VECTOR_STATUS only 		    */
+#define	 PIOTYPE_PROT_ERR	6	/* VECTOR_STATUS only 		    */
+#define	 PIOTYPE_UNKNOWN	7	/* VECTOR_STATUS only 		    */
+
+/* NI_AGE_XXX mask and shift definitions */
+
+#define NAGE_VCH_SHFT		10
+#define NAGE_VCH_MASK		(UINT64_CAST 3 << 10)
+#define NAGE_CC_SHFT		8
+#define NAGE_CC_MASK		(UINT64_CAST 3 << 8)
+#define NAGE_AGE_SHFT		0
+#define NAGE_AGE_MASK		(UINT64_CAST 0xff)
+#define NAGE_MASK		(NAGE_VCH_MASK | NAGE_CC_MASK | NAGE_AGE_MASK)
+
+#define	 VCHANNEL_A		0
+#define	 VCHANNEL_B		1
+#define	 VCHANNEL_ANY		2
+
+/* NI_PORT_PARMS mask and shift definitions */
+
+#define NPP_NULLTO_SHFT		10
+#define NPP_NULLTO_MASK		(UINT64_CAST 0x3f << 16)
+#define NPP_MAXBURST_SHFT	0
+#define NPP_MAXBURST_MASK	(UINT64_CAST 0x3ff)
+#define NPP_RESET_DFLT_HUB20	((UINT64_CAST 1	    << NPP_NULLTO_SHFT) | \
+				 (UINT64_CAST 0x3f0 << NPP_MAXBURST_SHFT))
+#define NPP_RESET_DEFAULTS	((UINT64_CAST 6	    << NPP_NULLTO_SHFT) | \
+				 (UINT64_CAST 0x3f0 << NPP_MAXBURST_SHFT))
+
+
+/* NI_PORT_ERROR mask and shift definitions */
+
+#define NPE_LINKRESET		(UINT64_CAST 1 << 37)
+#define NPE_INTERNALERROR	(UINT64_CAST 1 << 36)
+#define NPE_BADMESSAGE		(UINT64_CAST 1 << 35)
+#define NPE_BADDEST		(UINT64_CAST 1 << 34)
+#define NPE_FIFOOVERFLOW	(UINT64_CAST 1 << 33)
+#define NPE_CREDITTO_SHFT	28
+#define NPE_CREDITTO_MASK	(UINT64_CAST 0xf << 28)
+#define NPE_TAILTO_SHFT		24
+#define NPE_TAILTO_MASK		(UINT64_CAST 0xf << 24)
+#define NPE_RETRYCOUNT_SHFT	16
+#define NPE_RETRYCOUNT_MASK	(UINT64_CAST 0xff << 16)
+#define NPE_CBERRCOUNT_SHFT	8
+#define NPE_CBERRCOUNT_MASK	(UINT64_CAST 0xff << 8)
+#define NPE_SNERRCOUNT_SHFT	0
+#define NPE_SNERRCOUNT_MASK	(UINT64_CAST 0xff << 0)
+#define NPE_MASK		0x3effffffff
+
+#define NPE_COUNT_MAX		0xff
+
+#define NPE_FATAL_ERRORS	(NPE_LINKRESET | NPE_INTERNALERROR |	\
+				 NPE_BADMESSAGE | NPE_BADDEST |		\
+				 NPE_FIFOOVERFLOW | NPE_CREDITTO_MASK |	\
+				 NPE_TAILTO_MASK)
+
+/* NI_META_TABLE mask and shift definitions */
+
+#define NMT_EXIT_PORT_MASK (UINT64_CAST 0xf)
+
+/* NI_LOCAL_TABLE mask and shift definitions */
+
+#define NLT_EXIT_PORT_MASK (UINT64_CAST 0xf)
+
+#ifdef _LANGUAGE_C
+
+typedef union	hubni_port_error_u {
+	u64	nipe_reg_value;
+	struct {
+	    u64	nipe_rsvd:	26,	/* unused */
+		nipe_lnk_reset:	 1,	/* link reset */
+		nipe_intl_err:	 1,	/* internal error */
+		nipe_bad_msg:	 1,	/* bad message */
+		nipe_bad_dest:	 1,	/* bad dest	*/
+		nipe_fifo_ovfl:	 1,	/* fifo overflow */
+		nipe_rsvd1:	 1,	/* unused */
+		nipe_credit_to:	 4,	/* credit timeout */
+		nipe_tail_to:	 4,	/* tail timeout */
+		nipe_retry_cnt:	 8,	/* retry error count */
+		nipe_cb_cnt:	 8,	/* checkbit error count */
+		nipe_sn_cnt:	 8;	/* sequence number count */
+	} nipe_fields_s;
+} hubni_port_error_t;
+
+#define NI_LLP_RETRY_MAX	0xff
+#define NI_LLP_CB_MAX		0xff
+#define NI_LLP_SN_MAX		0xff
+
+#endif /* LANGUAGE_C */
+
+#endif /* _ASM_SGI_SN0_HUBNI_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/sn0/hubpi.h linux/include/asm-mips64/sn/sn0/hubpi.h
--- v2.3.47/linux/include/asm-mips64/sn/sn0/hubpi.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/sn0/hubpi.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,428 @@
+/* $Id: hubpi.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/hubpi.h>, revision 1.28.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef	_ASM_SN_SN0_HUBPI_H
+#define	_ASM_SN_SN0_HUBPI_H
+
+#include <linux/types.h>
+
+/*
+ * Hub I/O interface registers
+ *
+ * All registers in this file are subject to change until Hub chip tapeout.
+ * All register "addresses" are actually offsets.  Use the LOCAL_HUB
+ * or REMOTE_HUB macros to synthesize an actual address
+ */
+
+#define PI_BASE			0x000000
+
+/* General protection and control registers */
+
+#define PI_CPU_PROTECT		0x000000 /* CPU Protection 		    */
+#define PI_PROT_OVERRD		0x000008 /* Clear CPU Protection bit 	    */
+#define	PI_IO_PROTECT		0x000010 /* Interrupt Pending Protection    */
+#define PI_REGION_PRESENT	0x000018 /* Indicates whether region exists */
+#define PI_CPU_NUM		0x000020 /* CPU Number ID 		    */
+#define PI_CALIAS_SIZE		0x000028 /* Cached Alias Size 		    */
+#define PI_MAX_CRB_TIMEOUT	0x000030 /* Maximum Timeout for CRB 	    */
+#define PI_CRB_SFACTOR		0x000038 /* Scale factor for CRB timeout    */
+
+/* CALIAS values */
+#define PI_CALIAS_SIZE_0	0
+#define PI_CALIAS_SIZE_4K	1
+#define PI_CALIAS_SIZE_8K	2
+#define PI_CALIAS_SIZE_16K	3
+#define PI_CALIAS_SIZE_32K	4
+#define PI_CALIAS_SIZE_64K	5
+#define PI_CALIAS_SIZE_128K	6
+#define PI_CALIAS_SIZE_256K	7
+#define PI_CALIAS_SIZE_512K	8
+#define PI_CALIAS_SIZE_1M	9
+#define PI_CALIAS_SIZE_2M	10
+#define PI_CALIAS_SIZE_4M	11
+#define PI_CALIAS_SIZE_8M	12
+#define PI_CALIAS_SIZE_16M	13
+#define PI_CALIAS_SIZE_32M	14
+#define PI_CALIAS_SIZE_64M	15
+
+/* Processor control and status checking */
+
+#define PI_CPU_PRESENT_A	0x000040 /* CPU Present A 		    */
+#define PI_CPU_PRESENT_B	0x000048 /* CPU Present B 		    */
+#define PI_CPU_ENABLE_A		0x000050 /* CPU Enable A 		    */
+#define PI_CPU_ENABLE_B		0x000058 /* CPU Enable B 		    */
+#define PI_REPLY_LEVEL		0x000060 /* Reply Level		 	    */
+#define PI_HARDRESET_BIT	0x020068 /* Bit cleared by s/w on SR	    */
+#define PI_NMI_A		0x000070 /* NMI to CPU A 		    */
+#define PI_NMI_B		0x000078 /* NMI to CPU B 		    */
+#define PI_NMI_OFFSET		(PI_NMI_B - PI_NMI_A)
+#define PI_SOFTRESET		0x000080 /* Softreset (to both CPUs) 	    */
+
+/* Regular Interrupt register checking.  */
+
+#define PI_INT_PEND_MOD		0x000090 /* Write to set pending ints	    */
+#define PI_INT_PEND0		0x000098 /* Read to get pending ints 	    */
+#define PI_INT_PEND1		0x0000a0 /* Read to get pending ints 	    */
+#define PI_INT_MASK0_A		0x0000a8 /* Interrupt Mask 0 for CPU A 	    */
+#define PI_INT_MASK1_A		0x0000b0 /* Interrupt Mask 1 for CPU A 	    */
+#define PI_INT_MASK0_B		0x0000b8 /* Interrupt Mask 0 for CPU B 	    */
+#define PI_INT_MASK1_B		0x0000c0 /* Interrupt Mask 1 for CPU B 	    */
+
+#define PI_INT_MASK_OFFSET	0x10	 /* Offset from A to B 		    */
+
+/* Crosscall interrupts */
+
+#define PI_CC_PEND_SET_A	0x0000c8 /* CC Interrupt Pending Set, CPU A */
+#define PI_CC_PEND_SET_B	0x0000d0 /* CC Interrupt Pending Set, CPU B */
+#define PI_CC_PEND_CLR_A	0x0000d8 /* CC Interrupt Pending Clr, CPU A */
+#define PI_CC_PEND_CLR_B	0x0000e0 /* CC Interrupt Pending Clr, CPU B */
+#define PI_CC_MASK		0x0000e8 /* CC Interrupt mask 		    */
+
+#define PI_INT_SET_OFFSET	0x08	 /* Offset from A to B 		    */
+
+/* Realtime Counter and Profiler control registers */
+
+#define PI_RT_COUNT		0x030100 /* Real Time Counter 		    */
+#define PI_RT_COMPARE_A		0x000108 /* Real Time Compare A 	    */
+#define PI_RT_COMPARE_B		0x000110 /* Real Time Compare B 	    */
+#define PI_PROFILE_COMPARE	0x000118 /* L5 int to both cpus when == RTC */
+#define PI_RT_PEND_A		0x000120 /* Set if RT int for A pending     */
+#define PI_RT_PEND_B		0x000128 /* Set if RT int for B pending     */
+#define PI_PROF_PEND_A		0x000130 /* Set if Prof int for A pending   */
+#define PI_PROF_PEND_B		0x000138 /* Set if Prof int for B pending   */
+#define PI_RT_EN_A		0x000140 /* RT int for CPU A enable 	    */
+#define PI_RT_EN_B		0x000148 /* RT int for CPU B enable 	    */
+#define PI_PROF_EN_A		0x000150 /* PROF int for CPU A enable 	    */
+#define PI_PROF_EN_B		0x000158 /* PROF int for CPU B enable 	    */
+#define PI_RT_LOCAL_CTRL	0x000160 /* RT control register 	    */
+#define PI_RT_FILTER_CTRL	0x000168 /* GCLK Filter control register    */
+
+#define PI_COUNT_OFFSET		0x08	 /* A to B offset for all counts    */
+
+/* Built-In Self Test support */
+
+#define PI_BIST_WRITE_DATA	0x000200 /* BIST write data 		    */
+#define PI_BIST_READ_DATA	0x000208 /* BIST read data 		    */
+#define PI_BIST_COUNT_TARG	0x000210 /* BIST Count and Target 	    */
+#define PI_BIST_READY		0x000218 /* BIST Ready indicator 	    */
+#define PI_BIST_SHIFT_LOAD	0x000220 /* BIST control 		    */
+#define PI_BIST_SHIFT_UNLOAD	0x000228 /* BIST control 		    */
+#define PI_BIST_ENTER_RUN	0x000230 /* BIST control 		    */
+
+/* Graphics control registers */
+
+#define PI_GFX_PAGE_A		0x000300 /* Graphics page A 		    */
+#define PI_GFX_CREDIT_CNTR_A	0x000308 /* Graphics credit counter A 	    */
+#define PI_GFX_BIAS_A		0x000310 /* Graphics bias A 		    */
+#define PI_GFX_INT_CNTR_A	0x000318 /* Graphics interrupt counter A    */
+#define PI_GFX_INT_CMP_A	0x000320 /* Graphics interrupt comparator A */
+#define PI_GFX_PAGE_B		0x000328 /* Graphics page B 		    */
+#define PI_GFX_CREDIT_CNTR_B	0x000330 /* Graphics credit counter B 	    */
+#define PI_GFX_BIAS_B		0x000338 /* Graphics bias B 		    */
+#define PI_GFX_INT_CNTR_B	0x000340 /* Graphics interrupt counter B    */
+#define PI_GFX_INT_CMP_B	0x000348 /* Graphics interrupt comparator B */
+
+#define PI_GFX_OFFSET		(PI_GFX_PAGE_B - PI_GFX_PAGE_A)
+#define PI_GFX_PAGE_ENABLE	0x0000010000000000LL
+
+/* Error and timeout registers */
+#define PI_ERR_INT_PEND		0x000400 /* Error Interrupt Pending	    */
+#define PI_ERR_INT_MASK_A	0x000408 /* Error Interrupt mask for CPU A  */
+#define PI_ERR_INT_MASK_B	0x000410 /* Error Interrupt mask for CPU B  */
+#define PI_ERR_STACK_ADDR_A	0x000418 /* Error stack address for CPU A   */ 
+#define PI_ERR_STACK_ADDR_B	0x000420 /* Error stack address for CPU B   */ 
+#define PI_ERR_STACK_SIZE	0x000428 /* Error Stack Size 		    */
+#define PI_ERR_STATUS0_A	0x000430 /* Error Status 0A 		    */
+#define PI_ERR_STATUS0_A_RCLR	0x000438 /* Error Status 0A clear on read   */
+#define PI_ERR_STATUS1_A	0x000440 /* Error Status 1A 		    */
+#define PI_ERR_STATUS1_A_RCLR	0x000448 /* Error Status 1A clear on read   */
+#define PI_ERR_STATUS0_B	0x000450 /* Error Status 0B 		    */
+#define PI_ERR_STATUS0_B_RCLR	0x000458 /* Error Status 0B clear on read   */
+#define PI_ERR_STATUS1_B	0x000460 /* Error Status 1B 		    */
+#define PI_ERR_STATUS1_B_RCLR	0x000468 /* Error Status 1B clear on read   */
+#define PI_SPOOL_CMP_A		0x000470 /* Spool compare for CPU A 	    */
+#define PI_SPOOL_CMP_B		0x000478 /* Spool compare for CPU B 	    */
+#define PI_CRB_TIMEOUT_A	0x000480 /* Timed out CRB entries for A     */
+#define PI_CRB_TIMEOUT_B	0x000488 /* Timed out CRB entries for B     */
+#define PI_SYSAD_ERRCHK_EN	0x000490 /* Enables SYSAD error checking    */
+#define PI_BAD_CHECK_BIT_A	0x000498 /* Force SYSAD check bit error     */
+#define PI_BAD_CHECK_BIT_B	0x0004a0 /* Force SYSAD check bit error     */
+#define PI_NACK_CNT_A		0x0004a8 /* Consecutive NACK counter 	    */
+#define PI_NACK_CNT_B		0x0004b0 /* 	"	" for CPU B 	    */
+#define PI_NACK_CMP		0x0004b8 /* NACK count compare		    */
+#define PI_STACKADDR_OFFSET	(PI_ERR_STACK_ADDR_B - PI_ERR_STACK_ADDR_A)
+#define PI_ERRSTAT_OFFSET	(PI_ERR_STATUS0_B - PI_ERR_STATUS0_A)
+#define PI_RDCLR_OFFSET		(PI_ERR_STATUS0_A_RCLR - PI_ERR_STATUS0_A)
+
+/* Bits in PI_ERR_INT_PEND */
+#define PI_ERR_SPOOL_CMP_B	0x00000001	/* Spool end hit high water */
+#define PI_ERR_SPOOL_CMP_A	0x00000002
+#define PI_ERR_SPUR_MSG_B	0x00000004	/* Spurious message intr.   */
+#define PI_ERR_SPUR_MSG_A	0x00000008
+#define PI_ERR_WRB_TERR_B	0x00000010	/* WRB TERR		    */
+#define PI_ERR_WRB_TERR_A	0x00000020
+#define PI_ERR_WRB_WERR_B	0x00000040	/* WRB WERR 		    */
+#define PI_ERR_WRB_WERR_A	0x00000080
+#define PI_ERR_SYSSTATE_B	0x00000100	/* SysState parity error    */
+#define PI_ERR_SYSSTATE_A	0x00000200
+#define PI_ERR_SYSAD_DATA_B	0x00000400	/* SysAD data parity error  */
+#define PI_ERR_SYSAD_DATA_A	0x00000800
+#define PI_ERR_SYSAD_ADDR_B	0x00001000	/* SysAD addr parity error  */
+#define PI_ERR_SYSAD_ADDR_A	0x00002000
+#define PI_ERR_SYSCMD_DATA_B	0x00004000	/* SysCmd data parity error */
+#define PI_ERR_SYSCMD_DATA_A	0x00008000
+#define PI_ERR_SYSCMD_ADDR_B	0x00010000	/* SysCmd addr parity error */
+#define PI_ERR_SYSCMD_ADDR_A	0x00020000
+#define PI_ERR_BAD_SPOOL_B	0x00040000	/* Error spooling to memory */
+#define PI_ERR_BAD_SPOOL_A	0x00080000
+#define PI_ERR_UNCAC_UNCORR_B	0x00100000	/* Uncached uncorrectable   */
+#define PI_ERR_UNCAC_UNCORR_A	0x00200000
+#define PI_ERR_SYSSTATE_TAG_B	0x00400000	/* SysState tag parity error */
+#define PI_ERR_SYSSTATE_TAG_A	0x00800000
+#define PI_ERR_MD_UNCORR	0x01000000	/* Must be cleared in MD    */
+
+#define PI_ERR_CLEAR_ALL_A	0x00aaaaaa
+#define PI_ERR_CLEAR_ALL_B	0x00555555
+
+
+/*
+ * The following three macros define all possible error int pends. 
+ */
+
+#define PI_FATAL_ERR_CPU_A	(PI_ERR_SYSSTATE_TAG_A 	| \
+				 PI_ERR_BAD_SPOOL_A 	| \
+				 PI_ERR_SYSCMD_ADDR_A 	| \
+				 PI_ERR_SYSCMD_DATA_A 	| \
+				 PI_ERR_SYSAD_ADDR_A 	| \
+				 PI_ERR_SYSAD_DATA_A	| \
+				 PI_ERR_SYSSTATE_A)
+
+#define PI_MISC_ERR_CPU_A	(PI_ERR_UNCAC_UNCORR_A 	| \
+				 PI_ERR_WRB_WERR_A 	| \
+				 PI_ERR_WRB_TERR_A 	| \
+				 PI_ERR_SPUR_MSG_A 	| \
+				 PI_ERR_SPOOL_CMP_A)
+
+#define PI_FATAL_ERR_CPU_B	(PI_ERR_SYSSTATE_TAG_B 	| \
+				 PI_ERR_BAD_SPOOL_B 	| \
+				 PI_ERR_SYSCMD_ADDR_B 	| \
+				 PI_ERR_SYSCMD_DATA_B 	| \
+				 PI_ERR_SYSAD_ADDR_B 	| \
+				 PI_ERR_SYSAD_DATA_B	| \
+				 PI_ERR_SYSSTATE_B)
+
+#define PI_MISC_ERR_CPU_B 	(PI_ERR_UNCAC_UNCORR_B  | \
+				 PI_ERR_WRB_WERR_B 	| \
+				 PI_ERR_WRB_TERR_B 	| \
+				 PI_ERR_SPUR_MSG_B 	| \
+				 PI_ERR_SPOOL_CMP_B)
+
+#define PI_ERR_GENERIC	(PI_ERR_MD_UNCORR)
+
+/*
+ * Error types for PI_ERR_STATUS0_[AB] and error stack:
+ * Use the write types if WRBRRB is 1 else use the read types
+ */
+
+/* Fields in PI_ERR_STATUS0_[AB] */
+#define PI_ERR_ST0_TYPE_MASK	0x0000000000000007
+#define PI_ERR_ST0_TYPE_SHFT	0
+#define PI_ERR_ST0_REQNUM_MASK	0x0000000000000038
+#define PI_ERR_ST0_REQNUM_SHFT	3
+#define PI_ERR_ST0_SUPPL_MASK	0x000000000001ffc0
+#define PI_ERR_ST0_SUPPL_SHFT	6
+#define PI_ERR_ST0_CMD_MASK	0x0000000001fe0000
+#define PI_ERR_ST0_CMD_SHFT	17
+#define PI_ERR_ST0_ADDR_MASK	0x3ffffffffe000000
+#define PI_ERR_ST0_ADDR_SHFT	25
+#define PI_ERR_ST0_OVERRUN_MASK	0x4000000000000000
+#define PI_ERR_ST0_OVERRUN_SHFT	62
+#define PI_ERR_ST0_VALID_MASK	0x8000000000000000
+#define PI_ERR_ST0_VALID_SHFT	63
+
+/* Fields in PI_ERR_STATUS1_[AB] */
+#define PI_ERR_ST1_SPOOL_MASK	0x00000000001fffff
+#define PI_ERR_ST1_SPOOL_SHFT	0
+#define PI_ERR_ST1_TOUTCNT_MASK	0x000000001fe00000
+#define PI_ERR_ST1_TOUTCNT_SHFT	21
+#define PI_ERR_ST1_INVCNT_MASK	0x0000007fe0000000
+#define PI_ERR_ST1_INVCNT_SHFT	29
+#define PI_ERR_ST1_CRBNUM_MASK	0x0000038000000000
+#define PI_ERR_ST1_CRBNUM_SHFT	39
+#define PI_ERR_ST1_WRBRRB_MASK	0x0000040000000000
+#define PI_ERR_ST1_WRBRRB_SHFT	42
+#define PI_ERR_ST1_CRBSTAT_MASK	0x001ff80000000000
+#define PI_ERR_ST1_CRBSTAT_SHFT	43
+#define PI_ERR_ST1_MSGSRC_MASK	0xffe0000000000000
+#define PI_ERR_ST1_MSGSRC_SHFT	53
+
+/* Fields in the error stack */
+#define PI_ERR_STK_TYPE_MASK	0x0000000000000003
+#define PI_ERR_STK_TYPE_SHFT	0
+#define PI_ERR_STK_SUPPL_MASK	0x0000000000000038
+#define PI_ERR_STK_SUPPL_SHFT	3
+#define PI_ERR_STK_REQNUM_MASK	0x00000000000001c0
+#define PI_ERR_STK_REQNUM_SHFT	6
+#define PI_ERR_STK_CRBNUM_MASK	0x0000000000000e00
+#define PI_ERR_STK_CRBNUM_SHFT	9
+#define PI_ERR_STK_WRBRRB_MASK	0x0000000000001000
+#define PI_ERR_STK_WRBRRB_SHFT	12
+#define PI_ERR_STK_CRBSTAT_MASK	0x00000000007fe000
+#define PI_ERR_STK_CRBSTAT_SHFT	13
+#define PI_ERR_STK_CMD_MASK	0x000000007f800000
+#define PI_ERR_STK_CMD_SHFT	23
+#define PI_ERR_STK_ADDR_MASK	0xffffffff80000000
+#define PI_ERR_STK_ADDR_SHFT	31
+
+/* Error type in the error status or stack on Read CRBs */
+#define PI_ERR_RD_PRERR		1
+#define PI_ERR_RD_DERR		2
+#define PI_ERR_RD_TERR		3
+
+/* Error type in the error status or stack on Write CRBs */
+#define PI_ERR_WR_WERR		0
+#define PI_ERR_WR_PWERR		1
+#define PI_ERR_WR_TERR		3
+
+/* Read or Write CRB in error status or stack */
+#define PI_ERR_RRB	0
+#define PI_ERR_WRB	1
+#define PI_ERR_ANY_CRB	2
+
+/* Address masks in the error status and error stack are not the same */
+#define ERR_STK_ADDR_SHFT	7
+#define ERR_STAT0_ADDR_SHFT	3
+
+#define PI_MIN_STACK_SIZE 4096	/* For figuring out the size to set */
+#define PI_STACK_SIZE_SHFT	12	/* 4k */
+
+#define ERR_STACK_SIZE_BYTES(_sz) \
+       ((_sz) ? (PI_MIN_STACK_SIZE << ((_sz) - 1)) : 0)
+
+#ifdef _LANGUAGE_C
+/*
+ * format of error stack and error status registers.
+ */
+
+struct err_stack_format {
+	u64	sk_addr	   : 33,   /* address */
+		sk_cmd	   :  8,   /* message command */
+		sk_crb_sts : 10,   /* status from RRB or WRB */
+		sk_rw_rb   :  1,   /* RRB == 0, WRB == 1 */
+		sk_crb_num :  3,   /* WRB (0 to 7) or RRB (0 to 4) */
+		sk_t5_req  :  3,   /* RRB T5 request number */
+		sk_suppl   :  3,   /* lowest 3 bit of supplemental */
+		sk_err_type:  3;   /* error type	*/
+};
+
+typedef union pi_err_stack {
+	u64	pi_stk_word;
+	struct	err_stack_format pi_stk_fmt;
+} pi_err_stack_t;
+
+struct err_status0_format {
+	u64	s0_valid   :  1,   /* Valid */
+		s0_ovr_run :  1,   /* Overrun, spooled to memory */
+		s0_addr	   : 37,   /* address */
+		s0_cmd	   :  8,   /* message command */
+		s0_supl	   : 11,   /* message supplemental field */
+		s0_t5_req  :  3,   /* RRB T5 request number */
+		s0_err_type:  3;   /* error type */
+};
+
+typedef union pi_err_stat0 {
+	u64	pi_stat0_word;
+	struct err_status0_format pi_stat0_fmt;
+} pi_err_stat0_t;
+
+struct err_status1_format {
+	u64	s1_src	   : 11,   /* message source */
+		s1_crb_sts : 10,   /* status from RRB or WRB */
+		s1_rw_rb   :  1,   /* RRB == 0, WRB == 1 */
+		s1_crb_num :  3,   /* WRB (0 to 7) or RRB (0 to 4) */
+		s1_inval_cnt:10,   /* signed invalidate counter RRB */
+		s1_to_cnt  :  8,   /* crb timeout counter */
+		s1_spl_cnt : 21;   /* number spooled to memory */
+};
+
+typedef union pi_err_stat1 {
+	u64	pi_stat1_word;
+	struct err_status1_format pi_stat1_fmt;
+} pi_err_stat1_t;
+
+typedef u64	rtc_time_t;
+
+#endif /* _LANGUAGE_C */
+
+
+/* Bits in PI_SYSAD_ERRCHK_EN */
+#define PI_SYSAD_ERRCHK_ECCGEN	0x01	/* Enable ECC generation	    */
+#define PI_SYSAD_ERRCHK_QUALGEN	0x02	/* Enable data quality signal gen.  */
+#define PI_SYSAD_ERRCHK_SADP	0x04	/* Enable SysAD parity checking     */
+#define PI_SYSAD_ERRCHK_CMDP	0x08	/* Enable SysCmd parity checking    */
+#define PI_SYSAD_ERRCHK_STATE	0x10	/* Enable SysState parity checking  */
+#define PI_SYSAD_ERRCHK_QUAL	0x20	/* Enable data quality checking     */
+#define PI_SYSAD_CHECK_ALL	0x3f	/* Generate and check all signals.  */
+
+/* Interrupt pending bits on R10000 */
+
+#define HUB_IP_PEND0		0x0400
+#define HUB_IP_PEND1_CC		0x0800
+#define HUB_IP_RT		0x1000
+#define HUB_IP_PROF		0x2000
+#define HUB_IP_ERROR		0x4000
+#define HUB_IP_MASK		0x7c00
+
+/* PI_RT_LOCAL_CTRL mask and shift definitions */
+
+#define PRLC_USE_INT_SHFT	16
+#define PRLC_USE_INT_MASK	(UINT64_CAST 1 << 16)
+#define PRLC_USE_INT		(UINT64_CAST 1 << 16)
+#define PRLC_GCLK_SHFT		15
+#define PRLC_GCLK_MASK		(UINT64_CAST 1 << 15)
+#define PRLC_GCLK		(UINT64_CAST 1 << 15)
+#define PRLC_GCLK_COUNT_SHFT	8
+#define PRLC_GCLK_COUNT_MASK	(UINT64_CAST 0x7f << 8)
+#define PRLC_MAX_COUNT_SHFT	1
+#define PRLC_MAX_COUNT_MASK	(UINT64_CAST 0x7f << 1)
+#define PRLC_GCLK_EN_SHFT	0
+#define PRLC_GCLK_EN_MASK	(UINT64_CAST 1)
+#define PRLC_GCLK_EN		(UINT64_CAST 1)
+
+/* PI_RT_FILTER_CTRL mask and shift definitions */
+
+#if 0
+/*
+ * XXX - This register's definition has changed, but it's only implemented
+ * in Hub 2.
+ */
+#define PRFC_DROP_COUNT_SHFT	27
+#define PRFC_DROP_COUNT_MASK	(UINT64_CAST 0x3ff << 27)
+#define PRFC_DROP_CTR_SHFT	18
+#define PRFC_DROP_CTR_MASK	(UINT64_CAST 0x1ff << 18)
+#define PRFC_MASK_ENABLE_SHFT	10
+#define PRFC_MASK_ENABLE_MASK	(UINT64_CAST 0x7f << 10)
+#define PRFC_MASK_CTR_SHFT	2
+#define PRFC_MASK_CTR_MASK	(UINT64_CAST 0xff << 2)
+#define PRFC_OFFSET_SHFT	0
+#define PRFC_OFFSET_MASK	(UINT64_CAST 3)
+#endif /* 0 */
+
+
+/*
+ * Bits for NACK_CNT_A/B and NACK_CMP
+ */
+#define PI_NACK_CNT_EN_SHFT	20
+#define PI_NACK_CNT_EN_MASK	0x100000
+#define PI_NACK_CNT_MASK	0x0fffff
+#define PI_NACK_CNT_MAX		0x0fffff
+
+#endif /* _ASM_SN_SN0_HUBPI_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/sn0/ip27.h linux/include/asm-mips64/sn/sn0/ip27.h
--- v2.3.47/linux/include/asm-mips64/sn/sn0/ip27.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/sn0/ip27.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,93 @@
+/* $Id: ip27.h,v 1.2 2000/01/26 06:11:50 kanoj Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/IP27.h>.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SN_SN0_IP27_H
+#define _ASM_SN_SN0_IP27_H
+
+#include <asm/mipsregs.h>
+
+/*
+ * Simple definitions for the masks which remove SW bits from pte.
+ */
+
+#define TLBLO_HWBITSHIFT	0		/* Shift value, for masking */
+
+#if !_LANGUAGE_ASSEMBLY
+
+#define CAUSE_BERRINTR 		IE_IRQ5
+
+#define ECCF_CACHE_ERR  0
+#define ECCF_TAGLO      1
+#define ECCF_ECC        2
+#define ECCF_ERROREPC   3
+#define ECCF_PADDR      4
+#define ECCF_SIZE       (5 * sizeof(long))
+
+#endif /* !_LANGUAGE_ASSEMBLY */
+
+#if _LANGUAGE_ASSEMBLY
+
+/*
+ * KL_GET_CPUNUM (similar to EV_GET_SPNUM for EVEREST platform) reads
+ * the processor number of the calling processor.  The proc parameters
+ * must be a register.
+ */
+#define KL_GET_CPUNUM(proc) 				\
+	dli	proc, LOCAL_HUB(0); 			\
+	ld	proc, PI_CPU_NUM(proc)
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/*
+ * R10000 status register interrupt bit mask usage for IP27.
+ */
+#define SRB_SWTIMO	IE_SW0		/* 0x0100 */
+#define SRB_NET		IE_SW1		/* 0x0200 */
+#define SRB_DEV0	IE_IRQ0		/* 0x0400 */
+#define SRB_DEV1	IE_IRQ1		/* 0x0800 */
+#define SRB_TIMOCLK	IE_IRQ2		/* 0x1000 */
+#define SRB_PROFCLK	IE_IRQ3		/* 0x2000 */
+#define SRB_ERR		IE_IRQ4		/* 0x4000 */
+#define SRB_SCHEDCLK	IE_IRQ5		/* 0x8000 */
+
+#define SR_IBIT_HI	SRB_DEV0
+#define SR_IBIT_PROF	SRB_PROFCLK
+
+#define SRB_SWTIMO_IDX		0
+#define SRB_NET_IDX		1
+#define SRB_DEV0_IDX		2
+#define SRB_DEV1_IDX		3
+#define SRB_TIMOCLK_IDX		4
+#define SRB_PROFCLK_IDX		5
+#define SRB_ERR_IDX		6
+#define SRB_SCHEDCLK_IDX	7
+
+#define NUM_CAUSE_INTRS		8
+
+#define SCACHE_LINESIZE	128
+#define SCACHE_LINEMASK	(SCACHE_LINESIZE - 1)
+
+#include <asm/sn/addrs.h>
+
+#define LED_CYCLE_MASK  0x0f
+#define LED_CYCLE_SHFT  4
+
+#define SEND_NMI(_nasid, _slice)	\
+          REMOTE_HUB_S((_nasid),  (PI_NMI_A + ((_slice) * PI_NMI_OFFSET)), 1)
+
+/* Sanity hazzard ...  Below all the Origin hacks are following.  */
+
+#define IOC3_SERIAL_INT		8
+#define IOC3_ETH_INT		9
+#define SCSI1_INT		1
+#define SCSI0_INT		0
+
+#endif /* _ASM_SN_SN0_IP27_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/sn0/sn0_fru.h linux/include/asm-mips64/sn/sn0/sn0_fru.h
--- v2.3.47/linux/include/asm-mips64/sn/sn0/sn0_fru.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/sn0/sn0_fru.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,45 @@
+/* $Id: sn0_fru.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/sn0_fru.h>
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_SN_SN0_SN0_FRU_H
+#define _ASM_SN_SN0_SN0_FRU_H
+
+#define MAX_DIMMS			8	 /* max # of dimm banks */
+#define MAX_PCIDEV			8	 /* max # of pci devices on a pci bus */
+
+typedef unsigned char confidence_t;
+
+typedef struct kf_mem_s {
+	confidence_t km_confidence; /* confidence level that the memory is bad 
+				     * is this necessary ? 
+				     */
+	confidence_t km_dimm[MAX_DIMMS];   
+	                            /* confidence level that dimm[i] is bad 
+				     *I think this is the right number
+				     */
+
+} kf_mem_t;
+
+typedef struct kf_cpu_s {
+	confidence_t  	kc_confidence; /* confidence level that cpu is bad */
+	confidence_t  	kc_icache; /* confidence level that instr. cache is bad */
+	confidence_t  	kc_dcache; /* confidence level that data   cache is bad */
+	confidence_t  	kc_scache; /* confidence level that sec.   cache is bad */
+	confidence_t	kc_sysbus; /* confidence level that sysad/cmd/state bus is bad */
+} kf_cpu_t;
+
+typedef struct kf_pci_bus_s {
+	confidence_t	kpb_belief;	/* confidence level  that the  pci bus is bad */
+	confidence_t	kpb_pcidev_belief[MAX_PCIDEV];
+	                                /* confidence level that the pci dev is bad */
+} kf_pci_bus_t;
+
+#endif /* _ASM_SN_SN0_SN0_FRU_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sn/types.h linux/include/asm-mips64/sn/types.h
--- v2.3.47/linux/include/asm-mips64/sn/types.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sn/types.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,24 @@
+/* $Id: types.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SN_TYPES_H
+#define _ASM_SN_TYPES_H
+
+#include <linux/types.h>
+
+typedef signed short	nasid_t;	/* node id in numa-as-id space */
+typedef signed short	cnodeid_t;	/* node id in compact-id space */
+typedef signed char	partid_t;	/* partition ID type */
+typedef signed short	moduleid_t;	/* user-visible module number type */
+typedef signed short	cmoduleid_t;	/* kernel compact module id type */
+typedef unsigned char	clusterid_t;	/* Clusterid of the cell */
+
+typedef dev_t		vertex_hdl_t;	/* hardware graph vertex handle */
+
+#endif /* _ASM_SN_TYPES_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/socket.h linux/include/asm-mips64/socket.h
--- v2.3.47/linux/include/asm-mips64/socket.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/socket.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,77 @@
+/* $Id: socket.h,v 1.1 1999/08/18 23:37:52 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1999 Ralf Baechle
+ */
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/*
+ * For setsockoptions(2)
+ *
+ * This defines are ABI conformant as far as Linux supports these ...
+ */
+#define SOL_SOCKET	0xffff
+
+#define SO_DEBUG	0x0001	/* Record debugging information.  */
+#define SO_REUSEADDR	0x0004	/* Allow reuse of local addresses.  */
+#define SO_KEEPALIVE	0x0008	/* Keep connections alive and send
+				   SIGPIPE when they die.  */
+#define SO_DONTROUTE	0x0010	/* Don't do local routing.  */
+#define SO_BROADCAST	0x0020	/* Allow transmission of
+				   broadcast messages.  */
+#define SO_LINGER	0x0080	/* Block on close of a reliable
+				   socket to transmit pending data.  */
+#define SO_OOBINLINE 0x0100	/* Receive out-of-band data in-band.  */
+#if 0
+To add: #define SO_REUSEPORT 0x0200	/* Allow local address and port reuse.  */
+#endif
+
+#define SO_TYPE		0x1008	/* Compatible name for SO_STYLE.  */
+#define SO_STYLE	SO_TYPE	/* Synonym */
+#define SO_ERROR	0x1007	/* get error status and clear */
+#define SO_SNDBUF	0x1001	/* Send buffer size. */
+#define SO_RCVBUF	0x1002	/* Receive buffer. */
+#define SO_SNDLOWAT	0x1003	/* send low-water mark */
+#define SO_RCVLOWAT	0x1004	/* receive low-water mark */
+#define SO_SNDTIMEO	0x1005	/* send timeout */
+#define SO_RCVTIMEO 	0x1006	/* receive timeout */
+
+/* linux-specific, might as well be the same as on i386 */
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_BSDCOMPAT	14
+
+#define SO_PASSCRED	17
+#define SO_PEERCRED	18
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE		25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+/* Types of sockets.  */
+#define SOCK_DGRAM 1		/* Connectionless, unreliable datagrams
+				   of fixed maximum length.  */
+#define SOCK_STREAM 2		/* Sequenced, reliable, connection-based
+				   byte streams.  */
+#define SOCK_RAW 3		/* Raw protocol interface.  */
+#define SOCK_RDM 4		/* Reliably-delivered messages.  */
+#define SOCK_SEQPACKET 5	/* Sequenced, reliable, connection-based,
+				   datagrams of fixed maximum length.  */
+#define SOCK_PACKET 10		/* Linux specific way of getting packets at
+				   the dev level.  For writing rarp and
+				   other similar things on the user level.  */
+
+#endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sockios.h linux/include/asm-mips64/sockios.h
--- v2.3.47/linux/include/asm-mips64/sockios.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sockios.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,24 @@
+/* $Id: sockios.h,v 1.1 1999/08/18 23:37:52 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SOCKIOS_H
+#define _ASM_SOCKIOS_H
+
+#include <asm/ioctl.h>
+
+/* Socket-level I/O control calls. */
+#define FIOGETOWN	_IOR('f', 123, int)
+#define FIOSETOWN 	_IOW('f', 124, int)
+
+#define SIOCATMARK	_IOR('s', 7, int)
+#define SIOCSPGRP	_IOW('s', 8, pid_t)
+#define SIOCGPGRP	_IOR('s', 9, pid_t)
+
+#define SIOCGSTAMP	0x8906			/* Get stamp - linux-specific */
+
+#endif /* _ASM_SOCKIOS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/softirq.h linux/include/asm-mips64/softirq.h
--- v2.3.47/linux/include/asm-mips64/softirq.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/softirq.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,26 @@
+/* $Id: softirq.h,v 1.3 2000/02/23 00:41:38 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SOFTIRQ_H
+#define _ASM_SOFTIRQ_H
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+extern unsigned int local_bh_count[NR_CPUS];
+
+#define cpu_bh_disable(cpu)	do { local_bh_count[(cpu)]++; barrier(); } while (0)
+#define cpu_bh_enable(cpu)	do { barrier(); local_bh_count[(cpu)]--; } while (0)
+
+#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
+#define local_bh_enable()	cpu_bh_enable(smp_processor_id())
+
+#define in_softirq() (local_bh_count[smp_processor_id()] != 0)
+
+#endif /* _ASM_SOFTIRQ_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/spinlock.h linux/include/asm-mips64/spinlock.h
--- v2.3.47/linux/include/asm-mips64/spinlock.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/spinlock.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,149 @@
+/* $Id: spinlock.h,v 1.4 2000/01/25 00:41:46 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SPINLOCK_H
+#define _ASM_SPINLOCK_H
+
+/*
+ * Your basic SMP spinlocks, allowing only a single CPU anywhere
+ */
+
+typedef struct {
+	volatile unsigned int lock;
+} spinlock_t;
+
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
+
+#define spin_lock_init(x)	do { (x)->lock = 0; } while(0);
+
+/*
+ * Simple spin lock operations.  There are two variants, one clears IRQ's
+ * on the local processor, one does not.
+ *
+ * We make no fairness assumptions.  They have a cost.
+ */
+
+typedef struct { unsigned long a[100]; } __dummy_lock_t;
+#define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
+
+static inline void spin_lock(spinlock_t *lock)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# spin_lock\n"
+	"1:\tll\t%1, %2\n\t"
+	"bnez\t%1, 1b\n\t"
+	" li\t%1, 1\n\t"
+	"sc\t%1, %0\n\t"
+	"beqz\t%1, 1b\n\t"
+	" sync\n\t"
+	".set\treorder"
+	: "=o" (__dummy_lock(lock)), "=&r" (tmp)
+	: "o" (__dummy_lock(lock))
+	: "memory");
+}
+
+static inline void spin_unlock(spinlock_t *lock)
+{
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# spin_unlock\n\t"
+	"sync\n\t"
+	"sw\t$0, %0\n\t"
+	".set\treorder"	
+	: "=o" (__dummy_lock(lock))
+	: "o" (__dummy_lock(lock))
+	: "memory");
+}
+
+#define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
+
+/*
+ * Read-write spinlocks, allowing multiple readers but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts but no interrupt
+ * writers. For those circumstances we can "mix" irq-safe locks - any writer
+ * needs to get a irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ */
+
+typedef struct {
+	volatile unsigned int lock;
+} rwlock_t;
+
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
+
+static inline void read_lock(rwlock_t *rw)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# read_lock\n"
+	"1:\tll\t%1, %2\n\t"
+	"bltz\t%1, 1b\n\t"
+	" addu\t%1, 1\n\t"
+	"sc\t%1, %0\n\t"
+	"beqz\t%1, 1b\n\t"
+	" sync\n\t"
+	".set\treorder"	
+	: "=o" (__dummy_lock(rw)), "=&r" (tmp)
+	: "o" (__dummy_lock(rw))
+	: "memory");
+}
+
+/* Note the use of sub, not subu which will make the kernel die with an
+   overflow exception if we ever try to unlock an rwlock that is already
+   unlocked or is being held by a writer.  */
+static inline void read_unlock(rwlock_t *rw)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# read_unlock\n"
+	"1:\tll\t%1, %2\n\t"
+	"sub\t%1, 1\n\t"
+	"sc\t%1, %0\n\t"
+	"beqz\t%1, 1b\n\t"
+	".set\treorder"	
+	: "=o" (__dummy_lock(rw)), "=&r" (tmp)
+	: "o" (__dummy_lock(rw))
+	: "memory");
+}
+
+static inline void write_lock(rwlock_t *rw)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# write_lock\n"
+	"1:\tll\t%1, %2\n\t"
+	"bnez\t%1, 1b\n\t"
+	" lui\t%1, 0x8000\n\t"
+	"sc\t%1, %0\n\t"
+	"beqz\t%1, 1b\n\t"
+	" sync\n\t"
+	".set\treorder"	
+	: "=o" (__dummy_lock(rw)), "=&r" (tmp)
+	: "o" (__dummy_lock(rw))
+	: "memory");
+}
+
+static inline void write_unlock(rwlock_t *rw)
+{
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# write_unlock\n\t"
+	"sync\n\t"
+	"sw\t$0, %0\n\t"
+	".set\treorder"	
+	: "=o" (__dummy_lock(rw))
+	: "o" (__dummy_lock(rw))
+	: "memory");
+}
+
+#endif /* _ASM_SPINLOCK_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/stackframe.h linux/include/asm-mips64/stackframe.h
--- v2.3.47/linux/include/asm-mips64/stackframe.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/stackframe.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,231 @@
+/* $Id: stackframe.h,v 1.4 2000/02/24 03:24:38 ulfc Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996 Paul M. Antoine.
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_STACKFRAME_H
+#define _ASM_STACKFRAME_H
+
+#include <asm/asm.h>
+#include <asm/offset.h>
+
+#ifdef _LANGUAGE_C
+
+#define __str2(x) #x
+#define __str(x) __str2(x)
+
+#define save_static(frame)                               \
+	__asm__ __volatile__(                            \
+		"sd\t$16,"__str(PT_R16)"(%0)\n\t"        \
+		"sd\t$17,"__str(PT_R17)"(%0)\n\t"        \
+		"sd\t$18,"__str(PT_R18)"(%0)\n\t"        \
+		"sd\t$19,"__str(PT_R19)"(%0)\n\t"        \
+		"sd\t$20,"__str(PT_R20)"(%0)\n\t"        \
+		"sd\t$21,"__str(PT_R21)"(%0)\n\t"        \
+		"sd\t$22,"__str(PT_R22)"(%0)\n\t"        \
+		"sd\t$23,"__str(PT_R23)"(%0)\n\t"        \
+		"sd\t$30,"__str(PT_R30)"(%0)\n\t"        \
+		: /* No outputs */                       \
+		: "r" (frame))
+
+#endif /* _LANGUAGE_C */
+
+#ifdef _LANGUAGE_ASSEMBLY
+
+		.macro	SAVE_AT
+		.set	push
+		.set	noat
+		sd	$1, PT_R1(sp)
+		.set	pop
+		.endm
+
+		.macro	SAVE_TEMP
+		mfhi	v1
+		sd	$8, PT_R8(sp)
+		sd	$9, PT_R9(sp)
+		sd	v1, PT_HI(sp)
+		mflo	v1
+		sd	$10, PT_R10(sp)
+		sd	$11, PT_R11(sp)
+		sd	v1,  PT_LO(sp)
+		sd	$12, PT_R12(sp)
+		sd	$13, PT_R13(sp)
+		sd	$14, PT_R14(sp)
+		sd	$15, PT_R15(sp)
+		sd	$24, PT_R24(sp)
+		.endm
+
+		.macro	SAVE_STATIC
+		sd	$16, PT_R16(sp)
+		sd	$17, PT_R17(sp)
+		sd	$18, PT_R18(sp)
+		sd	$19, PT_R19(sp)
+		sd	$20, PT_R20(sp)
+		sd	$21, PT_R21(sp)
+		sd	$22, PT_R22(sp)
+		sd	$23, PT_R23(sp)
+		sd	$30, PT_R30(sp)
+		.endm
+
+		.macro	SAVE_SOME
+		.set	push
+		.set	reorder
+		mfc0	k0, CP0_STATUS
+		sll	k0, 3		/* extract cu0 bit */
+		.set	noreorder
+		bltz	k0, 8f
+		 move	k1, sp
+		.set	reorder
+		/* Called from user mode, new stack. */
+		lui	k1, %hi(kernelsp)
+		ld	k1, %lo(kernelsp)(k1)
+8:		move	k0, sp
+		dsubu	sp, k1, PT_SIZE
+		sd	k0, PT_R29(sp)
+		sd	$3, PT_R3(sp)
+		sd	$0, PT_R0(sp)
+		dmfc0	v1, CP0_STATUS
+		sd	$2, PT_R2(sp)
+		sd	v1, PT_STATUS(sp)
+		sd	$4, PT_R4(sp)
+		dmfc0	v1, CP0_CAUSE
+		sd	$5, PT_R5(sp)
+		sd	v1, PT_CAUSE(sp)
+		sd	$6, PT_R6(sp)
+		dmfc0	v1, CP0_EPC
+		sd	$7, PT_R7(sp)
+		sd	v1, PT_EPC(sp)
+		sd	$25, PT_R25(sp)
+		sd	$28, PT_R28(sp)
+		sd	$31, PT_R31(sp)
+		ori	$28, sp, 0x3fff
+		xori	$28, 0x3fff
+		.set	pop
+		.endm
+
+		.macro	SAVE_ALL
+		SAVE_SOME
+		SAVE_AT
+		SAVE_TEMP
+		SAVE_STATIC
+		.endm
+
+		.macro	RESTORE_AT
+		.set	push
+		.set	noat
+		ld	$1,  PT_R1(sp)
+		.set	pop
+		.endm
+
+		.macro	RESTORE_SP
+		ld	sp,  PT_R29(sp)
+		.endm
+
+		.macro	RESTORE_TEMP
+		ld	$24, PT_LO(sp)
+		ld	$8, PT_R8(sp)
+		ld	$9, PT_R9(sp)
+		mtlo	$24
+		ld	$24, PT_HI(sp)
+		ld	$10, PT_R10(sp)
+		ld	$11, PT_R11(sp)
+		mthi	$24
+		ld	$12, PT_R12(sp)
+		ld	$13, PT_R13(sp)
+		ld	$14, PT_R14(sp)
+		ld	$15, PT_R15(sp)
+		ld	$24, PT_R24(sp)
+		.endm
+
+		.macro	RESTORE_STATIC
+		ld	$16, PT_R16(sp)
+		ld	$17, PT_R17(sp)
+		ld	$18, PT_R18(sp)
+		ld	$19, PT_R19(sp)
+		ld	$20, PT_R20(sp)
+		ld	$21, PT_R21(sp)
+		ld	$22, PT_R22(sp)
+		ld	$23, PT_R23(sp)
+		ld	$30, PT_R30(sp)
+		.endm
+
+		.macro	RESTORE_SOME
+		.set	push
+		.set	reorder
+		mfc0	t0, CP0_STATUS
+		.set	pop
+		ori	t0, 0x1f
+		xori	t0, 0x1f
+		mtc0	t0, CP0_STATUS
+		li	v1, 0xff00
+		and	t0, v1
+		ld	v0, PT_STATUS(sp)
+		nor	v1, $0, v1
+		and	v0, v1
+		or	v0, t0
+		dmtc0	v0, CP0_STATUS
+		ld	v1, PT_EPC(sp)
+		dmtc0	v1, CP0_EPC
+		ld	$31, PT_R31(sp)
+		ld	$28, PT_R28(sp)
+		ld	$25, PT_R25(sp)
+		ld	$7,  PT_R7(sp)
+		ld	$6,  PT_R6(sp)
+		ld	$5,  PT_R5(sp)
+		ld	$4,  PT_R4(sp)
+		ld	$3,  PT_R3(sp)
+		ld	$2,  PT_R2(sp)
+		.endm
+
+		.macro	RESTORE_ALL
+		RESTORE_SOME
+		RESTORE_AT
+		RESTORE_TEMP
+		RESTORE_STATIC
+		RESTORE_SP
+		.endm
+
+/*
+ * Move to kernel mode and disable interrupts.
+ * Set cp0 enable bit as sign that we're running on the kernel stack
+ */
+		.macro	CLI
+		mfc0	t0, CP0_STATUS
+		li	t1, ST0_CU0|0x1f
+		or	t0, t1
+		xori	t0, 0x1f
+		mtc0	t0, CP0_STATUS
+		.endm
+
+/*
+ * Move to kernel mode and enable interrupts.
+ * Set cp0 enable bit as sign that we're running on the kernel stack
+ */
+		.macro	STI
+		mfc0	t0, CP0_STATUS
+		li	t1, ST0_CU0 | 0x1f
+		or	t0, t1
+		xori	t0, 0x1e
+		mtc0	t0, CP0_STATUS
+		.endm
+
+/*
+ * Just move to kernel mode and leave interrupts as they are.
+ * Set cp0 enable bit as sign that we're running on the kernel stack
+ */
+		.macro	KMODE
+		mfc0	t0, CP0_STATUS
+		li	t1, ST0_CU0 | 0x1e
+		or	t0, t1
+		xori	t0, 0x1e
+		mtc0	t0, CP0_STATUS
+		.endm
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+#endif /* _ASM_STACKFRAME_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/stat.h linux/include/asm-mips64/stat.h
--- v2.3.47/linux/include/asm-mips64/stat.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/stat.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,62 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999 Ralf Baechle
+ */
+#ifndef _ASM_STAT_H
+#define _ASM_STAT_H
+
+#include <linux/types.h>
+
+struct __old_kernel_stat {
+	unsigned int	st_dev;
+	unsigned int	st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+	unsigned int	st_rdev;
+	long		st_size;
+	unsigned int	st_atime, st_res1;
+	unsigned int	st_mtime, st_res2;
+	unsigned int	st_ctime, st_res3;
+	unsigned int	st_blksize;
+	int		st_blocks;
+	unsigned int	st_flags;
+	unsigned int	st_gen;
+};
+
+struct stat {
+	dev_t		st_dev;
+	long		st_pad1[3];		/* Reserved for network id */
+	ino_t		st_ino;
+	mode_t		st_mode;
+	nlink_t		st_nlink;
+	uid_t		st_uid;
+	gid_t		st_gid;
+	dev_t		st_rdev;
+	long		st_pad2[2];
+	off_t		st_size;
+	long		st_pad3;
+	/*
+	 * Actually this should be timestruc_t st_atime, st_mtime and st_ctime
+	 * but we don't have it under Linux.
+	 */
+	time_t		st_atime;
+	long		reserved0;
+	time_t		st_mtime;
+	long		reserved1;
+	time_t		st_ctime;
+	long		reserved2;
+	long		st_blksize;
+	long		st_blocks;
+	char		st_fstype[16];	/* Filesystem type name */
+	long		st_pad4[8];
+	/* Linux specific fields */
+	unsigned int	st_flags;
+	unsigned int	st_gen;
+};
+
+#endif /* _ASM_STAT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/statfs.h linux/include/asm-mips64/statfs.h
--- v2.3.47/linux/include/asm-mips64/statfs.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/statfs.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,39 @@
+/* $Id: statfs.h,v 1.1 1999/08/18 23:37:52 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_STATFS_H
+#define _ASM_STATFS_H
+
+#include <linux/posix_types.h>
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t        fsid_t;
+
+#endif
+
+struct statfs {
+	long		f_type;
+#define f_fstyp f_type
+	long		f_bsize;
+	long		f_frsize;	/* Fragment size - unsupported */
+	long		f_blocks;
+	long		f_bfree;
+	long		f_files;
+	long		f_ffree;
+
+	/* Linux specials */
+	long	f_bavail;
+	__kernel_fsid_t	f_fsid;
+	long		f_namelen;
+	long		f_spare[6];
+};
+
+#endif /* _ASM_STATFS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/string.h linux/include/asm-mips64/string.h
--- v2.3.47/linux/include/asm-mips64/string.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/string.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,27 @@
+/* $Id: string.h,v 1.4 2000/01/16 01:37:19 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1994, 1995, 1996, 1997, 1998 by Ralf Baechle
+ *
+ * XXX For now I'm too lazy to fix the string functions, let's rely on the
+ * generic stuff.
+ */
+#ifndef _ASM_STRING_H
+#define _ASM_STRING_H
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *__s, int __c, size_t __count);
+
+#undef __HAVE_ARCH_MEMCPY
+//extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
+
+#undef __HAVE_ARCH_MEMMOVE
+//extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
+
+/* Don't build bcopy at all ...  */
+#define __HAVE_ARCH_BCOPY
+
+#endif /* _ASM_STRING_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/sysmips.h linux/include/asm-mips64/sysmips.h
--- v2.3.47/linux/include/asm-mips64/sysmips.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/sysmips.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,25 @@
+/* $Id: sysmips.h,v 1.1 1999/12/04 03:59:12 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999 by Ralf Baechle
+ * Copyright 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SYSMIPS_H
+#define _ASM_SYSMIPS_H
+
+/*
+ * Commands for the sysmips(2) call
+ *
+ * sysmips(2) is deprecated - though some existing software uses it.
+ * We only support the following commands.
+ */
+#define SETNAME                    1	/* set hostname                  */
+#define FLUSH_CACHE		   3	/* writeback and invalidate caches */
+#define MIPS_FIXADE                7	/* control address error fixing  */
+#define MIPS_RDNVRAM              10	/* read NVRAM */
+#define MIPS_ATOMIC_SET		2001	/* atomically set variable       */
+
+#endif /* _ASM_SYSMIPS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/system.h linux/include/asm-mips64/system.h
--- v2.3.47/linux/include/asm-mips64/system.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/system.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,228 @@
+/* $Id: system.h,v 1.5 2000/01/27 07:48:08 kanoj Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Modified further for R[236]000 by Paul M. Antoine, 1996
+ * Copyright (C) 1999 Silicon Graphics
+ */
+#ifndef _ASM_SYSTEM_H
+#define _ASM_SYSTEM_H
+
+#include <asm/sgidefs.h>
+#include <linux/kernel.h>
+
+extern __inline__ void
+__sti(void)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"mfc0\t$1,$12\n\t"
+		"ori\t$1,0x1f\n\t"
+		"xori\t$1,0x1e\n\t"
+		"mtc0\t$1,$12\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		: /* no outputs */
+		: /* no inputs */
+		: "$1", "memory");
+}
+
+/*
+ * For cli() we have to insert nops to make shure that the new value
+ * has actually arrived in the status register before the end of this
+ * macro.
+ * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
+ * no nops at all.
+ */
+extern __inline__ void
+__cli(void)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"mfc0\t$1,$12\n\t"
+		"ori\t$1,1\n\t"
+		"xori\t$1,1\n\t"
+		"mtc0\t$1,$12\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		: /* no outputs */
+		: /* no inputs */
+		: "$1", "memory");
+}
+
+#define __save_flags(x)                  \
+__asm__ __volatile__(                    \
+	".set\tnoreorder\n\t"            \
+	"mfc0\t%0,$12\n\t"               \
+	".set\treorder"                  \
+	: "=r" (x)                       \
+	: /* no inputs */                \
+	: "memory")
+
+#define __save_and_cli(x)                \
+__asm__ __volatile__(                    \
+	".set\tnoreorder\n\t"            \
+	".set\tnoat\n\t"                 \
+	"mfc0\t%0,$12\n\t"               \
+	"ori\t$1,%0,1\n\t"               \
+	"xori\t$1,1\n\t"                 \
+	"mtc0\t$1,$12\n\t"               \
+	"nop\n\t"                        \
+	"nop\n\t"                        \
+	"nop\n\t"                        \
+	".set\tat\n\t"                   \
+	".set\treorder"                  \
+	: "=r" (x)                       \
+	: /* no inputs */                \
+	: "$1", "memory")
+
+extern void __inline__
+__restore_flags(int flags)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		"mfc0\t$8,$12\n\t"
+		"li\t$9,0xff00\n\t"
+		"and\t$8,$9\n\t"
+		"nor\t$9,$0,$9\n\t"
+		"and\t%0,$9\n\t"
+		"or\t%0,$8\n\t"
+		"mtc0\t%0,$12\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		".set\treorder"
+		: /* no output */
+		: "r" (flags)
+		: "$8", "$9", "memory");
+}
+
+/*
+ * Non-SMP versions ...
+ */
+#define sti() __sti()
+#define cli() __cli()
+#define save_flags(x) __save_flags(x)
+#define save_and_cli(x) __save_and_cli(x)
+#define restore_flags(x) __restore_flags(x)
+
+/* For spinlocks etc */
+#define local_irq_save(x)	__save_and_cli(x);
+#define local_irq_restore(x)	__restore_flags(x);
+#define local_irq_disable()	__cli();
+#define local_irq_enable()	__sti();
+
+/*
+ * These are probably defined overly paranoid ...
+ */
+#define mb()						\
+__asm__ __volatile__(					\
+	"# prevent instructions being moved around\n\t"	\
+	".set\tnoreorder\n\t"				\
+	"# 8 nops to fool the R4400 pipeline\n\t"	\
+	"nop;nop;nop;nop;nop;nop;nop;nop\n\t"		\
+	".set\treorder"					\
+	: /* no output */				\
+	: /* no input */				\
+	: "memory")
+#define rmb() mb()
+#define wmb() mb()
+
+#define set_mb(var, value) \
+do { var = value; mb(); } while (0)
+
+#define set_rmb(var, value) \
+do { var = value; rmb(); } while (0)
+
+#define set_wmb(var, value) \
+do { var = value; wmb(); } while (0)
+
+#if !defined (_LANGUAGE_ASSEMBLY)
+/*
+ * switch_to(n) should switch tasks to task nr n, first
+ * checking that n isn't the current task, in which case it does nothing.
+ */
+extern asmlinkage void *resume(void *last, void *next);
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+
+#define prepare_to_switch()	do { } while(0)
+#define switch_to(prev,next,last) \
+do { \
+	(last) = resume(prev, next); \
+} while(0)
+
+extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
+{
+	unsigned long dummy;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"ll\t%0,(%1)\n"
+		"1:\tmove\t$1,%2\n\t"
+		"sc\t$1,(%1)\n\t"
+		"beqzl\t$1,1b\n\t"
+		"lld\t%0,(%1)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		: "=r" (val), "=r" (m), "=r" (dummy)
+		: "1" (m), "2" (val)
+		: "memory");
+
+	return val;
+}
+
+/*
+ * Only used for 64 bit kernel.
+ */
+extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val)
+{
+	unsigned long dummy;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"lld\t%0,(%1)\n"
+		"1:\tmove\t$1,%2\n\t"
+		"scd\t$1,(%1)\n\t"
+		"beqzl\t$1,1b\n\t"
+		"lld\t%0,(%1)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		: "=r" (val), "=r" (m), "=r" (dummy)
+		: "1" (m), "2" (val)
+		: "memory");
+
+	return val;
+}
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define tas(ptr) (xchg((ptr),1))
+
+/* This function doesn't exist, so you'll get a linker error if something
+   tries to do an invalid xchg().  */
+extern void __xchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+	switch (size) {
+		case 4:
+			return xchg_u32(ptr, x);
+		case 8:
+			return xchg_u64(ptr, x);
+	}
+	__xchg_called_with_bad_pointer();
+	return x;
+}
+
+extern void set_except_vector(int n, void *addr);
+
+#endif /* _ASM_SYSTEM_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/termbits.h linux/include/asm-mips64/termbits.h
--- v2.3.47/linux/include/asm-mips64/termbits.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/termbits.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,220 @@
+/* $Id: termbits.h,v 1.1 1999/08/18 23:37:52 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_TERMBITS_H
+#define _ASM_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char cc_t;
+#if (_MIPS_SZLONG == 32)
+typedef unsigned long speed_t;
+typedef unsigned long tcflag_t;
+#endif
+#if (_MIPS_SZLONG == 64)
+typedef __u32 speed_t;
+typedef __u32 tcflag_t;
+#endif
+
+/*
+ * The ABI says nothing about NCC but seems to use NCCS as
+ * replacement for it in struct termio
+ */
+#define NCCS	23
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+#define VINTR		 0		/* Interrupt character [ISIG].  */
+#define VQUIT		 1		/* Quit character [ISIG].  */
+#define VERASE		 2		/* Erase character [ICANON].  */
+#define VKILL		 3		/* Kill-line character [ICANON].  */
+#define VMIN		 4		/* Minimum number of bytes read at once [!ICANON].  */
+#define VTIME		 5		/* Time-out value (tenths of a second) [!ICANON].  */
+#define VEOL2		 6		/* Second EOL character [ICANON].  */
+#define VSWTC		 7		/* ??? */
+#define VSWTCH		VSWTC
+#define VSTART		 8		/* Start (X-ON) character [IXON, IXOFF].  */
+#define VSTOP		 9		/* Stop (X-OFF) character [IXON, IXOFF].  */
+#define VSUSP		10		/* Suspend character [ISIG].  */
+#if 0
+/*
+ * VDSUSP is not supported
+ */
+#define VDSUSP		11		/* Delayed suspend character [ISIG].  */
+#endif
+#define VREPRINT	12		/* Reprint-line character [ICANON].  */
+#define VDISCARD	13		/* Discard character [IEXTEN].  */
+#define VWERASE		14		/* Word-erase character [ICANON].  */
+#define VLNEXT		15		/* Literal-next character [IEXTEN].  */
+#define VEOF		16		/* End-of-file character [ICANON].  */
+#define VEOL		17		/* End-of-line character [ICANON].  */
+
+/* c_iflag bits */
+#define IGNBRK	0000001		/* Ignore break condition.  */
+#define BRKINT	0000002		/* Signal interrupt on break.  */
+#define IGNPAR	0000004		/* Ignore characters with parity errors.  */
+#define PARMRK	0000010		/* Mark parity and framing errors.  */
+#define INPCK	0000020		/* Enable input parity check.  */
+#define ISTRIP	0000040		/* Strip 8th bit off characters.  */
+#define INLCR	0000100		/* Map NL to CR on input.  */
+#define IGNCR	0000200		/* Ignore CR.  */
+#define ICRNL	0000400		/* Map CR to NL on input.  */
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define IUCLC	0001000		/* Map upper case to lower case on input.  */
+#endif
+#define IXON	0002000		/* Enable start/stop output control.  */
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define IXANY	0004000		/* Any character will restart after stop.  */
+#endif
+#define IXOFF	0010000		/* Enable start/stop input control.  */
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define IMAXBEL	0020000		/* Ring bell when input queue is full.  */
+#endif
+
+/* c_oflag bits */
+#define OPOST	0000001		/* Perform output processing.  */
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define OLCUC	0000002		/* Map lower case to upper case on output.  */
+#define ONLCR	0000004		/* Map NL to CR-NL on output.  */
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+/*
+#define PAGEOUT ???
+#define WRAP    ???
+ */
+#endif
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060		/* Number of bits per byte (mask).  */
+#define   CS5	0000000		/* 5 bits per byte.  */
+#define   CS6	0000020		/* 6 bits per byte.  */
+#define   CS7	0000040		/* 7 bits per byte.  */
+#define   CS8	0000060		/* 8 bits per byte.  */
+#define CSTOPB	0000100		/* Two stop bits instead of one.  */
+#define CREAD	0000200		/* Enable receiver.  */
+#define PARENB	0000400		/* Parity enable.  */
+#define PARODD	0001000		/* Odd parity instead of even.  */
+#define HUPCL	0002000		/* Hang up on last close.  */
+#define CLOCAL	0004000		/* Ignore modem status lines.  */
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CMSPAR    010000000000	/* mark or space (stick) parity */
+#define CRTSCTS	  020000000000		/* flow control */
+#endif
+
+/* c_lflag bits */
+#define ISIG	0000001		/* Enable signals.  */
+#define ICANON	0000002		/* Do erase and kill processing.  */
+#define XCASE	0000004
+#define ECHO	0000010		/* Enable echo.  */
+#define ECHOE	0000020		/* Visual erase for ERASE.  */
+#define ECHOK	0000040		/* Echo NL after KILL.  */
+#define ECHONL	0000100		/* Echo NL even if ECHO is off.  */
+#define NOFLSH	0000200		/* Disable flush after interrupt.  */
+#define IEXTEN	0000400		/* Enable DISCARD and LNEXT.  */
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define ECHOCTL	0001000		/* Echo control characters as ^X.  */
+#define ECHOPRT	0002000		/* Hardcopy visual erase.  */
+#define ECHOKE	0004000		/* Visual erase for KILL.  */
+#endif
+#define FLUSHO	0020000
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define PENDIN	0040000		/* Retype pending input (state).  */
+#endif
+#define TOSTOP	0100000		/* Send SIGTTOU for background output.  */
+#define ITOSTOP	TOSTOP
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0	/* Suspend output.  */
+#define	TCOON		1	/* Restart suspended output.  */
+#define	TCIOFF		2	/* Send a STOP character.  */
+#define	TCION		3	/* Send a START character.  */
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0	/* Discard data received but not yet read.  */
+#define	TCOFLUSH	1	/* Discard data written but not yet sent.  */
+#define	TCIOFLUSH	2	/* Discard all pending data.  */
+
+/* tcsetattr uses these */
+#define	TCSANOW		TCSETS	/* Change immediately.  */
+#define	TCSADRAIN	TCSETSW	/* Change when pending output is written.  */
+#define	TCSAFLUSH	TCSETSF	/* Flush pending input before changing.  */
+
+#endif /* _ASM_TERMBITS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/termios.h linux/include/asm-mips64/termios.h
--- v2.3.47/linux/include/asm-mips64/termios.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/termios.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,145 @@
+/* $Id: termios.h,v 1.3 2000/02/18 00:24:49 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996 by Ralf Baechle
+ */
+#ifndef _ASM_TERMIOS_H
+#define _ASM_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct sgttyb {
+	char	sg_ispeed;
+	char	sg_ospeed;
+	char	sg_erase;
+	char	sg_kill;
+	int	sg_flags;	/* SGI special - int, not short */
+};
+
+struct tchars {
+	char	t_intrc;
+	char	t_quitc;
+	char	t_startc;
+	char	t_stopc;
+	char	t_eofc;
+	char	t_brkc;
+};
+
+struct ltchars {
+        char    t_suspc;        /* stop process signal */
+        char    t_dsuspc;       /* delayed stop process signal */
+        char    t_rprntc;       /* reprint line */
+        char    t_flushc;       /* flush output (toggles) */
+        char    t_werasc;       /* word erase */
+        char    t_lnextc;       /* literal next character */
+};
+
+/* TIOCGSIZE, TIOCSSIZE not defined yet.  Only needed for SunOS source
+   compatibility anyway ... */
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC	8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	char c_line;			/* line discipline */
+	unsigned char c_cc[NCCS];	/* control characters */
+};
+
+#ifdef __KERNEL__
+/*
+ *	intr=^C		quit=^\		erase=del	kill=^U
+ *	vmin=\1		vtime=\0	eol2=\0		swtc=\0
+ *	start=^Q	stop=^S		susp=^Z		vdsusp=
+ *	reprint=^R	discard=^U	werase=^W	lnext=^V
+ *	eof=^D		eol=\0
+ */
+#define INIT_C_CC "\003\034\177\025\1\0\0\0\021\023\032\0\022\017\027\026\004\0"
+#endif
+
+/* modem lines */
+#define TIOCM_LE	0x001		/* line enable */
+#define TIOCM_DTR	0x002		/* data terminal ready */
+#define TIOCM_RTS	0x004		/* request to send */
+#define TIOCM_ST	0x010		/* secondary transmit */
+#define TIOCM_SR	0x020		/* secondary receive */
+#define TIOCM_CTS	0x040		/* clear to send */
+#define TIOCM_CAR	0x100		/* carrier detect */
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RNG	0x200		/* ring */
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_DSR	0x400		/* data set ready */
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6		/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved fo Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14	/* synchronous PPP */
+
+#ifdef __KERNEL__
+
+#include <linux/string.h>
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	unsigned short tmp; \
+	get_user(tmp, &(termio)->c_iflag); \
+	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+	get_user(tmp, &(termio)->c_oflag); \
+	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+	get_user(tmp, &(termio)->c_cflag); \
+	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+	get_user(tmp, &(termio)->c_lflag); \
+	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+	get_user((termios)->c_line, &(termio)->c_line); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line, &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif /* defined(__KERNEL__) */
+
+#endif /* _ASM_TERMIOS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/timex.h linux/include/asm-mips64/timex.h
--- v2.3.47/linux/include/asm-mips64/timex.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/timex.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,39 @@
+/* $Id: timex.h,v 1.1 1999/08/18 23:37:53 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 1999 by Ralf Baechle
+ *
+ * FIXME: For some of the supported machines this is dead wrong.
+ */
+#ifndef _ASM_TIMEX_H
+#define _ASM_TIMEX_H
+
+#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+/*
+ * Standard way to access the cycle counter.
+ * Currently only used on SMP for scheduling.
+ *
+ * Only the low 32 bits are available as a continuously counting entity. 
+ * But this only means we'll force a reschedule every 8 seconds or so,
+ * which isn't an evil thing.
+ *
+ * We know that all SMP capable CPUs have cycle counters.
+ */
+
+typedef unsigned int cycles_t;
+extern cycles_t cacheflush_time;
+
+static inline cycles_t get_cycles (void)
+{
+	return read_32bit_cp0_register(CP0_COUNT);
+}
+
+#endif /*  _ASM_TIMEX_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/types.h linux/include/asm-mips64/types.h
--- v2.3.47/linux/include/asm-mips64/types.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/types.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,77 @@
+/* $Id: types.h,v 1.3 2000/02/18 00:24:49 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_TYPES_H
+#define _ASM_TYPES_H
+
+typedef unsigned int umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if (_MIPS_SZLONG == 64)
+
+typedef __signed__ long __s64;
+typedef unsigned long __u64;
+
+#else
+ 
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+ 
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef __signed char s8;
+typedef unsigned char u8;
+
+typedef __signed short s16;
+typedef unsigned short u16;
+
+typedef __signed int s32;
+typedef unsigned int u32;
+
+#if (_MIPS_SZLONG == 64)
+
+typedef __signed__ long s64;
+typedef unsigned long u64;
+
+#else
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long s64;
+typedef unsigned long long u64;
+#endif
+
+#endif
+
+#define BITS_PER_LONG _MIPS_SZLONG
+
+typedef unsigned long dma_addr_t;
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_TYPES_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/uaccess.h linux/include/asm-mips64/uaccess.h
--- v2.3.47/linux/include/asm-mips64/uaccess.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/uaccess.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,471 @@
+/* $Id: uaccess.h,v 1.5 2000/02/21 18:05:07 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+
+#define STR(x)  __STR(x)
+#define __STR(x)  #x
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not.  If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ */
+#define KERNEL_DS	((mm_segment_t) { (unsigned long) 0L })
+#define USER_DS		((mm_segment_t) { (unsigned long) -1L })
+
+#define VERIFY_READ    0
+#define VERIFY_WRITE   1
+
+#define get_fs()        (current->thread.current_ds)
+#define get_ds()	(KERNEL_DS)
+#define set_fs(x)       (current->thread.current_ds=(x))
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+
+/*
+ * Is a address valid? This does a straighforward calculation rather
+ * than tests.
+ *
+ * Address valid if:
+ *  - "addr" doesn't have any high-bits set
+ *  - AND "size" doesn't have any high-bits set
+ *  - AND "addr+size" doesn't have any high-bits set
+ *  - OR we are in kernel mode.
+ */
+#define __access_ok(addr,size,mask) \
+        (((__signed__ long)((mask)&(addr | size | (addr+size)))) >= 0)
+#define __access_mask ((long)(get_fs().seg))
+
+#define access_ok(type,addr,size) \
+__access_ok(((unsigned long)(addr)),(size),__access_mask)
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type,addr,size) ? 0 : -EFAULT;
+}
+
+/*
+ * Uh, these should become the main single-value transfer routines ...
+ * They automatically use the right size if we just have the right
+ * pointer type ...
+ *
+ * As MIPS uses the same address space for kernel and user data, we
+ * can just do these as direct assignments.
+ *
+ * Careful to not
+ * (a) re-use the arguments for side effects (sizeof is ok)
+ * (b) require any knowledge of processes at this stage
+ */
+#define put_user(x,ptr)	__put_user_check((x),(ptr),sizeof(*(ptr)),__access_mask)
+#define get_user(x,ptr) __get_user_check((x),(ptr),sizeof(*(ptr)),__access_mask)
+
+/*
+ * The "__xxx" versions do not do address space checking, useful when
+ * doing multiple accesses to the same area (the user has to do the
+ * checks by hand with "access_ok()")
+ */
+#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+
+/*
+ * The "xxx_ret" versions return constant specified in third argument, if
+ * something bad happens. These macros can be optimized for the
+ * case of just returning from the function xxx_ret is used.
+ */
+
+#define put_user_ret(x,ptr,ret) ({ \
+if (put_user(x,ptr)) return ret; })
+
+#define get_user_ret(x,ptr,ret) ({ \
+if (get_user(x,ptr)) return ret; })
+
+#define __put_user_ret(x,ptr,ret) ({ \
+if (__put_user(x,ptr)) return ret; })
+
+#define __get_user_ret(x,ptr,ret) ({ \
+if (__get_user(x,ptr)) return ret; })
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) (*(struct __large_struct *)(x))
+
+#define __get_user_nocheck(x,ptr,size) ({ \
+long __gu_err; \
+__typeof(*(ptr)) __gu_val; \
+long __gu_addr; \
+__asm__("":"=r" (__gu_val)); \
+__gu_addr = (long) (ptr); \
+__asm__("":"=r" (__gu_err)); \
+switch (size) { \
+case 1: __get_user_asm("lb"); break; \
+case 2: __get_user_asm("lh"); break; \
+case 4: __get_user_asm("lw"); break; \
+case 8:  __get_user_asm("ld"); break; \
+default: __get_user_unknown(); break; \
+} x = (__typeof__(*(ptr))) __gu_val; __gu_err; })
+
+#define __get_user_check(x,ptr,size,mask) ({ \
+long __gu_err; \
+__typeof__(*(ptr)) __gu_val; \
+long __gu_addr; \
+__asm__("":"=r" (__gu_val)); \
+__gu_addr = (long) (ptr); \
+__asm__("":"=r" (__gu_err)); \
+if (__access_ok(__gu_addr,size,mask)) { \
+switch (size) { \
+case 1: __get_user_asm("lb"); break; \
+case 2: __get_user_asm("lh"); break; \
+case 4: __get_user_asm("lw"); break; \
+case 8: __get_user_asm("ld"); break; \
+default: __get_user_unknown(); break; \
+} } x = (__typeof__(*(ptr))) __gu_val; __gu_err; })
+
+#define __get_user_asm(insn) \
+({ \
+__asm__ __volatile__( \
+	"1:\t" insn "\t%1,%2\n\t" \
+	"move\t%0,$0\n" \
+	"2:\n\t" \
+	".section\t.fixup,\"ax\"\n" \
+	"3:\tli\t%0,%3\n\t" \
+	"move\t%1,$0\n\t" \
+	"j\t2b\n\t" \
+	".previous\n\t" \
+	".section\t__ex_table,\"a\"\n\t" \
+	".dword\t1b,3b\n\t" \
+	".previous" \
+	:"=r" (__gu_err), "=r" (__gu_val) \
+	:"o" (__m(__gu_addr)), "i" (-EFAULT)); })
+
+extern void __get_user_unknown(void);
+
+#define __put_user_nocheck(x,ptr,size) ({ \
+long __pu_err; \
+__typeof__(*(ptr)) __pu_val; \
+long __pu_addr; \
+__pu_val = (x); \
+__pu_addr = (long) (ptr); \
+__asm__("":"=r" (__pu_err)); \
+switch (size) { \
+case 1: __put_user_asm("sb"); break; \
+case 2: __put_user_asm("sh"); break; \
+case 4: __put_user_asm("sw"); break; \
+case 8: __put_user_asm("sd"); break; \
+default: __put_user_unknown(); break; \
+} __pu_err; })
+
+#define __put_user_check(x,ptr,size,mask) ({ \
+long __pu_err; \
+__typeof__(*(ptr)) __pu_val; \
+long __pu_addr; \
+__pu_val = (x); \
+__pu_addr = (long) (ptr); \
+__asm__("":"=r" (__pu_err)); \
+if (__access_ok(__pu_addr,size,mask)) { \
+switch (size) { \
+case 1: __put_user_asm("sb"); break; \
+case 2: __put_user_asm("sh"); break; \
+case 4: __put_user_asm("sw"); break; \
+case 8: __put_user_asm("sd"); break; \
+default: __put_user_unknown(); break; \
+} } __pu_err; })
+
+#define __put_user_asm(insn) \
+({ \
+__asm__ __volatile__( \
+	"1:\t" insn "\t%1,%2\n\t" \
+	"move\t%0,$0\n" \
+	"2:\n\t" \
+	".section\t.fixup,\"ax\"\n" \
+	"3:\tli\t%0,%3\n\t" \
+	"j\t2b\n\t" \
+	".previous\n\t" \
+	".section\t__ex_table,\"a\"\n\t" \
+	".dword\t1b,3b\n\t" \
+	".previous" \
+	:"=r" (__pu_err) \
+	:"r" (__pu_val), "o" (__m(__pu_addr)), "i" (-EFAULT)); })
+
+extern void __put_user_unknown(void);
+
+/*
+ * We're generating jump to subroutines which will be outside the range of
+ * jump instructions
+ */
+#ifdef MODULE
+#define __MODULE_JAL(destination) \
+	".set\tnoat\n\t" \
+	"la\t$1, " #destination "\n\t" \
+	"jalr\t$1\n\t" \
+	".set\tat\n\t"
+#else
+#define __MODULE_JAL(destination) \
+	"jal\t" #destination "\n\t"
+#endif
+
+#define copy_to_user_ret(to,from,n,retval) ({ \
+if (copy_to_user(to,from,n)) \
+        return retval; \
+})
+
+#define copy_from_user_ret(to,from,n,retval) ({ \
+if (copy_from_user(to,from,n)) \
+        return retval; \
+})
+
+extern size_t __copy_user(void *__to, const void *__from, size_t __n);
+
+#define __copy_to_user(to,from,n) ({ \
+	void *__cu_to; \
+	const void *__cu_from; \
+	long __cu_len; \
+	\
+	__cu_to = (to); \
+	__cu_from = (from); \
+	__cu_len = (n); \
+	__asm__ __volatile__( \
+		"move\t$4, %1\n\t" \
+		"move\t$5, %2\n\t" \
+		"move\t$6, %3\n\t" \
+		__MODULE_JAL(__copy_user) \
+		"move\t%0, $6" \
+		: "=r" (__cu_len) \
+		: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
+		: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$15", \
+		  "$24", "$31","memory"); \
+	__cu_len; \
+})
+
+#define __copy_from_user(to,from,n) ({ \
+	void *__cu_to; \
+	const void *__cu_from; \
+	long __cu_len; \
+	\
+	__cu_to = (to); \
+	__cu_from = (from); \
+	__cu_len = (n); \
+	__asm__ __volatile__( \
+		"move\t$4, %1\n\t" \
+		"move\t$5, %2\n\t" \
+		"move\t$6, %3\n\t" \
+		".set\tnoreorder\n\t" \
+		__MODULE_JAL(__copy_user) \
+		".set\tnoat\n\t" \
+		"daddu\t$1, %2, %3\n\t" \
+		".set\tat\n\t" \
+		".set\treorder\n\t" \
+		"move\t%0, $6" \
+		: "=r" (__cu_len) \
+		: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
+		: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$15", \
+		  "$24", "$31","memory"); \
+	__cu_len; \
+})
+
+#define copy_to_user(to,from,n) ({ \
+	void *__cu_to; \
+	const void *__cu_from; \
+	long __cu_len; \
+	\
+	__cu_to = (to); \
+	__cu_from = (from); \
+	__cu_len = (n); \
+	if (access_ok(VERIFY_WRITE, __cu_to, __cu_len)) \
+		__asm__ __volatile__( \
+			"move\t$4, %1\n\t" \
+			"move\t$5, %2\n\t" \
+			"move\t$6, %3\n\t" \
+			__MODULE_JAL(__copy_user) \
+			"move\t%0, $6" \
+			: "=r" (__cu_len) \
+			: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
+			: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", \
+			  "$15", "$24", "$31","memory"); \
+	__cu_len; \
+})
+
+#define copy_from_user(to,from,n) ({ \
+	void *__cu_to; \
+	const void *__cu_from; \
+	long __cu_len; \
+	\
+	__cu_to = (to); \
+	__cu_from = (from); \
+	__cu_len = (n); \
+	if (access_ok(VERIFY_READ, __cu_from, __cu_len)) \
+		__asm__ __volatile__( \
+			"move\t$4, %1\n\t" \
+			"move\t$5, %2\n\t" \
+			"move\t$6, %3\n\t" \
+			".set\tnoreorder\n\t" \
+			__MODULE_JAL(__copy_user) \
+			".set\tnoat\n\t" \
+			"daddu\t$1, %2, %3\n\t" \
+			".set\tat\n\t" \
+			".set\treorder\n\t" \
+			"move\t%0, $6" \
+			: "=r" (__cu_len) \
+			: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
+			: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", \
+			  "$15", "$24", "$31","memory"); \
+	__cu_len; \
+})
+
+extern inline __kernel_size_t
+__clear_user(void *addr, __kernel_size_t size)
+{
+	__kernel_size_t res;
+
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		"move\t$5, $0\n\t"
+		"move\t$6, %2\n\t"
+		__MODULE_JAL(__bzero)
+		"move\t%0, $6"
+		: "=r" (res)
+		: "r" (addr), "r" (size)
+		: "$4", "$5", "$6", "$8", "$9", "$31");
+
+	return res;
+}
+
+#define clear_user(addr,n) ({ \
+void * __cl_addr = (addr); \
+unsigned long __cl_size = (n); \
+if (__cl_size && __access_ok(VERIFY_WRITE, ((unsigned long)(__cl_addr)), __cl_size)) \
+__cl_size = __clear_user(__cl_addr, __cl_size); \
+__cl_size; })
+
+/*
+ * Returns: -EFAULT if exception before terminator, N if the entire
+ * buffer filled, else strlen.
+ */
+extern inline long
+__strncpy_from_user(char *__to, const char *__from, long __len)
+{
+	long res;
+
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		"move\t$5, %2\n\t"
+		"move\t$6, %3\n\t"
+		__MODULE_JAL(__strncpy_from_user_nocheck_asm)
+		"move\t%0, $2"
+		: "=r" (res)
+		: "r" (__to), "r" (__from), "r" (__len)
+		: "$2", "$3", "$4", "$5", "$6", "$8", "$31", "memory");
+
+	return res;
+}
+
+extern inline long
+strncpy_from_user(char *__to, const char *__from, long __len)
+{
+	long res;
+
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		"move\t$5, %2\n\t"
+		"move\t$6, %3\n\t"
+		__MODULE_JAL(__strncpy_from_user_asm)
+		"move\t%0, $2"
+		: "=r" (res)
+		: "r" (__to), "r" (__from), "r" (__len)
+		: "$2", "$3", "$4", "$5", "$6", "$8", "$31", "memory");
+
+	return res;
+}
+
+/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
+extern inline long __strlen_user(const char *s)
+{
+	long res;
+
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		__MODULE_JAL(__strlen_user_nocheck_asm)
+		"move\t%0, $2"
+		: "=r" (res)
+		: "r" (s)
+		: "$2", "$4", "$8", "$31");
+
+	return res;
+}
+
+extern inline long strlen_user(const char *s)
+{
+	long res;
+
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		__MODULE_JAL(__strlen_user_asm)
+		"move\t%0, $2"
+		: "=r" (res)
+		: "r" (s)
+		: "$2", "$4", "$8", "$31");
+
+	return res;
+}
+
+/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
+extern inline long __strnlen_user(const char *s, long n)
+{
+	long res;
+
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		"move\t$5, %2\n\t"
+		__MODULE_JAL(__strlen_user_nocheck_asm)
+		"move\t%0, $2"
+		: "=r" (res)
+		: "r" (s), "r" (n)
+		: "$2", "$4", "$5", "$8", "$31");
+
+	return res;
+}
+
+extern inline long strnlen_user(const char *s, long n)
+{
+	long res;
+
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		"move\t$5, %2\n\t"
+		__MODULE_JAL(__strlen_user_asm)
+		"move\t%0, $2"
+		: "=r" (res)
+		: "r" (s), "r" (n)
+		: "$2", "$4", "$5", "$8", "$31");
+
+	return res;
+}
+
+struct exception_table_entry
+{
+	unsigned long insn;
+	unsigned long nextinsn;
+};
+
+/* Returns 0 if exception not found and fixup.unit otherwise.  */
+extern unsigned long search_exception_table(unsigned long addr);
+
+/* Returns the new pc */
+#define fixup_exception(map_reg, fixup_unit, pc)                \
+({                                                              \
+	fixup_unit;                                             \
+})
+
+#endif /* _ASM_UACCESS_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/ucontext.h linux/include/asm-mips64/ucontext.h
--- v2.3.47/linux/include/asm-mips64/ucontext.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/ucontext.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,22 @@
+/* $Id: ucontext.h,v 1.1 1999/09/28 22:27:20 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Low level exception handling
+ *
+ * Copyright (C) 1998, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_UCONTEXT_H
+#define _ASM_UCONTEXT_H
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* _ASM_UCONTEXT_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/unaligned.h linux/include/asm-mips64/unaligned.h
--- v2.3.47/linux/include/asm-mips64/unaligned.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/unaligned.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,146 @@
+/* $Id: unaligned.h,v 1.1 1999/08/19 22:56:35 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_UNALIGNED_H
+#define _ASM_UNALIGNED_H
+
+extern void __get_unaligned_bad_length(void);
+extern void __put_unaligned_bad_length(void);
+
+/*
+ * Load quad unaligned.
+ */
+extern __inline__ unsigned long ldq_u(const unsigned long long * __addr)
+{
+	unsigned long long __res;
+
+	__asm__("uld\t%0,(%1)"
+		:"=&r" (__res)
+		:"r" (__addr));
+
+	return __res;
+}
+
+/*
+ * Load long unaligned.
+ */
+extern __inline__ unsigned long ldl_u(const unsigned int * __addr)
+{
+	unsigned long __res;
+
+	__asm__("ulw\t%0,(%1)"
+		:"=&r" (__res)
+		:"r" (__addr));
+
+	return __res;
+}
+
+/*
+ * Load word unaligned.
+ */
+extern __inline__ unsigned long ldw_u(const unsigned short * __addr)
+{
+	unsigned long __res;
+
+	__asm__("ulh\t%0,(%1)"
+		:"=&r" (__res)
+		:"r" (__addr));
+
+	return __res;
+}
+
+/*
+ * Store quad ununaligned.
+ */
+extern __inline__ void stq_u(unsigned long __val, unsigned long long * __addr)
+{
+	__asm__ __volatile__(
+		"usd\t%0,(%1)"
+		: /* No results */
+		:"r" (__val),
+		 "r" (__addr));
+}
+
+/*
+ * Store long ununaligned.
+ */
+extern __inline__ void stl_u(unsigned long __val, unsigned int * __addr)
+{
+	__asm__ __volatile__(
+		"usw\t%0,(%1)"
+		: /* No results */
+		:"r" (__val),
+		 "r" (__addr));
+}
+
+/*
+ * Store word ununaligned.
+ */
+extern __inline__ void stw_u(unsigned long __val, unsigned short * __addr)
+{
+	__asm__ __volatile__(
+		"ush\t%0,(%1)"
+		: /* No results */
+		:"r" (__val),
+		 "r" (__addr));
+}
+
+extern inline unsigned long __get_unaligned(const void *ptr, size_t size)
+{
+	unsigned long val;
+	switch (size) {
+	case 1:
+		val = *(const unsigned char *)ptr;
+		break;
+	case 2:
+		val = ldw_u((const unsigned short *)ptr);
+		break;
+	case 4:
+		val = ldl_u((const unsigned int *)ptr);
+		break;
+	case 8:
+		val = ldq_u((const unsigned long long *)ptr);
+		break;
+	default:
+		__get_unaligned_bad_length();
+		break;
+	}
+	return val;
+}
+
+extern inline void __put_unaligned(unsigned long val, void *ptr, size_t size)
+{
+	switch (size) {
+	case 1:
+		*(unsigned char *)ptr = (val);
+		break;
+	case 2:
+		stw_u(val, (unsigned short *)ptr);
+		break;
+	case 4:
+		stl_u(val, (unsigned int *)ptr);
+		break;
+	case 8:
+		stq_u(val, (unsigned long long *)ptr);
+		break;
+	default:
+		__put_unaligned_bad_length();
+		break;
+	}
+}
+
+/* 
+ * The main single-value unaligned transfer routines.
+ */
+#define get_unaligned(ptr) \
+	((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr))))
+#define put_unaligned(x,ptr) \
+	__put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr)))
+
+#endif /* _ASM_UNALIGNED_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/unistd.h linux/include/asm-mips64/unistd.h
--- v2.3.47/linux/include/asm-mips64/unistd.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/unistd.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,1764 @@
+/* $Id: unistd.h,v 1.10 2000/02/18 00:24:49 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto
+ * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A
+ */
+#ifndef _ASM_UNISTD_H
+#define _ASM_UNISTD_H
+
+/*
+ * The syscalls 0 - 3999 are reserved for a down to the root syscall
+ * compatibility with RISC/os and IRIX.  We'll see how to deal with the
+ * various "real" BSD variants like Ultrix, NetBSD ...
+ */
+
+/*
+ * SVR4 syscalls are in the range from 1 to 999
+ */
+#define __NR_SVR4			0
+#define __NR_SVR4_syscall		(__NR_SVR4 +   0)
+#define __NR_SVR4_exit			(__NR_SVR4 +   1)
+#define __NR_SVR4_fork			(__NR_SVR4 +   2)
+#define __NR_SVR4_read			(__NR_SVR4 +   3)
+#define __NR_SVR4_write			(__NR_SVR4 +   4)
+#define __NR_SVR4_open			(__NR_SVR4 +   5)
+#define __NR_SVR4_close			(__NR_SVR4 +   6)
+#define __NR_SVR4_wait			(__NR_SVR4 +   7)
+#define __NR_SVR4_creat			(__NR_SVR4 +   8)
+#define __NR_SVR4_link			(__NR_SVR4 +   9)
+#define __NR_SVR4_unlink		(__NR_SVR4 +  10)
+#define __NR_SVR4_exec			(__NR_SVR4 +  11)
+#define __NR_SVR4_chdir			(__NR_SVR4 +  12)
+#define __NR_SVR4_gtime			(__NR_SVR4 +  13)
+#define __NR_SVR4_mknod			(__NR_SVR4 +  14)
+#define __NR_SVR4_chmod			(__NR_SVR4 +  15)
+#define __NR_SVR4_chown			(__NR_SVR4 +  16)
+#define __NR_SVR4_sbreak		(__NR_SVR4 +  17)
+#define __NR_SVR4_stat			(__NR_SVR4 +  18)
+#define __NR_SVR4_lseek			(__NR_SVR4 +  19)
+#define __NR_SVR4_getpid		(__NR_SVR4 +  20)
+#define __NR_SVR4_mount			(__NR_SVR4 +  21)
+#define __NR_SVR4_umount		(__NR_SVR4 +  22)
+#define __NR_SVR4_setuid		(__NR_SVR4 +  23)
+#define __NR_SVR4_getuid		(__NR_SVR4 +  24)
+#define __NR_SVR4_stime			(__NR_SVR4 +  25)
+#define __NR_SVR4_ptrace		(__NR_SVR4 +  26)
+#define __NR_SVR4_alarm			(__NR_SVR4 +  27)
+#define __NR_SVR4_fstat			(__NR_SVR4 +  28)
+#define __NR_SVR4_pause			(__NR_SVR4 +  29)
+#define __NR_SVR4_utime			(__NR_SVR4 +  30)
+#define __NR_SVR4_stty			(__NR_SVR4 +  31)
+#define __NR_SVR4_gtty			(__NR_SVR4 +  32)
+#define __NR_SVR4_access		(__NR_SVR4 +  33)
+#define __NR_SVR4_nice			(__NR_SVR4 +  34)
+#define __NR_SVR4_statfs		(__NR_SVR4 +  35)
+#define __NR_SVR4_sync			(__NR_SVR4 +  36)
+#define __NR_SVR4_kill			(__NR_SVR4 +  37)
+#define __NR_SVR4_fstatfs		(__NR_SVR4 +  38)
+#define __NR_SVR4_setpgrp		(__NR_SVR4 +  39)
+#define __NR_SVR4_cxenix		(__NR_SVR4 +  40)
+#define __NR_SVR4_dup			(__NR_SVR4 +  41)
+#define __NR_SVR4_pipe			(__NR_SVR4 +  42)
+#define __NR_SVR4_times			(__NR_SVR4 +  43)
+#define __NR_SVR4_profil		(__NR_SVR4 +  44)
+#define __NR_SVR4_plock			(__NR_SVR4 +  45)
+#define __NR_SVR4_setgid		(__NR_SVR4 +  46)
+#define __NR_SVR4_getgid		(__NR_SVR4 +  47)
+#define __NR_SVR4_sig			(__NR_SVR4 +  48)
+#define __NR_SVR4_msgsys		(__NR_SVR4 +  49)
+#define __NR_SVR4_sysmips		(__NR_SVR4 +  50)
+#define __NR_SVR4_sysacct		(__NR_SVR4 +  51)
+#define __NR_SVR4_shmsys		(__NR_SVR4 +  52)
+#define __NR_SVR4_semsys		(__NR_SVR4 +  53)
+#define __NR_SVR4_ioctl			(__NR_SVR4 +  54)
+#define __NR_SVR4_uadmin		(__NR_SVR4 +  55)
+#define __NR_SVR4_exch 			(__NR_SVR4 +  56)
+#define __NR_SVR4_utssys		(__NR_SVR4 +  57)
+#define __NR_SVR4_fsync			(__NR_SVR4 +  58)
+#define __NR_SVR4_exece			(__NR_SVR4 +  59)
+#define __NR_SVR4_umask			(__NR_SVR4 +  60)
+#define __NR_SVR4_chroot		(__NR_SVR4 +  61)
+#define __NR_SVR4_fcntl			(__NR_SVR4 +  62)
+#define __NR_SVR4_ulimit		(__NR_SVR4 +  63)
+#define __NR_SVR4_reserved1		(__NR_SVR4 +  64)
+#define __NR_SVR4_reserved2		(__NR_SVR4 +  65)
+#define __NR_SVR4_reserved3		(__NR_SVR4 +  66)
+#define __NR_SVR4_reserved4		(__NR_SVR4 +  67)
+#define __NR_SVR4_reserved5		(__NR_SVR4 +  68)
+#define __NR_SVR4_reserved6		(__NR_SVR4 +  69)
+#define __NR_SVR4_advfs			(__NR_SVR4 +  70)
+#define __NR_SVR4_unadvfs		(__NR_SVR4 +  71)
+#define __NR_SVR4_unused1		(__NR_SVR4 +  72)
+#define __NR_SVR4_unused2		(__NR_SVR4 +  73)
+#define __NR_SVR4_rfstart		(__NR_SVR4 +  74)
+#define __NR_SVR4_unused3		(__NR_SVR4 +  75)
+#define __NR_SVR4_rdebug		(__NR_SVR4 +  76)
+#define __NR_SVR4_rfstop		(__NR_SVR4 +  77)
+#define __NR_SVR4_rfsys			(__NR_SVR4 +  78)
+#define __NR_SVR4_rmdir			(__NR_SVR4 +  79)
+#define __NR_SVR4_mkdir			(__NR_SVR4 +  80)
+#define __NR_SVR4_getdents		(__NR_SVR4 +  81)
+#define __NR_SVR4_libattach		(__NR_SVR4 +  82)
+#define __NR_SVR4_libdetach		(__NR_SVR4 +  83)
+#define __NR_SVR4_sysfs			(__NR_SVR4 +  84)
+#define __NR_SVR4_getmsg		(__NR_SVR4 +  85)
+#define __NR_SVR4_putmsg		(__NR_SVR4 +  86)
+#define __NR_SVR4_poll			(__NR_SVR4 +  87)
+#define __NR_SVR4_lstat			(__NR_SVR4 +  88)
+#define __NR_SVR4_symlink		(__NR_SVR4 +  89)
+#define __NR_SVR4_readlink		(__NR_SVR4 +  90)
+#define __NR_SVR4_setgroups		(__NR_SVR4 +  91)
+#define __NR_SVR4_getgroups		(__NR_SVR4 +  92)
+#define __NR_SVR4_fchmod		(__NR_SVR4 +  93)
+#define __NR_SVR4_fchown		(__NR_SVR4 +  94)
+#define __NR_SVR4_sigprocmask		(__NR_SVR4 +  95)
+#define __NR_SVR4_sigsuspend		(__NR_SVR4 +  96)
+#define __NR_SVR4_sigaltstack		(__NR_SVR4 +  97)
+#define __NR_SVR4_sigaction		(__NR_SVR4 +  98)
+#define __NR_SVR4_sigpending		(__NR_SVR4 +  99)
+#define __NR_SVR4_setcontext		(__NR_SVR4 + 100)
+#define __NR_SVR4_evsys			(__NR_SVR4 + 101)
+#define __NR_SVR4_evtrapret		(__NR_SVR4 + 102)
+#define __NR_SVR4_statvfs		(__NR_SVR4 + 103)
+#define __NR_SVR4_fstatvfs		(__NR_SVR4 + 104)
+#define __NR_SVR4_reserved7		(__NR_SVR4 + 105)
+#define __NR_SVR4_nfssys		(__NR_SVR4 + 106)
+#define __NR_SVR4_waitid		(__NR_SVR4 + 107)
+#define __NR_SVR4_sigsendset		(__NR_SVR4 + 108)
+#define __NR_SVR4_hrtsys		(__NR_SVR4 + 109)
+#define __NR_SVR4_acancel		(__NR_SVR4 + 110)
+#define __NR_SVR4_async			(__NR_SVR4 + 111)
+#define __NR_SVR4_priocntlset		(__NR_SVR4 + 112)
+#define __NR_SVR4_pathconf		(__NR_SVR4 + 113)
+#define __NR_SVR4_mincore		(__NR_SVR4 + 114)
+#define __NR_SVR4_mmap			(__NR_SVR4 + 115)
+#define __NR_SVR4_mprotect		(__NR_SVR4 + 116)
+#define __NR_SVR4_munmap		(__NR_SVR4 + 117)
+#define __NR_SVR4_fpathconf		(__NR_SVR4 + 118)
+#define __NR_SVR4_vfork			(__NR_SVR4 + 119)
+#define __NR_SVR4_fchdir		(__NR_SVR4 + 120)
+#define __NR_SVR4_readv			(__NR_SVR4 + 121)
+#define __NR_SVR4_writev		(__NR_SVR4 + 122)
+#define __NR_SVR4_xstat			(__NR_SVR4 + 123)
+#define __NR_SVR4_lxstat		(__NR_SVR4 + 124)
+#define __NR_SVR4_fxstat		(__NR_SVR4 + 125)
+#define __NR_SVR4_xmknod		(__NR_SVR4 + 126)
+#define __NR_SVR4_clocal		(__NR_SVR4 + 127)
+#define __NR_SVR4_setrlimit		(__NR_SVR4 + 128)
+#define __NR_SVR4_getrlimit		(__NR_SVR4 + 129)
+#define __NR_SVR4_lchown		(__NR_SVR4 + 130)
+#define __NR_SVR4_memcntl		(__NR_SVR4 + 131)
+#define __NR_SVR4_getpmsg		(__NR_SVR4 + 132)
+#define __NR_SVR4_putpmsg		(__NR_SVR4 + 133)
+#define __NR_SVR4_rename		(__NR_SVR4 + 134)
+#define __NR_SVR4_nuname		(__NR_SVR4 + 135)
+#define __NR_SVR4_setegid		(__NR_SVR4 + 136)
+#define __NR_SVR4_sysconf		(__NR_SVR4 + 137)
+#define __NR_SVR4_adjtime		(__NR_SVR4 + 138)
+#define __NR_SVR4_sysinfo		(__NR_SVR4 + 139)
+#define __NR_SVR4_reserved8		(__NR_SVR4 + 140)
+#define __NR_SVR4_seteuid		(__NR_SVR4 + 141)
+#define __NR_SVR4_PYRAMID_statis	(__NR_SVR4 + 142)
+#define __NR_SVR4_PYRAMID_tuning	(__NR_SVR4 + 143)
+#define __NR_SVR4_PYRAMID_forcerr	(__NR_SVR4 + 144)
+#define __NR_SVR4_PYRAMID_mpcntl	(__NR_SVR4 + 145)
+#define __NR_SVR4_reserved9		(__NR_SVR4 + 146)
+#define __NR_SVR4_reserved10		(__NR_SVR4 + 147)
+#define __NR_SVR4_reserved11		(__NR_SVR4 + 148)
+#define __NR_SVR4_reserved12		(__NR_SVR4 + 149)
+#define __NR_SVR4_reserved13		(__NR_SVR4 + 150)
+#define __NR_SVR4_reserved14		(__NR_SVR4 + 151)
+#define __NR_SVR4_reserved15		(__NR_SVR4 + 152)
+#define __NR_SVR4_reserved16		(__NR_SVR4 + 153)
+#define __NR_SVR4_reserved17		(__NR_SVR4 + 154)
+#define __NR_SVR4_reserved18		(__NR_SVR4 + 155)
+#define __NR_SVR4_reserved19		(__NR_SVR4 + 156)
+#define __NR_SVR4_reserved20		(__NR_SVR4 + 157)
+#define __NR_SVR4_reserved21		(__NR_SVR4 + 158)
+#define __NR_SVR4_reserved22		(__NR_SVR4 + 159)
+#define __NR_SVR4_reserved23		(__NR_SVR4 + 160)
+#define __NR_SVR4_reserved24		(__NR_SVR4 + 161)
+#define __NR_SVR4_reserved25		(__NR_SVR4 + 162)
+#define __NR_SVR4_reserved26		(__NR_SVR4 + 163)
+#define __NR_SVR4_reserved27		(__NR_SVR4 + 164)
+#define __NR_SVR4_reserved28		(__NR_SVR4 + 165)
+#define __NR_SVR4_reserved29		(__NR_SVR4 + 166)
+#define __NR_SVR4_reserved30		(__NR_SVR4 + 167)
+#define __NR_SVR4_reserved31		(__NR_SVR4 + 168)
+#define __NR_SVR4_reserved32		(__NR_SVR4 + 169)
+#define __NR_SVR4_reserved33		(__NR_SVR4 + 170)
+#define __NR_SVR4_reserved34		(__NR_SVR4 + 171)
+#define __NR_SVR4_reserved35		(__NR_SVR4 + 172)
+#define __NR_SVR4_reserved36		(__NR_SVR4 + 173)
+#define __NR_SVR4_reserved37		(__NR_SVR4 + 174)
+#define __NR_SVR4_reserved38		(__NR_SVR4 + 175)
+#define __NR_SVR4_reserved39		(__NR_SVR4 + 176)
+#define __NR_SVR4_reserved40		(__NR_SVR4 + 177)
+#define __NR_SVR4_reserved41		(__NR_SVR4 + 178)
+#define __NR_SVR4_reserved42		(__NR_SVR4 + 179)
+#define __NR_SVR4_reserved43		(__NR_SVR4 + 180)
+#define __NR_SVR4_reserved44		(__NR_SVR4 + 181)
+#define __NR_SVR4_reserved45		(__NR_SVR4 + 182)
+#define __NR_SVR4_reserved46		(__NR_SVR4 + 183)
+#define __NR_SVR4_reserved47		(__NR_SVR4 + 184)
+#define __NR_SVR4_reserved48		(__NR_SVR4 + 185)
+#define __NR_SVR4_reserved49		(__NR_SVR4 + 186)
+#define __NR_SVR4_reserved50		(__NR_SVR4 + 187)
+#define __NR_SVR4_reserved51		(__NR_SVR4 + 188)
+#define __NR_SVR4_reserved52		(__NR_SVR4 + 189)
+#define __NR_SVR4_reserved53		(__NR_SVR4 + 190)
+#define __NR_SVR4_reserved54		(__NR_SVR4 + 191)
+#define __NR_SVR4_reserved55		(__NR_SVR4 + 192)
+#define __NR_SVR4_reserved56		(__NR_SVR4 + 193)
+#define __NR_SVR4_reserved57		(__NR_SVR4 + 194)
+#define __NR_SVR4_reserved58		(__NR_SVR4 + 195)
+#define __NR_SVR4_reserved59		(__NR_SVR4 + 196)
+#define __NR_SVR4_reserved60		(__NR_SVR4 + 197)
+#define __NR_SVR4_reserved61		(__NR_SVR4 + 198)
+#define __NR_SVR4_reserved62		(__NR_SVR4 + 199)
+#define __NR_SVR4_reserved63		(__NR_SVR4 + 200)
+#define __NR_SVR4_aread			(__NR_SVR4 + 201)
+#define __NR_SVR4_awrite		(__NR_SVR4 + 202)	
+#define __NR_SVR4_listio		(__NR_SVR4 + 203)
+#define __NR_SVR4_mips_acancel		(__NR_SVR4 + 204)
+#define __NR_SVR4_astatus		(__NR_SVR4 + 205)
+#define __NR_SVR4_await			(__NR_SVR4 + 206)
+#define __NR_SVR4_areadv		(__NR_SVR4 + 207)
+#define __NR_SVR4_awritev		(__NR_SVR4 + 208)
+#define __NR_SVR4_MIPS_reserved1	(__NR_SVR4 + 209)
+#define __NR_SVR4_MIPS_reserved2	(__NR_SVR4 + 210)
+#define __NR_SVR4_MIPS_reserved3	(__NR_SVR4 + 211)
+#define __NR_SVR4_MIPS_reserved4	(__NR_SVR4 + 212)
+#define __NR_SVR4_MIPS_reserved5	(__NR_SVR4 + 213)
+#define __NR_SVR4_MIPS_reserved6	(__NR_SVR4 + 214)
+#define __NR_SVR4_MIPS_reserved7	(__NR_SVR4 + 215)
+#define __NR_SVR4_MIPS_reserved8	(__NR_SVR4 + 216)
+#define __NR_SVR4_MIPS_reserved9	(__NR_SVR4 + 217)
+#define __NR_SVR4_MIPS_reserved10	(__NR_SVR4 + 218)
+#define __NR_SVR4_MIPS_reserved11	(__NR_SVR4 + 219)
+#define __NR_SVR4_MIPS_reserved12	(__NR_SVR4 + 220)
+#define __NR_SVR4_CDC_reserved1		(__NR_SVR4 + 221)
+#define __NR_SVR4_CDC_reserved2		(__NR_SVR4 + 222)
+#define __NR_SVR4_CDC_reserved3		(__NR_SVR4 + 223)
+#define __NR_SVR4_CDC_reserved4		(__NR_SVR4 + 224)
+#define __NR_SVR4_CDC_reserved5		(__NR_SVR4 + 225)
+#define __NR_SVR4_CDC_reserved6		(__NR_SVR4 + 226)
+#define __NR_SVR4_CDC_reserved7		(__NR_SVR4 + 227)
+#define __NR_SVR4_CDC_reserved8		(__NR_SVR4 + 228)
+#define __NR_SVR4_CDC_reserved9		(__NR_SVR4 + 229)
+#define __NR_SVR4_CDC_reserved10	(__NR_SVR4 + 230)
+#define __NR_SVR4_CDC_reserved11	(__NR_SVR4 + 231)
+#define __NR_SVR4_CDC_reserved12	(__NR_SVR4 + 232)
+#define __NR_SVR4_CDC_reserved13	(__NR_SVR4 + 233)
+#define __NR_SVR4_CDC_reserved14	(__NR_SVR4 + 234)
+#define __NR_SVR4_CDC_reserved15	(__NR_SVR4 + 235)
+#define __NR_SVR4_CDC_reserved16	(__NR_SVR4 + 236)
+#define __NR_SVR4_CDC_reserved17	(__NR_SVR4 + 237)
+#define __NR_SVR4_CDC_reserved18	(__NR_SVR4 + 238)
+#define __NR_SVR4_CDC_reserved19	(__NR_SVR4 + 239)
+#define __NR_SVR4_CDC_reserved20	(__NR_SVR4 + 240)
+
+/*
+ * SYS V syscalls are in the range from 1000 to 1999
+ */
+#define __NR_SYSV			1000
+#define __NR_SYSV_syscall		(__NR_SYSV +   0)
+#define __NR_SYSV_exit			(__NR_SYSV +   1)
+#define __NR_SYSV_fork			(__NR_SYSV +   2)
+#define __NR_SYSV_read			(__NR_SYSV +   3)
+#define __NR_SYSV_write			(__NR_SYSV +   4)
+#define __NR_SYSV_open			(__NR_SYSV +   5)
+#define __NR_SYSV_close			(__NR_SYSV +   6)
+#define __NR_SYSV_wait			(__NR_SYSV +   7)
+#define __NR_SYSV_creat			(__NR_SYSV +   8)
+#define __NR_SYSV_link			(__NR_SYSV +   9)
+#define __NR_SYSV_unlink		(__NR_SYSV +  10)
+#define __NR_SYSV_execv			(__NR_SYSV +  11)
+#define __NR_SYSV_chdir			(__NR_SYSV +  12)
+#define __NR_SYSV_time			(__NR_SYSV +  13)
+#define __NR_SYSV_mknod			(__NR_SYSV +  14)
+#define __NR_SYSV_chmod			(__NR_SYSV +  15)
+#define __NR_SYSV_chown			(__NR_SYSV +  16)
+#define __NR_SYSV_brk			(__NR_SYSV +  17)
+#define __NR_SYSV_stat			(__NR_SYSV +  18)
+#define __NR_SYSV_lseek			(__NR_SYSV +  19)
+#define __NR_SYSV_getpid		(__NR_SYSV +  20)
+#define __NR_SYSV_mount			(__NR_SYSV +  21)
+#define __NR_SYSV_umount		(__NR_SYSV +  22)
+#define __NR_SYSV_setuid		(__NR_SYSV +  23)
+#define __NR_SYSV_getuid		(__NR_SYSV +  24)
+#define __NR_SYSV_stime			(__NR_SYSV +  25)
+#define __NR_SYSV_ptrace		(__NR_SYSV +  26)
+#define __NR_SYSV_alarm			(__NR_SYSV +  27)
+#define __NR_SYSV_fstat			(__NR_SYSV +  28)
+#define __NR_SYSV_pause			(__NR_SYSV +  29)
+#define __NR_SYSV_utime			(__NR_SYSV +  30)
+#define __NR_SYSV_stty			(__NR_SYSV +  31)
+#define __NR_SYSV_gtty			(__NR_SYSV +  32)
+#define __NR_SYSV_access		(__NR_SYSV +  33)
+#define __NR_SYSV_nice			(__NR_SYSV +  34)
+#define __NR_SYSV_statfs		(__NR_SYSV +  35)
+#define __NR_SYSV_sync			(__NR_SYSV +  36)
+#define __NR_SYSV_kill			(__NR_SYSV +  37)
+#define __NR_SYSV_fstatfs		(__NR_SYSV +  38)
+#define __NR_SYSV_setpgrp		(__NR_SYSV +  39)
+#define __NR_SYSV_syssgi		(__NR_SYSV +  40)
+#define __NR_SYSV_dup			(__NR_SYSV +  41)
+#define __NR_SYSV_pipe			(__NR_SYSV +  42)
+#define __NR_SYSV_times			(__NR_SYSV +  43)
+#define __NR_SYSV_profil		(__NR_SYSV +  44)
+#define __NR_SYSV_plock			(__NR_SYSV +  45)
+#define __NR_SYSV_setgid		(__NR_SYSV +  46)
+#define __NR_SYSV_getgid		(__NR_SYSV +  47)
+#define __NR_SYSV_sig			(__NR_SYSV +  48)
+#define __NR_SYSV_msgsys		(__NR_SYSV +  49)
+#define __NR_SYSV_sysmips		(__NR_SYSV +  50)
+#define __NR_SYSV_acct			(__NR_SYSV +  51)
+#define __NR_SYSV_shmsys		(__NR_SYSV +  52)
+#define __NR_SYSV_semsys		(__NR_SYSV +  53)
+#define __NR_SYSV_ioctl			(__NR_SYSV +  54)
+#define __NR_SYSV_uadmin		(__NR_SYSV +  55)
+#define __NR_SYSV_sysmp			(__NR_SYSV +  56)
+#define __NR_SYSV_utssys		(__NR_SYSV +  57)
+#define __NR_SYSV_USG_reserved1		(__NR_SYSV +  58)
+#define __NR_SYSV_execve		(__NR_SYSV +  59)
+#define __NR_SYSV_umask			(__NR_SYSV +  60)
+#define __NR_SYSV_chroot		(__NR_SYSV +  61)
+#define __NR_SYSV_fcntl			(__NR_SYSV +  62)
+#define __NR_SYSV_ulimit		(__NR_SYSV +  63)
+#define __NR_SYSV_SAFARI4_reserved1	(__NR_SYSV +  64)
+#define __NR_SYSV_SAFARI4_reserved2	(__NR_SYSV +  65)
+#define __NR_SYSV_SAFARI4_reserved3	(__NR_SYSV +  66)
+#define __NR_SYSV_SAFARI4_reserved4	(__NR_SYSV +  67)
+#define __NR_SYSV_SAFARI4_reserved5	(__NR_SYSV +  68)
+#define __NR_SYSV_SAFARI4_reserved6	(__NR_SYSV +  69)
+#define __NR_SYSV_advfs			(__NR_SYSV +  70)
+#define __NR_SYSV_unadvfs		(__NR_SYSV +  71)
+#define __NR_SYSV_rmount		(__NR_SYSV +  72)
+#define __NR_SYSV_rumount		(__NR_SYSV +  73)
+#define __NR_SYSV_rfstart		(__NR_SYSV +  74)
+#define __NR_SYSV_getrlimit64		(__NR_SYSV +  75)
+#define __NR_SYSV_setrlimit64		(__NR_SYSV +  76)
+#define __NR_SYSV_nanosleep		(__NR_SYSV +  77)
+#define __NR_SYSV_lseek64		(__NR_SYSV +  78)
+#define __NR_SYSV_rmdir			(__NR_SYSV +  79)
+#define __NR_SYSV_mkdir			(__NR_SYSV +  80)
+#define __NR_SYSV_getdents		(__NR_SYSV +  81)
+#define __NR_SYSV_sginap		(__NR_SYSV +  82)
+#define __NR_SYSV_sgikopt		(__NR_SYSV +  83)
+#define __NR_SYSV_sysfs			(__NR_SYSV +  84)
+#define __NR_SYSV_getmsg		(__NR_SYSV +  85)
+#define __NR_SYSV_putmsg		(__NR_SYSV +  86)
+#define __NR_SYSV_poll			(__NR_SYSV +  87)
+#define __NR_SYSV_sigreturn		(__NR_SYSV +  88)
+#define __NR_SYSV_accept		(__NR_SYSV +  89)
+#define __NR_SYSV_bind			(__NR_SYSV +  90)
+#define __NR_SYSV_connect		(__NR_SYSV +  91)
+#define __NR_SYSV_gethostid		(__NR_SYSV +  92)
+#define __NR_SYSV_getpeername		(__NR_SYSV +  93)
+#define __NR_SYSV_getsockname		(__NR_SYSV +  94)
+#define __NR_SYSV_getsockopt		(__NR_SYSV +  95)
+#define __NR_SYSV_listen		(__NR_SYSV +  96)
+#define __NR_SYSV_recv			(__NR_SYSV +  97)
+#define __NR_SYSV_recvfrom		(__NR_SYSV +  98)
+#define __NR_SYSV_recvmsg		(__NR_SYSV +  99)
+#define __NR_SYSV_select		(__NR_SYSV + 100)
+#define __NR_SYSV_send			(__NR_SYSV + 101)
+#define __NR_SYSV_sendmsg		(__NR_SYSV + 102)
+#define __NR_SYSV_sendto		(__NR_SYSV + 103)
+#define __NR_SYSV_sethostid		(__NR_SYSV + 104)
+#define __NR_SYSV_setsockopt		(__NR_SYSV + 105)
+#define __NR_SYSV_shutdown		(__NR_SYSV + 106)
+#define __NR_SYSV_socket		(__NR_SYSV + 107)
+#define __NR_SYSV_gethostname		(__NR_SYSV + 108)
+#define __NR_SYSV_sethostname		(__NR_SYSV + 109)
+#define __NR_SYSV_getdomainname		(__NR_SYSV + 110)
+#define __NR_SYSV_setdomainname		(__NR_SYSV + 111)
+#define __NR_SYSV_truncate		(__NR_SYSV + 112)
+#define __NR_SYSV_ftruncate		(__NR_SYSV + 113)
+#define __NR_SYSV_rename		(__NR_SYSV + 114)
+#define __NR_SYSV_symlink		(__NR_SYSV + 115)
+#define __NR_SYSV_readlink		(__NR_SYSV + 116)
+#define __NR_SYSV_lstat			(__NR_SYSV + 117)
+#define __NR_SYSV_nfsmount		(__NR_SYSV + 118)
+#define __NR_SYSV_nfssvc		(__NR_SYSV + 119)
+#define __NR_SYSV_getfh			(__NR_SYSV + 120)
+#define __NR_SYSV_async_daemon		(__NR_SYSV + 121)
+#define __NR_SYSV_exportfs		(__NR_SYSV + 122)
+#define __NR_SYSV_setregid		(__NR_SYSV + 123)
+#define __NR_SYSV_setreuid		(__NR_SYSV + 124)
+#define __NR_SYSV_getitimer		(__NR_SYSV + 125)
+#define __NR_SYSV_setitimer		(__NR_SYSV + 126)
+#define __NR_SYSV_adjtime		(__NR_SYSV + 127)
+#define __NR_SYSV_BSD_getime		(__NR_SYSV + 128)
+#define __NR_SYSV_sproc			(__NR_SYSV + 129)
+#define __NR_SYSV_prctl			(__NR_SYSV + 130)
+#define __NR_SYSV_procblk		(__NR_SYSV + 131)
+#define __NR_SYSV_sprocsp		(__NR_SYSV + 132)
+#define __NR_SYSV_sgigsc		(__NR_SYSV + 133)
+#define __NR_SYSV_mmap			(__NR_SYSV + 134)
+#define __NR_SYSV_munmap		(__NR_SYSV + 135)
+#define __NR_SYSV_mprotect		(__NR_SYSV + 136)
+#define __NR_SYSV_msync			(__NR_SYSV + 137)
+#define __NR_SYSV_madvise		(__NR_SYSV + 138)
+#define __NR_SYSV_pagelock		(__NR_SYSV + 139)
+#define __NR_SYSV_getpagesize		(__NR_SYSV + 140)
+#define __NR_SYSV_quotactl		(__NR_SYSV + 141)
+#define __NR_SYSV_libdetach		(__NR_SYSV + 142)
+#define __NR_SYSV_BSDgetpgrp		(__NR_SYSV + 143)
+#define __NR_SYSV_BSDsetpgrp		(__NR_SYSV + 144)
+#define __NR_SYSV_vhangup		(__NR_SYSV + 145)
+#define __NR_SYSV_fsync			(__NR_SYSV + 146)
+#define __NR_SYSV_fchdir		(__NR_SYSV + 147)
+#define __NR_SYSV_getrlimit		(__NR_SYSV + 148)
+#define __NR_SYSV_setrlimit		(__NR_SYSV + 149)
+#define __NR_SYSV_cacheflush		(__NR_SYSV + 150)
+#define __NR_SYSV_cachectl		(__NR_SYSV + 151)
+#define __NR_SYSV_fchown		(__NR_SYSV + 152)
+#define __NR_SYSV_fchmod		(__NR_SYSV + 153)
+#define __NR_SYSV_wait3			(__NR_SYSV + 154)
+#define __NR_SYSV_socketpair		(__NR_SYSV + 155)
+#define __NR_SYSV_sysinfo		(__NR_SYSV + 156)
+#define __NR_SYSV_nuname		(__NR_SYSV + 157)
+#define __NR_SYSV_xstat			(__NR_SYSV + 158)
+#define __NR_SYSV_lxstat		(__NR_SYSV + 159)
+#define __NR_SYSV_fxstat		(__NR_SYSV + 160)
+#define __NR_SYSV_xmknod		(__NR_SYSV + 161)
+#define __NR_SYSV_ksigaction		(__NR_SYSV + 162)
+#define __NR_SYSV_sigpending		(__NR_SYSV + 163)
+#define __NR_SYSV_sigprocmask		(__NR_SYSV + 164)
+#define __NR_SYSV_sigsuspend		(__NR_SYSV + 165)
+#define __NR_SYSV_sigpoll		(__NR_SYSV + 166)
+#define __NR_SYSV_swapctl		(__NR_SYSV + 167)
+#define __NR_SYSV_getcontext		(__NR_SYSV + 168)
+#define __NR_SYSV_setcontext		(__NR_SYSV + 169)
+#define __NR_SYSV_waitsys		(__NR_SYSV + 170)
+#define __NR_SYSV_sigstack		(__NR_SYSV + 171)
+#define __NR_SYSV_sigaltstack		(__NR_SYSV + 172)
+#define __NR_SYSV_sigsendset		(__NR_SYSV + 173)
+#define __NR_SYSV_statvfs		(__NR_SYSV + 174)
+#define __NR_SYSV_fstatvfs		(__NR_SYSV + 175)
+#define __NR_SYSV_getpmsg		(__NR_SYSV + 176)
+#define __NR_SYSV_putpmsg		(__NR_SYSV + 177)
+#define __NR_SYSV_lchown		(__NR_SYSV + 178)
+#define __NR_SYSV_priocntl		(__NR_SYSV + 179)
+#define __NR_SYSV_ksigqueue		(__NR_SYSV + 180)
+#define __NR_SYSV_readv			(__NR_SYSV + 181)
+#define __NR_SYSV_writev		(__NR_SYSV + 182)
+#define __NR_SYSV_truncate64		(__NR_SYSV + 183)
+#define __NR_SYSV_ftruncate64		(__NR_SYSV + 184)
+#define __NR_SYSV_mmap64		(__NR_SYSV + 185)
+#define __NR_SYSV_dmi			(__NR_SYSV + 186)
+#define __NR_SYSV_pread			(__NR_SYSV + 187)
+#define __NR_SYSV_pwrite		(__NR_SYSV + 188)
+
+/*
+ * BSD 4.3 syscalls are in the range from 2000 to 2999
+ */
+#define __NR_BSD43			2000
+#define __NR_BSD43_syscall		(__NR_BSD43 +   0)
+#define __NR_BSD43_exit			(__NR_BSD43 +   1)
+#define __NR_BSD43_fork			(__NR_BSD43 +   2)
+#define __NR_BSD43_read			(__NR_BSD43 +   3)
+#define __NR_BSD43_write		(__NR_BSD43 +   4)
+#define __NR_BSD43_open			(__NR_BSD43 +   5)
+#define __NR_BSD43_close		(__NR_BSD43 +   6)
+#define __NR_BSD43_wait			(__NR_BSD43 +   7)
+#define __NR_BSD43_creat		(__NR_BSD43 +   8)
+#define __NR_BSD43_link			(__NR_BSD43 +   9)
+#define __NR_BSD43_unlink		(__NR_BSD43 +  10)
+#define __NR_BSD43_exec			(__NR_BSD43 +  11)
+#define __NR_BSD43_chdir		(__NR_BSD43 +  12)
+#define __NR_BSD43_time			(__NR_BSD43 +  13)
+#define __NR_BSD43_mknod		(__NR_BSD43 +  14)
+#define __NR_BSD43_chmod		(__NR_BSD43 +  15)
+#define __NR_BSD43_chown		(__NR_BSD43 +  16)
+#define __NR_BSD43_sbreak		(__NR_BSD43 +  17)
+#define __NR_BSD43_oldstat		(__NR_BSD43 +  18)
+#define __NR_BSD43_lseek		(__NR_BSD43 +  19)
+#define __NR_BSD43_getpid		(__NR_BSD43 +  20)
+#define __NR_BSD43_oldmount		(__NR_BSD43 +  21)
+#define __NR_BSD43_umount		(__NR_BSD43 +  22)
+#define __NR_BSD43_setuid		(__NR_BSD43 +  23)
+#define __NR_BSD43_getuid		(__NR_BSD43 +  24)
+#define __NR_BSD43_stime		(__NR_BSD43 +  25)
+#define __NR_BSD43_ptrace		(__NR_BSD43 +  26)
+#define __NR_BSD43_alarm		(__NR_BSD43 +  27)
+#define __NR_BSD43_oldfstat		(__NR_BSD43 +  28)
+#define __NR_BSD43_pause		(__NR_BSD43 +  29)
+#define __NR_BSD43_utime		(__NR_BSD43 +  30)
+#define __NR_BSD43_stty			(__NR_BSD43 +  31)
+#define __NR_BSD43_gtty			(__NR_BSD43 +  32)
+#define __NR_BSD43_access		(__NR_BSD43 +  33)
+#define __NR_BSD43_nice			(__NR_BSD43 +  34)
+#define __NR_BSD43_ftime		(__NR_BSD43 +  35)
+#define __NR_BSD43_sync			(__NR_BSD43 +  36)
+#define __NR_BSD43_kill			(__NR_BSD43 +  37)
+#define __NR_BSD43_stat			(__NR_BSD43 +  38)
+#define __NR_BSD43_oldsetpgrp		(__NR_BSD43 +  39)
+#define __NR_BSD43_lstat		(__NR_BSD43 +  40)
+#define __NR_BSD43_dup			(__NR_BSD43 +  41)
+#define __NR_BSD43_pipe			(__NR_BSD43 +  42)
+#define __NR_BSD43_times		(__NR_BSD43 +  43)
+#define __NR_BSD43_profil		(__NR_BSD43 +  44)
+#define __NR_BSD43_msgsys		(__NR_BSD43 +  45)
+#define __NR_BSD43_setgid		(__NR_BSD43 +  46)
+#define __NR_BSD43_getgid		(__NR_BSD43 +  47)
+#define __NR_BSD43_ssig			(__NR_BSD43 +  48)
+#define __NR_BSD43_reserved1		(__NR_BSD43 +  49)
+#define __NR_BSD43_reserved2		(__NR_BSD43 +  50)
+#define __NR_BSD43_sysacct		(__NR_BSD43 +  51)
+#define __NR_BSD43_phys			(__NR_BSD43 +  52)
+#define __NR_BSD43_lock			(__NR_BSD43 +  53)
+#define __NR_BSD43_ioctl		(__NR_BSD43 +  54)
+#define __NR_BSD43_reboot		(__NR_BSD43 +  55)
+#define __NR_BSD43_mpxchan		(__NR_BSD43 +  56)
+#define __NR_BSD43_symlink		(__NR_BSD43 +  57)
+#define __NR_BSD43_readlink		(__NR_BSD43 +  58)
+#define __NR_BSD43_execve		(__NR_BSD43 +  59)
+#define __NR_BSD43_umask		(__NR_BSD43 +  60)
+#define __NR_BSD43_chroot		(__NR_BSD43 +  61)
+#define __NR_BSD43_fstat		(__NR_BSD43 +  62)
+#define __NR_BSD43_reserved3		(__NR_BSD43 +  63)
+#define __NR_BSD43_getpagesize		(__NR_BSD43 +  64)
+#define __NR_BSD43_mremap		(__NR_BSD43 +  65)
+#define __NR_BSD43_vfork		(__NR_BSD43 +  66)
+#define __NR_BSD43_vread		(__NR_BSD43 +  67)
+#define __NR_BSD43_vwrite		(__NR_BSD43 +  68)
+#define __NR_BSD43_sbrk			(__NR_BSD43 +  69)
+#define __NR_BSD43_sstk			(__NR_BSD43 +  70)
+#define __NR_BSD43_mmap			(__NR_BSD43 +  71)
+#define __NR_BSD43_vadvise		(__NR_BSD43 +  72)
+#define __NR_BSD43_munmap		(__NR_BSD43 +  73)
+#define __NR_BSD43_mprotect		(__NR_BSD43 +  74)
+#define __NR_BSD43_madvise		(__NR_BSD43 +  75)
+#define __NR_BSD43_vhangup		(__NR_BSD43 +  76)
+#define __NR_BSD43_vlimit		(__NR_BSD43 +  77)
+#define __NR_BSD43_mincore		(__NR_BSD43 +  78)
+#define __NR_BSD43_getgroups		(__NR_BSD43 +  79)
+#define __NR_BSD43_setgroups		(__NR_BSD43 +  80)
+#define __NR_BSD43_getpgrp		(__NR_BSD43 +  81)
+#define __NR_BSD43_setpgrp		(__NR_BSD43 +  82)
+#define __NR_BSD43_setitimer		(__NR_BSD43 +  83)
+#define __NR_BSD43_wait3		(__NR_BSD43 +  84)
+#define __NR_BSD43_swapon		(__NR_BSD43 +  85)
+#define __NR_BSD43_getitimer		(__NR_BSD43 +  86)
+#define __NR_BSD43_gethostname		(__NR_BSD43 +  87)
+#define __NR_BSD43_sethostname		(__NR_BSD43 +  88)
+#define __NR_BSD43_getdtablesize	(__NR_BSD43 +  89)
+#define __NR_BSD43_dup2			(__NR_BSD43 +  90)
+#define __NR_BSD43_getdopt		(__NR_BSD43 +  91)
+#define __NR_BSD43_fcntl		(__NR_BSD43 +  92)
+#define __NR_BSD43_select		(__NR_BSD43 +  93)
+#define __NR_BSD43_setdopt		(__NR_BSD43 +  94)
+#define __NR_BSD43_fsync		(__NR_BSD43 +  95)
+#define __NR_BSD43_setpriority		(__NR_BSD43 +  96)
+#define __NR_BSD43_socket		(__NR_BSD43 +  97)
+#define __NR_BSD43_connect		(__NR_BSD43 +  98)
+#define __NR_BSD43_oldaccept		(__NR_BSD43 +  99)
+#define __NR_BSD43_getpriority		(__NR_BSD43 + 100)
+#define __NR_BSD43_send			(__NR_BSD43 + 101)
+#define __NR_BSD43_recv			(__NR_BSD43 + 102)
+#define __NR_BSD43_sigreturn		(__NR_BSD43 + 103)
+#define __NR_BSD43_bind			(__NR_BSD43 + 104)
+#define __NR_BSD43_setsockopt		(__NR_BSD43 + 105)
+#define __NR_BSD43_listen		(__NR_BSD43 + 106)
+#define __NR_BSD43_vtimes		(__NR_BSD43 + 107)
+#define __NR_BSD43_sigvec		(__NR_BSD43 + 108)
+#define __NR_BSD43_sigblock		(__NR_BSD43 + 109)
+#define __NR_BSD43_sigsetmask		(__NR_BSD43 + 110)
+#define __NR_BSD43_sigpause		(__NR_BSD43 + 111)
+#define __NR_BSD43_sigstack		(__NR_BSD43 + 112)
+#define __NR_BSD43_oldrecvmsg		(__NR_BSD43 + 113)
+#define __NR_BSD43_oldsendmsg		(__NR_BSD43 + 114)
+#define __NR_BSD43_vtrace		(__NR_BSD43 + 115)
+#define __NR_BSD43_gettimeofday		(__NR_BSD43 + 116)
+#define __NR_BSD43_getrusage		(__NR_BSD43 + 117)
+#define __NR_BSD43_getsockopt		(__NR_BSD43 + 118)
+#define __NR_BSD43_reserved4		(__NR_BSD43 + 119)
+#define __NR_BSD43_readv		(__NR_BSD43 + 120)
+#define __NR_BSD43_writev		(__NR_BSD43 + 121)
+#define __NR_BSD43_settimeofday		(__NR_BSD43 + 122)
+#define __NR_BSD43_fchown		(__NR_BSD43 + 123)
+#define __NR_BSD43_fchmod		(__NR_BSD43 + 124)
+#define __NR_BSD43_oldrecvfrom		(__NR_BSD43 + 125)
+#define __NR_BSD43_setreuid		(__NR_BSD43 + 126)
+#define __NR_BSD43_setregid		(__NR_BSD43 + 127)
+#define __NR_BSD43_rename		(__NR_BSD43 + 128)
+#define __NR_BSD43_truncate		(__NR_BSD43 + 129)
+#define __NR_BSD43_ftruncate		(__NR_BSD43 + 130)
+#define __NR_BSD43_flock		(__NR_BSD43 + 131)
+#define __NR_BSD43_semsys		(__NR_BSD43 + 132)
+#define __NR_BSD43_sendto		(__NR_BSD43 + 133)
+#define __NR_BSD43_shutdown		(__NR_BSD43 + 134)
+#define __NR_BSD43_socketpair		(__NR_BSD43 + 135)
+#define __NR_BSD43_mkdir		(__NR_BSD43 + 136)
+#define __NR_BSD43_rmdir		(__NR_BSD43 + 137)
+#define __NR_BSD43_utimes		(__NR_BSD43 + 138)
+#define __NR_BSD43_sigcleanup		(__NR_BSD43 + 139)
+#define __NR_BSD43_adjtime		(__NR_BSD43 + 140)
+#define __NR_BSD43_oldgetpeername	(__NR_BSD43 + 141)
+#define __NR_BSD43_gethostid		(__NR_BSD43 + 142)
+#define __NR_BSD43_sethostid		(__NR_BSD43 + 143)
+#define __NR_BSD43_getrlimit		(__NR_BSD43 + 144)
+#define __NR_BSD43_setrlimit		(__NR_BSD43 + 145)
+#define __NR_BSD43_killpg		(__NR_BSD43 + 146)
+#define __NR_BSD43_shmsys		(__NR_BSD43 + 147)
+#define __NR_BSD43_quota		(__NR_BSD43 + 148)
+#define __NR_BSD43_qquota		(__NR_BSD43 + 149)
+#define __NR_BSD43_oldgetsockname	(__NR_BSD43 + 150)
+#define __NR_BSD43_sysmips		(__NR_BSD43 + 151)
+#define __NR_BSD43_cacheflush		(__NR_BSD43 + 152)
+#define __NR_BSD43_cachectl		(__NR_BSD43 + 153)
+#define __NR_BSD43_debug		(__NR_BSD43 + 154)
+#define __NR_BSD43_reserved5		(__NR_BSD43 + 155)
+#define __NR_BSD43_reserved6		(__NR_BSD43 + 156)
+#define __NR_BSD43_nfs_mount		(__NR_BSD43 + 157)
+#define __NR_BSD43_nfs_svc		(__NR_BSD43 + 158)
+#define __NR_BSD43_getdirentries	(__NR_BSD43 + 159)
+#define __NR_BSD43_statfs		(__NR_BSD43 + 160)
+#define __NR_BSD43_fstatfs		(__NR_BSD43 + 161)
+#define __NR_BSD43_unmount		(__NR_BSD43 + 162)
+#define __NR_BSD43_async_daemon		(__NR_BSD43 + 163)
+#define __NR_BSD43_nfs_getfh		(__NR_BSD43 + 164)
+#define __NR_BSD43_getdomainname	(__NR_BSD43 + 165)
+#define __NR_BSD43_setdomainname	(__NR_BSD43 + 166)
+#define __NR_BSD43_pcfs_mount		(__NR_BSD43 + 167)
+#define __NR_BSD43_quotactl		(__NR_BSD43 + 168)
+#define __NR_BSD43_oldexportfs		(__NR_BSD43 + 169)
+#define __NR_BSD43_smount		(__NR_BSD43 + 170)
+#define __NR_BSD43_mipshwconf		(__NR_BSD43 + 171)
+#define __NR_BSD43_exportfs		(__NR_BSD43 + 172)
+#define __NR_BSD43_nfsfh_open		(__NR_BSD43 + 173)
+#define __NR_BSD43_libattach		(__NR_BSD43 + 174)
+#define __NR_BSD43_libdetach		(__NR_BSD43 + 175)
+#define __NR_BSD43_accept		(__NR_BSD43 + 176)
+#define __NR_BSD43_reserved7		(__NR_BSD43 + 177)
+#define __NR_BSD43_reserved8		(__NR_BSD43 + 178)
+#define __NR_BSD43_recvmsg		(__NR_BSD43 + 179)
+#define __NR_BSD43_recvfrom		(__NR_BSD43 + 180)
+#define __NR_BSD43_sendmsg		(__NR_BSD43 + 181)
+#define __NR_BSD43_getpeername		(__NR_BSD43 + 182)
+#define __NR_BSD43_getsockname		(__NR_BSD43 + 183)
+#define __NR_BSD43_aread		(__NR_BSD43 + 184)
+#define __NR_BSD43_awrite		(__NR_BSD43 + 185)
+#define __NR_BSD43_listio		(__NR_BSD43 + 186)
+#define __NR_BSD43_acancel		(__NR_BSD43 + 187)
+#define __NR_BSD43_astatus		(__NR_BSD43 + 188)
+#define __NR_BSD43_await		(__NR_BSD43 + 189)
+#define __NR_BSD43_areadv		(__NR_BSD43 + 190)
+#define __NR_BSD43_awritev		(__NR_BSD43 + 191)
+
+/*
+ * POSIX syscalls are in the range from 3000 to 3999
+ */
+#define __NR_POSIX			3000
+#define __NR_POSIX_syscall		(__NR_POSIX +   0)
+#define __NR_POSIX_exit			(__NR_POSIX +   1)
+#define __NR_POSIX_fork			(__NR_POSIX +   2)
+#define __NR_POSIX_read			(__NR_POSIX +   3)
+#define __NR_POSIX_write		(__NR_POSIX +   4)
+#define __NR_POSIX_open			(__NR_POSIX +   5)
+#define __NR_POSIX_close		(__NR_POSIX +   6)
+#define __NR_POSIX_wait			(__NR_POSIX +   7)
+#define __NR_POSIX_creat		(__NR_POSIX +   8)
+#define __NR_POSIX_link			(__NR_POSIX +   9)
+#define __NR_POSIX_unlink		(__NR_POSIX +  10)
+#define __NR_POSIX_exec			(__NR_POSIX +  11)
+#define __NR_POSIX_chdir		(__NR_POSIX +  12)
+#define __NR_POSIX_gtime		(__NR_POSIX +  13)
+#define __NR_POSIX_mknod		(__NR_POSIX +  14)
+#define __NR_POSIX_chmod		(__NR_POSIX +  15)
+#define __NR_POSIX_chown		(__NR_POSIX +  16)
+#define __NR_POSIX_sbreak		(__NR_POSIX +  17)
+#define __NR_POSIX_stat			(__NR_POSIX +  18)
+#define __NR_POSIX_lseek		(__NR_POSIX +  19)
+#define __NR_POSIX_getpid		(__NR_POSIX +  20)
+#define __NR_POSIX_mount		(__NR_POSIX +  21)
+#define __NR_POSIX_umount		(__NR_POSIX +  22)
+#define __NR_POSIX_setuid		(__NR_POSIX +  23)
+#define __NR_POSIX_getuid		(__NR_POSIX +  24)
+#define __NR_POSIX_stime		(__NR_POSIX +  25)
+#define __NR_POSIX_ptrace		(__NR_POSIX +  26)
+#define __NR_POSIX_alarm		(__NR_POSIX +  27)
+#define __NR_POSIX_fstat		(__NR_POSIX +  28)
+#define __NR_POSIX_pause		(__NR_POSIX +  29)
+#define __NR_POSIX_utime		(__NR_POSIX +  30)
+#define __NR_POSIX_stty			(__NR_POSIX +  31)
+#define __NR_POSIX_gtty			(__NR_POSIX +  32)
+#define __NR_POSIX_access		(__NR_POSIX +  33)
+#define __NR_POSIX_nice			(__NR_POSIX +  34)
+#define __NR_POSIX_statfs		(__NR_POSIX +  35)
+#define __NR_POSIX_sync			(__NR_POSIX +  36)
+#define __NR_POSIX_kill			(__NR_POSIX +  37)
+#define __NR_POSIX_fstatfs		(__NR_POSIX +  38)
+#define __NR_POSIX_getpgrp		(__NR_POSIX +  39)
+#define __NR_POSIX_syssgi		(__NR_POSIX +  40)
+#define __NR_POSIX_dup			(__NR_POSIX +  41)
+#define __NR_POSIX_pipe			(__NR_POSIX +  42)
+#define __NR_POSIX_times		(__NR_POSIX +  43)
+#define __NR_POSIX_profil		(__NR_POSIX +  44)
+#define __NR_POSIX_lock			(__NR_POSIX +  45)
+#define __NR_POSIX_setgid		(__NR_POSIX +  46)
+#define __NR_POSIX_getgid		(__NR_POSIX +  47)
+#define __NR_POSIX_sig			(__NR_POSIX +  48)
+#define __NR_POSIX_msgsys		(__NR_POSIX +  49)
+#define __NR_POSIX_sysmips		(__NR_POSIX +  50)
+#define __NR_POSIX_sysacct		(__NR_POSIX +  51)
+#define __NR_POSIX_shmsys		(__NR_POSIX +  52)
+#define __NR_POSIX_semsys		(__NR_POSIX +  53)
+#define __NR_POSIX_ioctl		(__NR_POSIX +  54)
+#define __NR_POSIX_uadmin		(__NR_POSIX +  55)
+#define __NR_POSIX_exch			(__NR_POSIX +  56)
+#define __NR_POSIX_utssys		(__NR_POSIX +  57)
+#define __NR_POSIX_USG_reserved1	(__NR_POSIX +  58)
+#define __NR_POSIX_exece		(__NR_POSIX +  59)
+#define __NR_POSIX_umask		(__NR_POSIX +  60)
+#define __NR_POSIX_chroot		(__NR_POSIX +  61)
+#define __NR_POSIX_fcntl		(__NR_POSIX +  62)
+#define __NR_POSIX_ulimit		(__NR_POSIX +  63)
+#define __NR_POSIX_SAFARI4_reserved1	(__NR_POSIX +  64)
+#define __NR_POSIX_SAFARI4_reserved2	(__NR_POSIX +  65)
+#define __NR_POSIX_SAFARI4_reserved3	(__NR_POSIX +  66)
+#define __NR_POSIX_SAFARI4_reserved4	(__NR_POSIX +  67)
+#define __NR_POSIX_SAFARI4_reserved5	(__NR_POSIX +  68)
+#define __NR_POSIX_SAFARI4_reserved6	(__NR_POSIX +  69)
+#define __NR_POSIX_advfs		(__NR_POSIX +  70)
+#define __NR_POSIX_unadvfs		(__NR_POSIX +  71)
+#define __NR_POSIX_rmount		(__NR_POSIX +  72)
+#define __NR_POSIX_rumount		(__NR_POSIX +  73)
+#define __NR_POSIX_rfstart		(__NR_POSIX +  74)
+#define __NR_POSIX_reserved1		(__NR_POSIX +  75)
+#define __NR_POSIX_rdebug		(__NR_POSIX +  76)
+#define __NR_POSIX_rfstop		(__NR_POSIX +  77)
+#define __NR_POSIX_rfsys		(__NR_POSIX +  78)
+#define __NR_POSIX_rmdir		(__NR_POSIX +  79)
+#define __NR_POSIX_mkdir		(__NR_POSIX +  80)
+#define __NR_POSIX_getdents		(__NR_POSIX +  81)
+#define __NR_POSIX_sginap		(__NR_POSIX +  82)
+#define __NR_POSIX_sgikopt		(__NR_POSIX +  83)
+#define __NR_POSIX_sysfs		(__NR_POSIX +  84)
+#define __NR_POSIX_getmsg		(__NR_POSIX +  85)
+#define __NR_POSIX_putmsg		(__NR_POSIX +  86)
+#define __NR_POSIX_poll			(__NR_POSIX +  87)
+#define __NR_POSIX_sigreturn		(__NR_POSIX +  88)
+#define __NR_POSIX_accept		(__NR_POSIX +  89)
+#define __NR_POSIX_bind			(__NR_POSIX +  90)
+#define __NR_POSIX_connect		(__NR_POSIX +  91)
+#define __NR_POSIX_gethostid		(__NR_POSIX +  92)
+#define __NR_POSIX_getpeername		(__NR_POSIX +  93)
+#define __NR_POSIX_getsockname		(__NR_POSIX +  94)
+#define __NR_POSIX_getsockopt		(__NR_POSIX +  95)
+#define __NR_POSIX_listen		(__NR_POSIX +  96)
+#define __NR_POSIX_recv			(__NR_POSIX +  97)
+#define __NR_POSIX_recvfrom		(__NR_POSIX +  98)
+#define __NR_POSIX_recvmsg		(__NR_POSIX +  99)
+#define __NR_POSIX_select		(__NR_POSIX + 100)
+#define __NR_POSIX_send			(__NR_POSIX + 101)
+#define __NR_POSIX_sendmsg		(__NR_POSIX + 102)
+#define __NR_POSIX_sendto		(__NR_POSIX + 103)
+#define __NR_POSIX_sethostid		(__NR_POSIX + 104)
+#define __NR_POSIX_setsockopt		(__NR_POSIX + 105)
+#define __NR_POSIX_shutdown		(__NR_POSIX + 106)
+#define __NR_POSIX_socket		(__NR_POSIX + 107)
+#define __NR_POSIX_gethostname		(__NR_POSIX + 108)
+#define __NR_POSIX_sethostname		(__NR_POSIX + 109)
+#define __NR_POSIX_getdomainname	(__NR_POSIX + 110)
+#define __NR_POSIX_setdomainname	(__NR_POSIX + 111)
+#define __NR_POSIX_truncate		(__NR_POSIX + 112)
+#define __NR_POSIX_ftruncate		(__NR_POSIX + 113)
+#define __NR_POSIX_rename		(__NR_POSIX + 114)
+#define __NR_POSIX_symlink		(__NR_POSIX + 115)
+#define __NR_POSIX_readlink		(__NR_POSIX + 116)
+#define __NR_POSIX_lstat		(__NR_POSIX + 117)
+#define __NR_POSIX_nfs_mount		(__NR_POSIX + 118)
+#define __NR_POSIX_nfs_svc		(__NR_POSIX + 119)
+#define __NR_POSIX_nfs_getfh		(__NR_POSIX + 120)
+#define __NR_POSIX_async_daemon		(__NR_POSIX + 121)
+#define __NR_POSIX_exportfs		(__NR_POSIX + 122)
+#define __NR_POSIX_SGI_setregid		(__NR_POSIX + 123)
+#define __NR_POSIX_SGI_setreuid		(__NR_POSIX + 124)
+#define __NR_POSIX_getitimer		(__NR_POSIX + 125)
+#define __NR_POSIX_setitimer		(__NR_POSIX + 126)
+#define __NR_POSIX_adjtime		(__NR_POSIX + 127)
+#define __NR_POSIX_SGI_bsdgettime	(__NR_POSIX + 128)
+#define __NR_POSIX_SGI_sproc		(__NR_POSIX + 129)
+#define __NR_POSIX_SGI_prctl		(__NR_POSIX + 130)
+#define __NR_POSIX_SGI_blkproc		(__NR_POSIX + 131)
+#define __NR_POSIX_SGI_reserved1	(__NR_POSIX + 132)
+#define __NR_POSIX_SGI_sgigsc		(__NR_POSIX + 133)
+#define __NR_POSIX_SGI_mmap		(__NR_POSIX + 134)
+#define __NR_POSIX_SGI_munmap		(__NR_POSIX + 135)
+#define __NR_POSIX_SGI_mprotect		(__NR_POSIX + 136)
+#define __NR_POSIX_SGI_msync		(__NR_POSIX + 137)
+#define __NR_POSIX_SGI_madvise		(__NR_POSIX + 138)
+#define __NR_POSIX_SGI_mpin		(__NR_POSIX + 139)
+#define __NR_POSIX_SGI_getpagesize	(__NR_POSIX + 140)
+#define __NR_POSIX_SGI_libattach	(__NR_POSIX + 141)
+#define __NR_POSIX_SGI_libdetach	(__NR_POSIX + 142)
+#define __NR_POSIX_SGI_getpgrp		(__NR_POSIX + 143)
+#define __NR_POSIX_SGI_setpgrp		(__NR_POSIX + 144)
+#define __NR_POSIX_SGI_reserved2	(__NR_POSIX + 145)
+#define __NR_POSIX_SGI_reserved3	(__NR_POSIX + 146)
+#define __NR_POSIX_SGI_reserved4	(__NR_POSIX + 147)
+#define __NR_POSIX_SGI_reserved5	(__NR_POSIX + 148)
+#define __NR_POSIX_SGI_reserved6	(__NR_POSIX + 149)
+#define __NR_POSIX_cacheflush		(__NR_POSIX + 150)
+#define __NR_POSIX_cachectl		(__NR_POSIX + 151)
+#define __NR_POSIX_fchown		(__NR_POSIX + 152)
+#define __NR_POSIX_fchmod		(__NR_POSIX + 153)
+#define __NR_POSIX_wait3		(__NR_POSIX + 154)
+#define __NR_POSIX_mmap			(__NR_POSIX + 155)
+#define __NR_POSIX_munmap		(__NR_POSIX + 156)
+#define __NR_POSIX_madvise		(__NR_POSIX + 157)
+#define __NR_POSIX_BSD_getpagesize	(__NR_POSIX + 158)
+#define __NR_POSIX_setreuid		(__NR_POSIX + 159)
+#define __NR_POSIX_setregid		(__NR_POSIX + 160)
+#define __NR_POSIX_setpgid		(__NR_POSIX + 161)
+#define __NR_POSIX_getgroups		(__NR_POSIX + 162)
+#define __NR_POSIX_setgroups		(__NR_POSIX + 163)
+#define __NR_POSIX_gettimeofday		(__NR_POSIX + 164)
+#define __NR_POSIX_getrusage		(__NR_POSIX + 165)
+#define __NR_POSIX_getrlimit		(__NR_POSIX + 166)
+#define __NR_POSIX_setrlimit		(__NR_POSIX + 167)
+#define __NR_POSIX_waitpid		(__NR_POSIX + 168)
+#define __NR_POSIX_dup2			(__NR_POSIX + 169)
+#define __NR_POSIX_reserved2		(__NR_POSIX + 170)
+#define __NR_POSIX_reserved3		(__NR_POSIX + 171)
+#define __NR_POSIX_reserved4		(__NR_POSIX + 172)
+#define __NR_POSIX_reserved5		(__NR_POSIX + 173)
+#define __NR_POSIX_reserved6		(__NR_POSIX + 174)
+#define __NR_POSIX_reserved7		(__NR_POSIX + 175)
+#define __NR_POSIX_reserved8		(__NR_POSIX + 176)
+#define __NR_POSIX_reserved9		(__NR_POSIX + 177)
+#define __NR_POSIX_reserved10		(__NR_POSIX + 178)
+#define __NR_POSIX_reserved11		(__NR_POSIX + 179)
+#define __NR_POSIX_reserved12		(__NR_POSIX + 180)
+#define __NR_POSIX_reserved13		(__NR_POSIX + 181)
+#define __NR_POSIX_reserved14		(__NR_POSIX + 182)
+#define __NR_POSIX_reserved15		(__NR_POSIX + 183)
+#define __NR_POSIX_reserved16		(__NR_POSIX + 184)
+#define __NR_POSIX_reserved17		(__NR_POSIX + 185)
+#define __NR_POSIX_reserved18		(__NR_POSIX + 186)
+#define __NR_POSIX_reserved19		(__NR_POSIX + 187)
+#define __NR_POSIX_reserved20		(__NR_POSIX + 188)
+#define __NR_POSIX_reserved21		(__NR_POSIX + 189)
+#define __NR_POSIX_reserved22		(__NR_POSIX + 190)
+#define __NR_POSIX_reserved23		(__NR_POSIX + 191)
+#define __NR_POSIX_reserved24		(__NR_POSIX + 192)
+#define __NR_POSIX_reserved25		(__NR_POSIX + 193)
+#define __NR_POSIX_reserved26		(__NR_POSIX + 194)
+#define __NR_POSIX_reserved27		(__NR_POSIX + 195)
+#define __NR_POSIX_reserved28		(__NR_POSIX + 196)
+#define __NR_POSIX_reserved29		(__NR_POSIX + 197)
+#define __NR_POSIX_reserved30		(__NR_POSIX + 198)
+#define __NR_POSIX_reserved31		(__NR_POSIX + 199)
+#define __NR_POSIX_reserved32		(__NR_POSIX + 200)
+#define __NR_POSIX_reserved33		(__NR_POSIX + 201)
+#define __NR_POSIX_reserved34		(__NR_POSIX + 202)
+#define __NR_POSIX_reserved35		(__NR_POSIX + 203)
+#define __NR_POSIX_reserved36		(__NR_POSIX + 204)
+#define __NR_POSIX_reserved37		(__NR_POSIX + 205)
+#define __NR_POSIX_reserved38		(__NR_POSIX + 206)
+#define __NR_POSIX_reserved39		(__NR_POSIX + 207)
+#define __NR_POSIX_reserved40		(__NR_POSIX + 208)
+#define __NR_POSIX_reserved41		(__NR_POSIX + 209)
+#define __NR_POSIX_reserved42		(__NR_POSIX + 210)
+#define __NR_POSIX_reserved43		(__NR_POSIX + 211)
+#define __NR_POSIX_reserved44		(__NR_POSIX + 212)
+#define __NR_POSIX_reserved45		(__NR_POSIX + 213)
+#define __NR_POSIX_reserved46		(__NR_POSIX + 214)
+#define __NR_POSIX_reserved47		(__NR_POSIX + 215)
+#define __NR_POSIX_reserved48		(__NR_POSIX + 216)
+#define __NR_POSIX_reserved49		(__NR_POSIX + 217)
+#define __NR_POSIX_reserved50		(__NR_POSIX + 218)
+#define __NR_POSIX_reserved51		(__NR_POSIX + 219)
+#define __NR_POSIX_reserved52		(__NR_POSIX + 220)
+#define __NR_POSIX_reserved53		(__NR_POSIX + 221)
+#define __NR_POSIX_reserved54		(__NR_POSIX + 222)
+#define __NR_POSIX_reserved55		(__NR_POSIX + 223)
+#define __NR_POSIX_reserved56		(__NR_POSIX + 224)
+#define __NR_POSIX_reserved57		(__NR_POSIX + 225)
+#define __NR_POSIX_reserved58		(__NR_POSIX + 226)
+#define __NR_POSIX_reserved59		(__NR_POSIX + 227)
+#define __NR_POSIX_reserved60		(__NR_POSIX + 228)
+#define __NR_POSIX_reserved61		(__NR_POSIX + 229)
+#define __NR_POSIX_reserved62		(__NR_POSIX + 230)
+#define __NR_POSIX_reserved63		(__NR_POSIX + 231)
+#define __NR_POSIX_reserved64		(__NR_POSIX + 232)
+#define __NR_POSIX_reserved65		(__NR_POSIX + 233)
+#define __NR_POSIX_reserved66		(__NR_POSIX + 234)
+#define __NR_POSIX_reserved67		(__NR_POSIX + 235)
+#define __NR_POSIX_reserved68		(__NR_POSIX + 236)
+#define __NR_POSIX_reserved69		(__NR_POSIX + 237)
+#define __NR_POSIX_reserved70		(__NR_POSIX + 238)
+#define __NR_POSIX_reserved71		(__NR_POSIX + 239)
+#define __NR_POSIX_reserved72		(__NR_POSIX + 240)
+#define __NR_POSIX_reserved73		(__NR_POSIX + 241)
+#define __NR_POSIX_reserved74		(__NR_POSIX + 242)
+#define __NR_POSIX_reserved75		(__NR_POSIX + 243)
+#define __NR_POSIX_reserved76		(__NR_POSIX + 244)
+#define __NR_POSIX_reserved77		(__NR_POSIX + 245)
+#define __NR_POSIX_reserved78		(__NR_POSIX + 246)
+#define __NR_POSIX_reserved79		(__NR_POSIX + 247)
+#define __NR_POSIX_reserved80		(__NR_POSIX + 248)
+#define __NR_POSIX_reserved81		(__NR_POSIX + 249)
+#define __NR_POSIX_reserved82		(__NR_POSIX + 250)
+#define __NR_POSIX_reserved83		(__NR_POSIX + 251)
+#define __NR_POSIX_reserved84		(__NR_POSIX + 252)
+#define __NR_POSIX_reserved85		(__NR_POSIX + 253)
+#define __NR_POSIX_reserved86		(__NR_POSIX + 254)
+#define __NR_POSIX_reserved87		(__NR_POSIX + 255)
+#define __NR_POSIX_reserved88		(__NR_POSIX + 256)
+#define __NR_POSIX_reserved89		(__NR_POSIX + 257)
+#define __NR_POSIX_reserved90		(__NR_POSIX + 258)
+#define __NR_POSIX_reserved91		(__NR_POSIX + 259)
+#define __NR_POSIX_netboot		(__NR_POSIX + 260)
+#define __NR_POSIX_netunboot		(__NR_POSIX + 261)
+#define __NR_POSIX_rdump		(__NR_POSIX + 262)
+#define __NR_POSIX_setsid		(__NR_POSIX + 263)
+#define __NR_POSIX_getmaxsig		(__NR_POSIX + 264)
+#define __NR_POSIX_sigpending		(__NR_POSIX + 265)
+#define __NR_POSIX_sigprocmask		(__NR_POSIX + 266)
+#define __NR_POSIX_sigsuspend		(__NR_POSIX + 267)
+#define __NR_POSIX_sigaction		(__NR_POSIX + 268)
+#define __NR_POSIX_MIPS_reserved1	(__NR_POSIX + 269)
+#define __NR_POSIX_MIPS_reserved2	(__NR_POSIX + 270)
+#define __NR_POSIX_MIPS_reserved3	(__NR_POSIX + 271)
+#define __NR_POSIX_MIPS_reserved4	(__NR_POSIX + 272)
+#define __NR_POSIX_MIPS_reserved5	(__NR_POSIX + 273)
+#define __NR_POSIX_MIPS_reserved6	(__NR_POSIX + 274)
+#define __NR_POSIX_MIPS_reserved7	(__NR_POSIX + 275)
+#define __NR_POSIX_MIPS_reserved8	(__NR_POSIX + 276)
+#define __NR_POSIX_MIPS_reserved9	(__NR_POSIX + 277)
+#define __NR_POSIX_MIPS_reserved10	(__NR_POSIX + 278)
+#define __NR_POSIX_MIPS_reserved11	(__NR_POSIX + 279)
+#define __NR_POSIX_TANDEM_reserved1	(__NR_POSIX + 280)
+#define __NR_POSIX_TANDEM_reserved2	(__NR_POSIX + 281)
+#define __NR_POSIX_TANDEM_reserved3	(__NR_POSIX + 282)
+#define __NR_POSIX_TANDEM_reserved4	(__NR_POSIX + 283)
+#define __NR_POSIX_TANDEM_reserved5	(__NR_POSIX + 284)
+#define __NR_POSIX_TANDEM_reserved6	(__NR_POSIX + 285)
+#define __NR_POSIX_TANDEM_reserved7	(__NR_POSIX + 286)
+#define __NR_POSIX_TANDEM_reserved8	(__NR_POSIX + 287)
+#define __NR_POSIX_TANDEM_reserved9	(__NR_POSIX + 288)
+#define __NR_POSIX_TANDEM_reserved10	(__NR_POSIX + 289)
+#define __NR_POSIX_TANDEM_reserved11	(__NR_POSIX + 290)
+#define __NR_POSIX_TANDEM_reserved12	(__NR_POSIX + 291)
+#define __NR_POSIX_TANDEM_reserved13	(__NR_POSIX + 292)
+#define __NR_POSIX_TANDEM_reserved14	(__NR_POSIX + 293)
+#define __NR_POSIX_TANDEM_reserved15	(__NR_POSIX + 294)
+#define __NR_POSIX_TANDEM_reserved16	(__NR_POSIX + 295)
+#define __NR_POSIX_TANDEM_reserved17	(__NR_POSIX + 296)
+#define __NR_POSIX_TANDEM_reserved18	(__NR_POSIX + 297)
+#define __NR_POSIX_TANDEM_reserved19	(__NR_POSIX + 298)
+#define __NR_POSIX_TANDEM_reserved20	(__NR_POSIX + 299)
+#define __NR_POSIX_SGI_reserved7	(__NR_POSIX + 300)
+#define __NR_POSIX_SGI_reserved8	(__NR_POSIX + 301)
+#define __NR_POSIX_SGI_reserved9	(__NR_POSIX + 302)
+#define __NR_POSIX_SGI_reserved10	(__NR_POSIX + 303)
+#define __NR_POSIX_SGI_reserved11	(__NR_POSIX + 304)
+#define __NR_POSIX_SGI_reserved12	(__NR_POSIX + 305)
+#define __NR_POSIX_SGI_reserved13	(__NR_POSIX + 306)
+#define __NR_POSIX_SGI_reserved14	(__NR_POSIX + 307)
+#define __NR_POSIX_SGI_reserved15	(__NR_POSIX + 308)
+#define __NR_POSIX_SGI_reserved16	(__NR_POSIX + 309)
+#define __NR_POSIX_SGI_reserved17	(__NR_POSIX + 310)
+#define __NR_POSIX_SGI_reserved18	(__NR_POSIX + 311)
+#define __NR_POSIX_SGI_reserved19	(__NR_POSIX + 312)
+#define __NR_POSIX_SGI_reserved20	(__NR_POSIX + 313)
+#define __NR_POSIX_SGI_reserved21	(__NR_POSIX + 314)
+#define __NR_POSIX_SGI_reserved22	(__NR_POSIX + 315)
+#define __NR_POSIX_SGI_reserved23	(__NR_POSIX + 316)
+#define __NR_POSIX_SGI_reserved24	(__NR_POSIX + 317)
+#define __NR_POSIX_SGI_reserved25	(__NR_POSIX + 318)
+#define __NR_POSIX_SGI_reserved26	(__NR_POSIX + 319)
+
+/*
+ * Linux o32 style syscalls are in the range from 4000 to 4999.
+ */
+#define __NR_Linux32			4000
+#define __NR_Linux32_syscall		(__NR_Linux32 +   0)
+#define __NR_Linux32_exit		(__NR_Linux32 +   1)
+#define __NR_Linux32_fork		(__NR_Linux32 +   2)
+#define __NR_Linux32_read		(__NR_Linux32 +   3)
+#define __NR_Linux32_write		(__NR_Linux32 +   4)
+#define __NR_Linux32_open		(__NR_Linux32 +   5)
+#define __NR_Linux32_close		(__NR_Linux32 +   6)
+#define __NR_Linux32_waitpid		(__NR_Linux32 +   7)
+#define __NR_Linux32_creat		(__NR_Linux32 +   8)
+#define __NR_Linux32_link		(__NR_Linux32 +   9)
+#define __NR_Linux32_unlink		(__NR_Linux32 +  10)
+#define __NR_Linux32_execve		(__NR_Linux32 +  11)
+#define __NR_Linux32_chdir		(__NR_Linux32 +  12)
+#define __NR_Linux32_time		(__NR_Linux32 +  13)
+#define __NR_Linux32_mknod		(__NR_Linux32 +  14)
+#define __NR_Linux32_chmod		(__NR_Linux32 +  15)
+#define __NR_Linux32_lchown		(__NR_Linux32 +  16)
+#define __NR_Linux32_break		(__NR_Linux32 +  17)
+#define __NR_Linux32_oldstat		(__NR_Linux32 +  18)
+#define __NR_Linux32_lseek		(__NR_Linux32 +  19)
+#define __NR_Linux32_getpid		(__NR_Linux32 +  20)
+#define __NR_Linux32_mount		(__NR_Linux32 +  21)
+#define __NR_Linux32_umount		(__NR_Linux32 +  22)
+#define __NR_Linux32_setuid		(__NR_Linux32 +  23)
+#define __NR_Linux32_getuid		(__NR_Linux32 +  24)
+#define __NR_Linux32_stime		(__NR_Linux32 +  25)
+#define __NR_Linux32_ptrace		(__NR_Linux32 +  26)
+#define __NR_Linux32_alarm		(__NR_Linux32 +  27)
+#define __NR_Linux32_oldfstat		(__NR_Linux32 +  28)
+#define __NR_Linux32_unused29		(__NR_Linux32 +  29)
+#define __NR_Linux32_utime		(__NR_Linux32 +  30)
+#define __NR_Linux32_stty		(__NR_Linux32 +  31)
+#define __NR_Linux32_gtty		(__NR_Linux32 +  32)
+#define __NR_Linux32_access		(__NR_Linux32 +  33)
+#define __NR_Linux32_nice		(__NR_Linux32 +  34)
+#define __NR_Linux32_ftime		(__NR_Linux32 +  35)
+#define __NR_Linux32_sync		(__NR_Linux32 +  36)
+#define __NR_Linux32_kill		(__NR_Linux32 +  37)
+#define __NR_Linux32_rename		(__NR_Linux32 +  38)
+#define __NR_Linux32_mkdir		(__NR_Linux32 +  39)
+#define __NR_Linux32_rmdir		(__NR_Linux32 +  40)
+#define __NR_Linux32_dup		(__NR_Linux32 +  41)
+#define __NR_Linux32_pipe		(__NR_Linux32 +  42)
+#define __NR_Linux32_times		(__NR_Linux32 +  43)
+#define __NR_Linux32_prof		(__NR_Linux32 +  44)
+#define __NR_Linux32_brk		(__NR_Linux32 +  45)
+#define __NR_Linux32_setgid		(__NR_Linux32 +  46)
+#define __NR_Linux32_getgid		(__NR_Linux32 +  47)
+#define __NR_Linux32_signal		(__NR_Linux32 +  48)
+#define __NR_Linux32_geteuid		(__NR_Linux32 +  49)
+#define __NR_Linux32_getegid		(__NR_Linux32 +  50)
+#define __NR_Linux32_acct		(__NR_Linux32 +  51)
+#define __NR_Linux32_umount2		(__NR_Linux32 +  52)
+#define __NR_Linux32_lock		(__NR_Linux32 +  53)
+#define __NR_Linux32_ioctl		(__NR_Linux32 +  54)
+#define __NR_Linux32_fcntl		(__NR_Linux32 +  55)
+#define __NR_Linux32_mpx		(__NR_Linux32 +  56)
+#define __NR_Linux32_setpgid		(__NR_Linux32 +  57)
+#define __NR_Linux32_ulimit		(__NR_Linux32 +  58)
+#define __NR_Linux32_oldolduname	(__NR_Linux32 +  59)
+#define __NR_Linux32_umask		(__NR_Linux32 +  60)
+#define __NR_Linux32_chroot		(__NR_Linux32 +  61)
+#define __NR_Linux32_ustat		(__NR_Linux32 +  62)
+#define __NR_Linux32_dup2		(__NR_Linux32 +  63)
+#define __NR_Linux32_getppid		(__NR_Linux32 +  64)
+#define __NR_Linux32_getpgrp		(__NR_Linux32 +  65)
+#define __NR_Linux32_setsid		(__NR_Linux32 +  66)
+#define __NR_Linux32_sigaction		(__NR_Linux32 +  67)
+#define __NR_Linux32_sgetmask		(__NR_Linux32 +  68)
+#define __NR_Linux32_ssetmask		(__NR_Linux32 +  69)
+#define __NR_Linux32_setreuid		(__NR_Linux32 +  70)
+#define __NR_Linux32_setregid		(__NR_Linux32 +  71)
+#define __NR_Linux32_sigsuspend		(__NR_Linux32 +  72)
+#define __NR_Linux32_sigpending		(__NR_Linux32 +  73)
+#define __NR_Linux32_sethostname	(__NR_Linux32 +  74)
+#define __NR_Linux32_setrlimit		(__NR_Linux32 +  75)
+#define __NR_Linux32_getrlimit		(__NR_Linux32 +  76)
+#define __NR_Linux32_getrusage		(__NR_Linux32 +  77)
+#define __NR_Linux32_gettimeofday	(__NR_Linux32 +  78)
+#define __NR_Linux32_settimeofday	(__NR_Linux32 +  79)
+#define __NR_Linux32_getgroups		(__NR_Linux32 +  80)
+#define __NR_Linux32_setgroups		(__NR_Linux32 +  81)
+#define __NR_Linux32_reserved82		(__NR_Linux32 +  82)
+#define __NR_Linux32_symlink		(__NR_Linux32 +  83)
+#define __NR_Linux32_oldlstat		(__NR_Linux32 +  84)
+#define __NR_Linux32_readlink		(__NR_Linux32 +  85)
+#define __NR_Linux32_uselib		(__NR_Linux32 +  86)
+#define __NR_Linux32_swapon		(__NR_Linux32 +  87)
+#define __NR_Linux32_reboot		(__NR_Linux32 +  88)
+#define __NR_Linux32_readdir		(__NR_Linux32 +  89)
+#define __NR_Linux32_mmap		(__NR_Linux32 +  90)
+#define __NR_Linux32_munmap		(__NR_Linux32 +  91)
+#define __NR_Linux32_truncate		(__NR_Linux32 +  92)
+#define __NR_Linux32_ftruncate		(__NR_Linux32 +  93)
+#define __NR_Linux32_fchmod		(__NR_Linux32 +  94)
+#define __NR_Linux32_fchown		(__NR_Linux32 +  95)
+#define __NR_Linux32_getpriority	(__NR_Linux32 +  96)
+#define __NR_Linux32_setpriority	(__NR_Linux32 +  97)
+#define __NR_Linux32_profil		(__NR_Linux32 +  98)
+#define __NR_Linux32_statfs		(__NR_Linux32 +  99)
+#define __NR_Linux32_fstatfs		(__NR_Linux32 + 100)
+#define __NR_Linux32_ioperm		(__NR_Linux32 + 101)
+#define __NR_Linux32_socketcall		(__NR_Linux32 + 102)
+#define __NR_Linux32_syslog		(__NR_Linux32 + 103)
+#define __NR_Linux32_setitimer		(__NR_Linux32 + 104)
+#define __NR_Linux32_getitimer		(__NR_Linux32 + 105)
+#define __NR_Linux32_stat		(__NR_Linux32 + 106)
+#define __NR_Linux32_lstat		(__NR_Linux32 + 107)
+#define __NR_Linux32_fstat		(__NR_Linux32 + 108)
+#define __NR_Linux32_olduname		(__NR_Linux32 + 109)
+#define __NR_Linux32_iopl		(__NR_Linux32 + 110)
+#define __NR_Linux32_vhangup		(__NR_Linux32 + 111)
+#define __NR_Linux32_idle		(__NR_Linux32 + 112)
+#define __NR_Linux32_vm86		(__NR_Linux32 + 113)
+#define __NR_Linux32_wait4		(__NR_Linux32 + 114)
+#define __NR_Linux32_swapoff		(__NR_Linux32 + 115)
+#define __NR_Linux32_sysinfo		(__NR_Linux32 + 116)
+#define __NR_Linux32_ipc		(__NR_Linux32 + 117)
+#define __NR_Linux32_fsync		(__NR_Linux32 + 118)
+#define __NR_Linux32_sigreturn		(__NR_Linux32 + 119)
+#define __NR_Linux32_clone		(__NR_Linux32 + 120)
+#define __NR_Linux32_setdomainname	(__NR_Linux32 + 121)
+#define __NR_Linux32_uname		(__NR_Linux32 + 122)
+#define __NR_Linux32_modify_ldt		(__NR_Linux32 + 123)
+#define __NR_Linux32_adjtimex		(__NR_Linux32 + 124)
+#define __NR_Linux32_mprotect		(__NR_Linux32 + 125)
+#define __NR_Linux32_sigprocmask	(__NR_Linux32 + 126)
+#define __NR_Linux32_create_module	(__NR_Linux32 + 127)
+#define __NR_Linux32_init_module	(__NR_Linux32 + 128)
+#define __NR_Linux32_delete_module	(__NR_Linux32 + 129)
+#define __NR_Linux32_get_kernel_syms	(__NR_Linux32 + 130)
+#define __NR_Linux32_quotactl		(__NR_Linux32 + 131)
+#define __NR_Linux32_getpgid		(__NR_Linux32 + 132)
+#define __NR_Linux32_fchdir		(__NR_Linux32 + 133)
+#define __NR_Linux32_bdflush		(__NR_Linux32 + 134)
+#define __NR_Linux32_sysfs		(__NR_Linux32 + 135)
+#define __NR_Linux32_personality	(__NR_Linux32 + 136)
+#define __NR_Linux32_afs_syscall	(__NR_Linux32 + 137) /* Syscall for Andrew File System */
+#define __NR_Linux32_setfsuid		(__NR_Linux32 + 138)
+#define __NR_Linux32_setfsgid		(__NR_Linux32 + 139)
+#define __NR_Linux32__llseek		(__NR_Linux32 + 140)
+#define __NR_Linux32_getdents		(__NR_Linux32 + 141)
+#define __NR_Linux32__newselect		(__NR_Linux32 + 142)
+#define __NR_Linux32_flock		(__NR_Linux32 + 143)
+#define __NR_Linux32_msync		(__NR_Linux32 + 144)
+#define __NR_Linux32_readv		(__NR_Linux32 + 145)
+#define __NR_Linux32_writev		(__NR_Linux32 + 146)
+#define __NR_Linux32_cacheflush		(__NR_Linux32 + 147)
+#define __NR_Linux32_cachectl		(__NR_Linux32 + 148)
+#define __NR_Linux32_sysmips		(__NR_Linux32 + 149)
+#define __NR_Linux32_unused150		(__NR_Linux32 + 150)
+#define __NR_Linux32_getsid		(__NR_Linux32 + 151)
+#define __NR_Linux32_fdatasync		(__NR_Linux32 + 152)
+#define __NR_Linux32__sysctl		(__NR_Linux32 + 153)
+#define __NR_Linux32_mlock		(__NR_Linux32 + 154)
+#define __NR_Linux32_munlock		(__NR_Linux32 + 155)
+#define __NR_Linux32_mlockall		(__NR_Linux32 + 156)
+#define __NR_Linux32_munlockall		(__NR_Linux32 + 157)
+#define __NR_Linux32_sched_setparam	(__NR_Linux32 + 158)
+#define __NR_Linux32_sched_getparam	(__NR_Linux32 + 159)
+#define __NR_Linux32_sched_setscheduler	(__NR_Linux32 + 160)
+#define __NR_Linux32_sched_getscheduler	(__NR_Linux32 + 161)
+#define __NR_Linux32_sched_yield	(__NR_Linux32 + 162)
+#define __NR_Linux32_sched_get_priority_max	(__NR_Linux32 + 163)
+#define __NR_Linux32_sched_get_priority_min	(__NR_Linux32 + 164)
+#define __NR_Linux32_sched_rr_get_interval	(__NR_Linux32 + 165)
+#define __NR_Linux32_nanosleep		(__NR_Linux32 + 166)
+#define __NR_Linux32_mremap		(__NR_Linux32 + 167)
+#define __NR_Linux32_accept		(__NR_Linux32 + 168)
+#define __NR_Linux32_bind		(__NR_Linux32 + 169)
+#define __NR_Linux32_connect		(__NR_Linux32 + 170)
+#define __NR_Linux32_getpeername	(__NR_Linux32 + 171)
+#define __NR_Linux32_getsockname	(__NR_Linux32 + 172)
+#define __NR_Linux32_getsockopt		(__NR_Linux32 + 173)
+#define __NR_Linux32_listen		(__NR_Linux32 + 174)
+#define __NR_Linux32_recv		(__NR_Linux32 + 175)
+#define __NR_Linux32_recvfrom		(__NR_Linux32 + 176)
+#define __NR_Linux32_recvmsg		(__NR_Linux32 + 177)
+#define __NR_Linux32_send		(__NR_Linux32 + 178)
+#define __NR_Linux32_sendmsg		(__NR_Linux32 + 179)
+#define __NR_Linux32_sendto		(__NR_Linux32 + 180)
+#define __NR_Linux32_setsockopt		(__NR_Linux32 + 181)
+#define __NR_Linux32_shutdown		(__NR_Linux32 + 182)
+#define __NR_Linux32_socket		(__NR_Linux32 + 183)
+#define __NR_Linux32_socketpair		(__NR_Linux32 + 184)
+#define __NR_Linux32_setresuid		(__NR_Linux32 + 185)
+#define __NR_Linux32_getresuid		(__NR_Linux32 + 186)
+#define __NR_Linux32_query_module	(__NR_Linux32 + 187)
+#define __NR_Linux32_poll		(__NR_Linux32 + 188)
+#define __NR_Linux32_nfsservctl		(__NR_Linux32 + 189)
+#define __NR_Linux32_setresgid		(__NR_Linux32 + 190)
+#define __NR_Linux32_getresgid		(__NR_Linux32 + 191)
+#define __NR_Linux32_prctl		(__NR_Linux32 + 192)
+#define __NR_Linux32_rt_sigreturn	(__NR_Linux32 + 193)
+#define __NR_Linux32_rt_sigaction	(__NR_Linux32 + 194)
+#define __NR_Linux32_rt_sigprocmask	(__NR_Linux32 + 195)
+#define __NR_Linux32_rt_sigpending	(__NR_Linux32 + 196)
+#define __NR_Linux32_rt_sigtimedwait	(__NR_Linux32 + 197)
+#define __NR_Linux32_rt_sigqueueinfo	(__NR_Linux32 + 198)
+#define __NR_Linux32_rt_sigsuspend	(__NR_Linux32 + 199)
+#define __NR_Linux32_pread		(__NR_Linux32 + 200)
+#define __NR_Linux32_pwrite		(__NR_Linux32 + 201)
+#define __NR_Linux32_chown		(__NR_Linux32 + 202)
+#define __NR_Linux32_getcwd		(__NR_Linux32 + 203)
+#define __NR_Linux32_capget		(__NR_Linux32 + 204)
+#define __NR_Linux32_capset		(__NR_Linux32 + 205)
+#define __NR_Linux32_sigaltstack	(__NR_Linux32 + 206)
+#define __NR_Linux32_sendfile		(__NR_Linux32 + 207)
+#define __NR_Linux32_getpmsg		(__NR_Linux32 + 208)
+#define __NR_Linux32_putpmsg		(__NR_Linux32 + 209)
+#define __NR_Linux32_mmap2		(__NR_Linux32 + 210)
+#define __NR_Linux32_truncate64		(__NR_Linux32 + 211)
+#define __NR_Linux32_ftruncate64	(__NR_Linux32 + 212)
+#define __NR_Linux32_stat64		(__NR_Linux32 + 213)
+#define __NR_Linux32_lstat64		(__NR_Linux32 + 214)
+#define __NR_Linux32_fstat64		(__NR_Linux32 + 215)
+#define __NR_Linux32_root_pivot		(__NR_Linux32 + 216)
+
+/*
+ * Offset of the last Linux o32 flavoured syscall
+ */
+#define __NR_Linux32_syscalls		216
+
+/*
+ * Linux 64-bit syscalls are in the range from 5000 to 5999.
+ */
+#define __NR_Linux			5000
+#define __NR_syscall			(__NR_Linux +   0)
+#define __NR_exit			(__NR_Linux +   1)
+#define __NR_fork			(__NR_Linux +   2)
+#define __NR_read			(__NR_Linux +   3)
+#define __NR_write			(__NR_Linux +   4)
+#define __NR_open			(__NR_Linux +   5)
+#define __NR_close			(__NR_Linux +   6)
+#define __NR_waitpid			(__NR_Linux +   7)
+#define __NR_creat			(__NR_Linux +   8)
+#define __NR_link			(__NR_Linux +   9)
+#define __NR_unlink			(__NR_Linux +  10)
+#define __NR_execve			(__NR_Linux +  11)
+#define __NR_chdir			(__NR_Linux +  12)
+#define __NR_time			(__NR_Linux +  13)
+#define __NR_mknod			(__NR_Linux +  14)
+#define __NR_chmod			(__NR_Linux +  15)
+#define __NR_lchown			(__NR_Linux +  16)
+#define __NR_break			(__NR_Linux +  17)
+#define __NR_oldstat			(__NR_Linux +  18)
+#define __NR_lseek			(__NR_Linux +  19)
+#define __NR_getpid			(__NR_Linux +  20)
+#define __NR_mount			(__NR_Linux +  21)
+#define __NR_umount			(__NR_Linux +  22)
+#define __NR_setuid			(__NR_Linux +  23)
+#define __NR_getuid			(__NR_Linux +  24)
+#define __NR_stime			(__NR_Linux +  25)
+#define __NR_ptrace			(__NR_Linux +  26)
+#define __NR_alarm			(__NR_Linux +  27)
+#define __NR_oldfstat			(__NR_Linux +  28)
+#define __NR_unused29			(__NR_Linux +  29)
+#define __NR_utime			(__NR_Linux +  30)
+#define __NR_stty			(__NR_Linux +  31)
+#define __NR_gtty			(__NR_Linux +  32)
+#define __NR_access			(__NR_Linux +  33)
+#define __NR_nice			(__NR_Linux +  34)
+#define __NR_ftime			(__NR_Linux +  35)
+#define __NR_sync			(__NR_Linux +  36)
+#define __NR_kill			(__NR_Linux +  37)
+#define __NR_rename			(__NR_Linux +  38)
+#define __NR_mkdir			(__NR_Linux +  39)
+#define __NR_rmdir			(__NR_Linux +  40)
+#define __NR_dup			(__NR_Linux +  41)
+#define __NR_pipe			(__NR_Linux +  42)
+#define __NR_times			(__NR_Linux +  43)
+#define __NR_prof			(__NR_Linux +  44)
+#define __NR_brk			(__NR_Linux +  45)
+#define __NR_setgid			(__NR_Linux +  46)
+#define __NR_getgid			(__NR_Linux +  47)
+#define __NR_signal			(__NR_Linux +  48)
+#define __NR_geteuid			(__NR_Linux +  49)
+#define __NR_getegid			(__NR_Linux +  50)
+#define __NR_acct			(__NR_Linux +  51)
+#define __NR_umount2			(__NR_Linux +  52)
+#define __NR_lock			(__NR_Linux +  53)
+#define __NR_ioctl			(__NR_Linux +  54)
+#define __NR_fcntl			(__NR_Linux +  55)
+#define __NR_mpx			(__NR_Linux +  56)
+#define __NR_setpgid			(__NR_Linux +  57)
+#define __NR_ulimit			(__NR_Linux +  58)
+#define __NR_oldolduname		(__NR_Linux +  59)
+#define __NR_umask			(__NR_Linux +  60)
+#define __NR_chroot			(__NR_Linux +  61)
+#define __NR_ustat			(__NR_Linux +  62)
+#define __NR_dup2			(__NR_Linux +  63)
+#define __NR_getppid			(__NR_Linux +  64)
+#define __NR_getpgrp			(__NR_Linux +  65)
+#define __NR_setsid			(__NR_Linux +  66)
+#define __NR_sigaction			(__NR_Linux +  67)
+#define __NR_sgetmask			(__NR_Linux +  68)
+#define __NR_ssetmask			(__NR_Linux +  69)
+#define __NR_setreuid			(__NR_Linux +  70)
+#define __NR_setregid			(__NR_Linux +  71)
+#define __NR_sigsuspend			(__NR_Linux +  72)
+#define __NR_sigpending			(__NR_Linux +  73)
+#define __NR_sethostname		(__NR_Linux +  74)
+#define __NR_setrlimit			(__NR_Linux +  75)
+#define __NR_getrlimit			(__NR_Linux +  76)
+#define __NR_getrusage			(__NR_Linux +  77)
+#define __NR_gettimeofday		(__NR_Linux +  78)
+#define __NR_settimeofday		(__NR_Linux +  79)
+#define __NR_getgroups			(__NR_Linux +  80)
+#define __NR_setgroups			(__NR_Linux +  81)
+#define __NR_reserved82			(__NR_Linux +  82)
+#define __NR_symlink			(__NR_Linux +  83)
+#define __NR_oldlstat			(__NR_Linux +  84)
+#define __NR_readlink			(__NR_Linux +  85)
+#define __NR_uselib			(__NR_Linux +  86)
+#define __NR_swapon			(__NR_Linux +  87)
+#define __NR_reboot			(__NR_Linux +  88)
+#define __NR_readdir			(__NR_Linux +  89)
+#define __NR_mmap			(__NR_Linux +  90)
+#define __NR_munmap			(__NR_Linux +  91)
+#define __NR_truncate			(__NR_Linux +  92)
+#define __NR_ftruncate			(__NR_Linux +  93)
+#define __NR_fchmod			(__NR_Linux +  94)
+#define __NR_fchown			(__NR_Linux +  95)
+#define __NR_getpriority		(__NR_Linux +  96)
+#define __NR_setpriority		(__NR_Linux +  97)
+#define __NR_profil			(__NR_Linux +  98)
+#define __NR_statfs			(__NR_Linux +  99)
+#define __NR_fstatfs			(__NR_Linux + 100)
+#define __NR_ioperm			(__NR_Linux + 101)
+#define __NR_socketcall			(__NR_Linux + 102)
+#define __NR_syslog			(__NR_Linux + 103)
+#define __NR_setitimer			(__NR_Linux + 104)
+#define __NR_getitimer			(__NR_Linux + 105)
+#define __NR_stat			(__NR_Linux + 106)
+#define __NR_lstat			(__NR_Linux + 107)
+#define __NR_fstat			(__NR_Linux + 108)
+#define __NR_olduname			(__NR_Linux + 109)
+#define __NR_iopl			(__NR_Linux + 110)
+#define __NR_vhangup			(__NR_Linux + 111)
+#define __NR_idle			(__NR_Linux + 112)
+#define __NR_vm86			(__NR_Linux + 113)
+#define __NR_wait4			(__NR_Linux + 114)
+#define __NR_swapoff			(__NR_Linux + 115)
+#define __NR_sysinfo			(__NR_Linux + 116)
+#define __NR_ipc			(__NR_Linux + 117)
+#define __NR_fsync			(__NR_Linux + 118)
+#define __NR_sigreturn			(__NR_Linux + 119)
+#define __NR_clone			(__NR_Linux + 120)
+#define __NR_setdomainname		(__NR_Linux + 121)
+#define __NR_uname			(__NR_Linux + 122)
+#define __NR_modify_ldt			(__NR_Linux + 123)
+#define __NR_adjtimex			(__NR_Linux + 124)
+#define __NR_mprotect			(__NR_Linux + 125)
+#define __NR_sigprocmask		(__NR_Linux + 126)
+#define __NR_create_module		(__NR_Linux + 127)
+#define __NR_init_module		(__NR_Linux + 128)
+#define __NR_delete_module		(__NR_Linux + 129)
+#define __NR_get_kernel_syms		(__NR_Linux + 130)
+#define __NR_quotactl			(__NR_Linux + 131)
+#define __NR_getpgid			(__NR_Linux + 132)
+#define __NR_fchdir			(__NR_Linux + 133)
+#define __NR_bdflush			(__NR_Linux + 134)
+#define __NR_sysfs			(__NR_Linux + 135)
+#define __NR_personality		(__NR_Linux + 136)
+#define __NR_afs_syscall		(__NR_Linux + 137) /* Syscall for Andrew File System */
+#define __NR_setfsuid			(__NR_Linux + 138)
+#define __NR_setfsgid			(__NR_Linux + 139)
+#define __NR__llseek			(__NR_Linux + 140)
+#define __NR_getdents			(__NR_Linux + 141)
+#define __NR__newselect			(__NR_Linux + 142)
+#define __NR_flock			(__NR_Linux + 143)
+#define __NR_msync			(__NR_Linux + 144)
+#define __NR_readv			(__NR_Linux + 145)
+#define __NR_writev			(__NR_Linux + 146)
+#define __NR_cacheflush			(__NR_Linux + 147)
+#define __NR_cachectl			(__NR_Linux + 148)
+#define __NR_sysmips			(__NR_Linux + 149)
+#define __NR_unused150			(__NR_Linux + 150)
+#define __NR_getsid			(__NR_Linux + 151)
+#define __NR_fdatasync			(__NR_Linux + 152)
+#define __NR__sysctl			(__NR_Linux + 153)
+#define __NR_mlock			(__NR_Linux + 154)
+#define __NR_munlock			(__NR_Linux + 155)
+#define __NR_mlockall			(__NR_Linux + 156)
+#define __NR_munlockall			(__NR_Linux + 157)
+#define __NR_sched_setparam		(__NR_Linux + 158)
+#define __NR_sched_getparam		(__NR_Linux + 159)
+#define __NR_sched_setscheduler		(__NR_Linux + 160)
+#define __NR_sched_getscheduler		(__NR_Linux + 161)
+#define __NR_sched_yield		(__NR_Linux + 162)
+#define __NR_sched_get_priority_max	(__NR_Linux + 163)
+#define __NR_sched_get_priority_min	(__NR_Linux + 164)
+#define __NR_sched_rr_get_interval	(__NR_Linux + 165)
+#define __NR_nanosleep			(__NR_Linux + 166)
+#define __NR_mremap			(__NR_Linux + 167)
+#define __NR_accept			(__NR_Linux + 168)
+#define __NR_bind			(__NR_Linux + 169)
+#define __NR_connect			(__NR_Linux + 170)
+#define __NR_getpeername		(__NR_Linux + 171)
+#define __NR_getsockname		(__NR_Linux + 172)
+#define __NR_getsockopt			(__NR_Linux + 173)
+#define __NR_listen			(__NR_Linux + 174)
+#define __NR_recv			(__NR_Linux + 175)
+#define __NR_recvfrom			(__NR_Linux + 176)
+#define __NR_recvmsg			(__NR_Linux + 177)
+#define __NR_send			(__NR_Linux + 178)
+#define __NR_sendmsg			(__NR_Linux + 179)
+#define __NR_sendto			(__NR_Linux + 180)
+#define __NR_setsockopt			(__NR_Linux + 181)
+#define __NR_shutdown			(__NR_Linux + 182)
+#define __NR_socket			(__NR_Linux + 183)
+#define __NR_socketpair			(__NR_Linux + 184)
+#define __NR_setresuid			(__NR_Linux + 185)
+#define __NR_getresuid			(__NR_Linux + 186)
+#define __NR_query_module		(__NR_Linux + 187)
+#define __NR_poll			(__NR_Linux + 188)
+#define __NR_nfsservctl			(__NR_Linux + 189)
+#define __NR_setresgid			(__NR_Linux + 190)
+#define __NR_getresgid			(__NR_Linux + 191)
+#define __NR_prctl			(__NR_Linux + 192)
+#define __NR_rt_sigreturn		(__NR_Linux + 193)
+#define __NR_rt_sigaction		(__NR_Linux + 194)
+#define __NR_rt_sigprocmask		(__NR_Linux + 195)
+#define __NR_rt_sigpending		(__NR_Linux + 196)
+#define __NR_rt_sigtimedwait		(__NR_Linux + 197)
+#define __NR_rt_sigqueueinfo		(__NR_Linux + 198)
+#define __NR_rt_sigsuspend		(__NR_Linux + 199)
+#define __NR_pread			(__NR_Linux + 200)
+#define __NR_pwrite			(__NR_Linux + 201)
+#define __NR_chown			(__NR_Linux + 202)
+#define __NR_getcwd			(__NR_Linux + 203)
+#define __NR_capget			(__NR_Linux + 204)
+#define __NR_capset			(__NR_Linux + 205)
+#define __NR_sigaltstack		(__NR_Linux + 206)
+#define __NR_sendfile			(__NR_Linux + 207)
+#define __NR_getpmsg			(__NR_Linux + 208)
+#define __NR_putpmsg			(__NR_Linux + 209)
+#define __NR_root_pivot			(__NR_Linux + 210)
+
+/*
+ * Offset of the last Linux flavoured syscall
+ */
+#define __NR_Linux_syscalls		210
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+register long __res __asm__ ("$2"); \
+register long __err __asm__ ("$7"); \
+__asm__ volatile ("li\t$2,%2\n\t" \
+		  "syscall" \
+                  : "=r" (__res), "=r" (__err) \
+                  : "i" (__NR_##name) \
+                  : "$8","$9","$10","$11","$12","$13","$14","$15","$24"); \
+if (__err == 0) \
+	return (type) __res; \
+errno = __res; \
+return -1; \
+}
+
+/*
+ * DANGER: This macro isn't usable for the pipe(2) call
+ * which has a unusual return convention.
+ */
+#define _syscall1(type,name,atype,a) \
+type name(atype a) \
+{ \
+register long __res __asm__ ("$2"); \
+register long __err __asm__ ("$7"); \
+__asm__ volatile ("move\t$4,%3\n\t" \
+		  "li\t$2,%2\n\t" \
+                  "syscall" \
+                  : "=r" (__res), "=r" (__err) \
+                  : "i" (__NR_##name),"r" ((long)(a)) \
+                  : "$4","$8","$9","$10","$11","$12","$13","$14","$15","$24"); \
+if (__err == 0) \
+	return (type) __res; \
+errno = __res; \
+return -1; \
+}
+
+#define _syscall2(type,name,atype,a,btype,b) \
+type name(atype a,btype b) \
+{ \
+register long __res __asm__ ("$2"); \
+register long __err __asm__ ("$7"); \
+__asm__ volatile ("move\t$4,%3\n\t" \
+                  "move\t$5,%4\n\t" \
+		  "li\t$2,%2\n\t" \
+                  "syscall" \
+                  : "=r" (__res), "=r" (__err) \
+                  : "i" (__NR_##name),"r" ((long)(a)), \
+                                      "r" ((long)(b)) \
+                  : "$4","$5","$8","$9","$10","$11","$12","$13","$14","$15", \
+                    "$24"); \
+if (__err == 0) \
+	return (type) __res; \
+errno = __res; \
+return -1; \
+}
+
+#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
+type name (atype a, btype b, ctype c) \
+{ \
+register long __res __asm__ ("$2"); \
+register long __err __asm__ ("$7"); \
+__asm__ volatile ("move\t$4,%3\n\t" \
+                  "move\t$5,%4\n\t" \
+                  "move\t$6,%5\n\t" \
+		  "li\t$2,%2\n\t" \
+                  "syscall" \
+                  : "=r" (__res), "=r" (__err) \
+                  : "i" (__NR_##name),"r" ((long)(a)), \
+                                      "r" ((long)(b)), \
+                                      "r" ((long)(c)) \
+                  : "$4","$5","$6","$8","$9","$10","$11","$12","$13","$14", \
+                    "$15","$24"); \
+if (__err == 0) \
+	return (type) __res; \
+errno = __res; \
+return -1; \
+}
+
+#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name (atype a, btype b, ctype c, dtype d) \
+{ \
+register long __res __asm__ ("$2"); \
+register long __err __asm__ ("$7"); \
+__asm__ volatile ("move\t$4,%3\n\t" \
+                  "move\t$5,%4\n\t" \
+                  "move\t$6,%5\n\t" \
+                  "move\t$7,%6\n\t" \
+		  "li\t$2,%2\n\t" \
+                  "syscall" \
+                  : "=r" (__res), "=r" (__err) \
+                  : "i" (__NR_##name),"r" ((long)(a)), \
+                                      "r" ((long)(b)), \
+                                      "r" ((long)(c)), \
+                                      "r" ((long)(d)) \
+                  : "$4","$5","$6","$8","$9","$10","$11","$12","$13","$14", \
+                    "$15","$24"); \
+if (__err == 0) \
+	return (type) __res; \
+errno = __res; \
+return -1; \
+}
+
+#if (_MIPS_SIM == _ABIN32) || (_MIPS_SIM == _ABI64)
+
+#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name (atype a,btype b,ctype c,dtype d,etype e) \
+{ \
+register long __res __asm__ ("$2"); \
+register long __err __asm__ ("$7"); \
+__asm__ volatile ("move\t$4,%3\n\t" \
+                  "move\t$5,%4\n\t" \
+                  "move\t$6,%5\n\t" \
+                  "move\t$7,%6\n\t" \
+		  "move\t$8,%7\n\t" \
+		  "sw\t$2,16($29)\n\t" \
+		  "li\t$2,%2\n\t" \
+                  "syscall" \
+                  : "=r" (__res), "=r" (__err) \
+                  : "i" (__NR_##name),"r" ((long)(a)), \
+                                      "r" ((long)(b)), \
+                                      "r" ((long)(c)), \
+                                      "r" ((long)(d)), \
+                                      "r" ((long)(e)) \
+                  : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \
+                    "$13","$14","$15","$24"); \
+if (__err == 0) \
+	return (type) __res; \
+errno = __res; \
+return -1; \
+}
+
+#define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \
+type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
+{ \
+register long __res __asm__ ("$2"); \
+register long __err __asm__ ("$7"); \
+__asm__ volatile ("move\t$4,%3\n\t" \
+                  "move\t$5,%4\n\t" \
+                  "move\t$6,%5\n\t" \
+                  "move\t$7,%6\n\t" \
+                  "move\t$8,%7\n\t" \
+                  "move\t$9,%8\n\t" \
+		  "li\t$2,%2\n\t" \
+                  "syscall" \
+                  : "=r" (__res), "=r" (__err) \
+                  : "i" (__NR_##name),"r" ((long)(a)), \
+                                      "r" ((long)(b)), \
+                                      "r" ((long)(c)), \
+                                      "r" ((long)(d)), \
+                                      "m" ((long)(e)), \
+                                      "m" ((long)(f)) \
+                  : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \
+                    "$12","$13","$14","$15","$24"); \
+if (__err == 0) \
+	return (type) __res; \
+errno = __res; \
+return -1; \
+}
+
+#define _syscall7(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f,gtype,g) \
+type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \
+{ \
+register long __res __asm__ ("$2"); \
+register long __err __asm__ ("$7"); \
+__asm__ volatile ("move\t$4,%3\n\t" \
+                  "move\t$5,%4\n\t" \
+                  "move\t$6,%5\n\t" \
+                  "move\t$7,%6\n\t" \
+                  "move\t$8,%7\n\t" \
+                  "move\t$9,%8\n\t" \
+                  "move\t$10,%9\n\t" \
+		  "li\t$2,%2\n\t" \
+                  "syscall" \
+                  : "=r" (__res), "=r" (__err) \
+                  : "i" (__NR_##name),"r" ((long)(a)), \
+                                      "r" ((long)(b)), \
+                                      "r" ((long)(c)), \
+                                      "r" ((long)(d)), \
+                                      "r" ((long)(e)), \
+                                      "r" ((long)(f)), \
+                                      "r" ((long)(g)) \
+                  : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \
+                    "$12","$13","$14","$15","$24"); \
+if (__err == 0) \
+	return (type) __res; \
+errno = __res; \
+return -1; \
+}
+
+#else /* not N32 or 64 ABI */
+
+/* These are here for sake of fucking lusercode living in the fucking believe
+   having to fuck around with the syscall interface themselfes.  */
+
+#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name (atype a,btype b,ctype c,dtype d,etype e) \
+{ \
+register long __res __asm__ ("$2"); \
+register long __err __asm__ ("$7"); \
+__asm__ volatile ("move\t$4,%3\n\t" \
+                  "move\t$5,%4\n\t" \
+                  "move\t$6,%5\n\t" \
+		  "lw\t$2,%7\n\t" \
+                  "move\t$7,%6\n\t" \
+		  "subu\t$29,24\n\t" \
+		  "sw\t$2,16($29)\n\t" \
+		  "li\t$2,%2\n\t" \
+                  "syscall\n\t" \
+		  "addiu\t$29,24" \
+                  : "=r" (__res), "=r" (__err) \
+                  : "i" (__NR_##name),"r" ((long)(a)), \
+                                      "r" ((long)(b)), \
+                                      "r" ((long)(c)), \
+                                      "r" ((long)(d)), \
+                                      "m" ((long)(e)) \
+                  : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \
+                    "$13","$14","$15","$24"); \
+if (__err == 0) \
+	return (type) __res; \
+errno = __res; \
+return -1; \
+}
+
+#define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \
+type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
+{ \
+register long __res __asm__ ("$2"); \
+register long __err __asm__ ("$7"); \
+__asm__ volatile ("move\t$4,%3\n\t" \
+                  "move\t$5,%4\n\t" \
+                  "move\t$6,%5\n\t" \
+		  "lw\t$2,%7\n\t" \
+		  "lw\t$3,%8\n\t" \
+                  "move\t$7,%6\n\t" \
+		  "subu\t$29,24\n\t" \
+		  "sw\t$2,16($29)\n\t" \
+		  "sw\t$3,20($29)\n\t" \
+		  "li\t$2,%2\n\t" \
+                  "syscall\n\t" \
+		  "addiu\t$29,24" \
+                  : "=r" (__res), "=r" (__err) \
+                  : "i" (__NR_##name),"r" ((long)(a)), \
+                                      "r" ((long)(b)), \
+                                      "r" ((long)(c)), \
+                                      "r" ((long)(d)), \
+                                      "m" ((long)(e)), \
+                                      "m" ((long)(f)) \
+                  : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \
+                    "$12","$13","$14","$15","$24"); \
+if (__err == 0) \
+	return (type) __res; \
+errno = __res; \
+return -1; \
+}
+
+#define _syscall7(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f,gtype,g) \
+type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \
+{ \
+register long __res __asm__ ("$2"); \
+register long __err __asm__ ("$7"); \
+__asm__ volatile ("move\t$4,%3\n\t" \
+                  "move\t$5,%4\n\t" \
+                  "move\t$6,%5\n\t" \
+		  "lw\t$2,%7\n\t" \
+		  "lw\t$3,%8\n\t" \
+                  "move\t$7,%6\n\t" \
+		  "subu\t$29,32\n\t" \
+		  "sw\t$2,16($29)\n\t" \
+		  "lw\t$2,%9\n\t" \
+		  "sw\t$3,20($29)\n\t" \
+		  "sw\t$2,24($29)\n\t" \
+		  "li\t$2,%2\n\t" \
+                  "syscall\n\t" \
+		  "addiu\t$29,32" \
+                  : "=r" (__res), "=r" (__err) \
+                  : "i" (__NR_##name),"r" ((long)(a)), \
+                                      "r" ((long)(b)), \
+                                      "r" ((long)(c)), \
+                                      "r" ((long)(d)), \
+                                      "m" ((long)(e)), \
+                                      "m" ((long)(f)), \
+                                      "m" ((long)(g)) \
+                  : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \
+                    "$12","$13","$14","$15","$24"); \
+if (__err == 0) \
+	return (type) __res; \
+errno = __res; \
+return -1; \
+}
+
+#endif
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
+
+static inline pid_t wait(int * wait_stat)
+{
+	return waitpid(-1,wait_stat,0);
+}
+
+#endif /* !defined (__KERNEL_SYSCALLS__) */
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+
+#endif /* _ASM_UNISTD_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/user.h linux/include/asm-mips64/user.h
--- v2.3.47/linux/include/asm-mips64/user.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/user.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,60 @@
+/* $Id: user.h,v 1.1 1999/08/20 21:59:09 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_USER_H
+#define _ASM_USER_H
+
+#include <linux/ptrace.h>
+
+#include <asm/page.h>
+#include <asm/reg.h>
+
+/*
+ * Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the `trad-core' bfd, NOT the irix-core).  The file
+ * contents are as follows:
+ *
+ *  upage: 1 page consisting of a user struct that tells gdb
+ *	what is present in the file.  Directly after this is a
+ *	copy of the task_struct, which is currently not used by gdb,
+ *	but it may come in handy at some point.  All of the registers
+ *	are stored as part of the upage.  The upage should always be
+ *	only one page long.
+ *  data: The data segment follows next.  We use current->end_text to
+ *	current->brk to pick up all of the user variables, plus any memory
+ *	that may have been sbrk'ed.  No attempt is made to determine if a
+ *	page is demand-zero or if a page is totally unused, we just cover
+ *	the entire range.  All of the addresses are rounded in such a way
+ *	that an integral number of pages is written.
+ *  stack: We need the stack information in order to get a meaningful
+ *	backtrace.  We need to write the data from usp to
+ *	current->start_stack, so we round each of these in order to be able
+ *	to write an integer number of pages.
+ */
+struct user {
+	unsigned long	regs[EF_SIZE/4+64];	/* integer and fp regs */
+	size_t		u_tsize;		/* text size (pages) */
+	size_t		u_dsize;		/* data size (pages) */
+	size_t		u_ssize;		/* stack size (pages) */
+	unsigned long	start_code;		/* text starting address */
+	unsigned long	start_data;		/* data starting address */
+	unsigned long	start_stack;		/* stack starting address */
+	long int	signal;			/* signal causing core dump */
+	struct regs *	u_ar0;			/* help gdb find registers */
+	unsigned long	magic;			/* identifies a core file */
+	char		u_comm[32];		/* user command name */
+};
+
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_DATA_START_ADDR	(u.start_data)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
+
+#endif /* _ASM_USER_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/usioctl.h linux/include/asm-mips64/usioctl.h
--- v2.3.47/linux/include/asm-mips64/usioctl.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/usioctl.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,33 @@
+/* $Id: usioctl.h,v 1.1 1999/08/19 22:56:35 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * usema/usemaclone-related stuff.
+ *
+ * `Inspired' by IRIX's sys/usioctl.h
+ *
+ * Mike.
+ */
+#ifndef _ASM_USIOCTL_H
+#define _ASM_USIOCTL_H
+
+/* ioctls */
+#define UIOC	('u' << 16 | 's' << 8)
+
+#define UIOCATTACHSEMA	(UIOC|2)	/* attach to sema */
+#define UIOCBLOCK	(UIOC|3)	/* block sync "intr"? */
+#define UIOCABLOCK	(UIOC|4)	/* block async */
+#define UIOCNOIBLOCK	(UIOC|5)	/* IRIX: block sync intr
+					   Linux: block sync nointr */
+#define UIOCUNBLOCK	(UIOC|6)	/* unblock sync */
+#define UIOCAUNBLOCK	(UIOC|7)	/* unblock async */
+#define UIOCINIT	(UIOC|8)	/* init sema (async) */
+
+typedef struct usattach_s {
+  dev_t	us_dev;		/* attach dev */
+  void	*us_handle;	/* userland semaphore handle */
+} usattach_t;
+
+#endif /* _ASM_USIOCTL_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/watch.h linux/include/asm-mips64/watch.h
--- v2.3.47/linux/include/asm-mips64/watch.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/watch.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,38 @@
+/* $Id: watch.h,v 1.1 1999/09/28 22:27:20 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_WATCH_H
+#define _ASM_WATCH_H
+
+#include <linux/linkage.h>
+
+/*
+ * Types of reference for watch_set()
+ */
+enum wref_type {
+	wr_save = 1,
+	wr_load = 2
+};
+
+extern char watch_available;
+
+extern asmlinkage void __watch_set(unsigned long addr, enum wref_type ref);
+extern asmlinkage void __watch_clear(void);
+extern asmlinkage void __watch_reenable(void);
+
+#define watch_set(addr, ref)					\
+	if (watch_available)					\
+		__watch_set(addr, ref)
+#define watch_clear()						\
+	if (watch_available)					\
+		__watch_clear()
+#define watch_reenable()					\
+	if (watch_available)					\
+		__watch_reenable()
+
+#endif _ASM_WATCH_H
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/xtalk/xtalk.h linux/include/asm-mips64/xtalk/xtalk.h
--- v2.3.47/linux/include/asm-mips64/xtalk/xtalk.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/xtalk/xtalk.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,53 @@
+/* $Id: xtalk.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * xtalk.h -- platform-independent crosstalk interface, derived from
+ * IRIX <sys/PCI/bridge.h>, revision 1.38.
+ *
+ * Copyright (C) 1995 - 1997, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_XTALK_XTALK_H
+#define _ASM_XTALK_XTALK_H
+
+#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+/*
+ * User-level device driver visible types
+ */
+typedef char            xwidgetnum_t;	/* xtalk widget number  (0..15) */
+
+#define XWIDGET_NONE		-1
+
+typedef int xwidget_part_num_t;	/* xtalk widget part number */
+
+#define XWIDGET_PART_NUM_NONE	-1
+
+typedef int             xwidget_rev_num_t;	/* xtalk widget revision number */
+
+#define XWIDGET_REV_NUM_NONE	-1
+
+typedef int xwidget_mfg_num_t;	/* xtalk widget manufacturing ID */
+
+#define XWIDGET_MFG_NUM_NONE	-1
+
+typedef struct xtalk_piomap_s *xtalk_piomap_t;
+
+/* It is often convenient to fold the XIO target port
+ * number into the XIO address.
+ */
+#define	XIO_NOWHERE	(0xFFFFFFFFFFFFFFFFull)
+#define	XIO_ADDR_BITS	(0x0000FFFFFFFFFFFFull)
+#define	XIO_PORT_BITS	(0xF000000000000000ull)
+#define	XIO_PORT_SHIFT	(60)
+
+#define	XIO_PACKED(x)	(((x)&XIO_PORT_BITS) != 0)
+#define	XIO_ADDR(x)	((x)&XIO_ADDR_BITS)
+#define	XIO_PORT(x)	((xwidgetnum_t)(((x)&XIO_PORT_BITS) >> XIO_PORT_SHIFT))
+#define	XIO_PACK(p,o)	((((uint64_t)(p))<<XIO_PORT_SHIFT) | ((o)&XIO_ADDR_BITS))
+
+#endif /* _LANGUAGE_C */
+
+#endif /* _ASM_XTALK_XTALK_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-mips64/xtalk/xwidget.h linux/include/asm-mips64/xtalk/xwidget.h
--- v2.3.47/linux/include/asm-mips64/xtalk/xwidget.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips64/xtalk/xwidget.h	Thu Feb 24 22:53:35 2000
@@ -0,0 +1,168 @@
+/* $Id: xwidget.h,v 1.1 2000/01/13 00:17:02 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * xwidget.h - generic crosstalk widget header file, derived from IRIX
+ * <sys/xtalk/xtalkwidget.h>, revision 1.32.
+ *
+ * Copyright (C) 1996, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_XTALK_XWIDGET_H
+#define _ASM_XTALK_XWIDGET_H
+
+#include <linux/types.h>
+#include <asm/xtalk/xtalk.h>
+
+#define WIDGET_ID			0x04
+#define WIDGET_STATUS			0x0c
+#define WIDGET_ERR_UPPER_ADDR		0x14
+#define WIDGET_ERR_LOWER_ADDR		0x1c
+#define WIDGET_CONTROL			0x24
+#define WIDGET_REQ_TIMEOUT		0x2c
+#define WIDGET_INTDEST_UPPER_ADDR	0x34
+#define WIDGET_INTDEST_LOWER_ADDR	0x3c
+#define WIDGET_ERR_CMD_WORD		0x44
+#define WIDGET_LLP_CFG			0x4c
+#define WIDGET_TFLUSH			0x54
+
+/* WIDGET_ID */
+#define WIDGET_REV_NUM			0xf0000000
+#define WIDGET_PART_NUM			0x0ffff000
+#define WIDGET_MFG_NUM			0x00000ffe
+#define WIDGET_REV_NUM_SHFT		28
+#define WIDGET_PART_NUM_SHFT		12
+#define WIDGET_MFG_NUM_SHFT		1
+
+#define XWIDGET_PART_NUM(widgetid) (((widgetid) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT)
+#define XWIDGET_REV_NUM(widgetid) (((widgetid) & WIDGET_REV_NUM) >> WIDGET_REV_NUM_SHFT)
+#define XWIDGET_MFG_NUM(widgetid) (((widgetid) & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT)
+
+/* WIDGET_STATUS */
+#define WIDGET_LLP_REC_CNT		0xff000000
+#define WIDGET_LLP_TX_CNT		0x00ff0000
+#define WIDGET_PENDING			0x0000001f
+
+/* WIDGET_ERR_UPPER_ADDR */
+#define	WIDGET_ERR_UPPER_ADDR_ONLY	0x0000ffff
+
+/* WIDGET_CONTROL */
+#define WIDGET_F_BAD_PKT		0x00010000
+#define WIDGET_LLP_XBAR_CRD		0x0000f000
+#define	WIDGET_LLP_XBAR_CRD_SHFT	12
+#define WIDGET_CLR_RLLP_CNT		0x00000800
+#define WIDGET_CLR_TLLP_CNT		0x00000400
+#define WIDGET_SYS_END			0x00000200
+#define WIDGET_MAX_TRANS		0x000001f0
+#define WIDGET_WIDGET_ID		0x0000000f
+
+/* WIDGET_INTDEST_UPPER_ADDR */
+#define WIDGET_INT_VECTOR		0xff000000
+#define WIDGET_INT_VECTOR_SHFT		24
+#define WIDGET_TARGET_ID		0x000f0000
+#define WIDGET_TARGET_ID_SHFT		16
+#define WIDGET_UPP_ADDR			0x0000ffff
+
+/* WIDGET_ERR_CMD_WORD */
+#define WIDGET_DIDN			0xf0000000
+#define WIDGET_SIDN			0x0f000000
+#define WIDGET_PACTYP			0x00f00000
+#define WIDGET_TNUM			0x000f8000
+#define WIDGET_COHERENT			0x00004000
+#define WIDGET_DS			0x00003000
+#define WIDGET_GBR			0x00000800
+#define WIDGET_VBPM			0x00000400
+#define WIDGET_ERROR			0x00000200
+#define WIDGET_BARRIER			0x00000100
+
+/* WIDGET_LLP_CFG */
+#define WIDGET_LLP_MAXRETRY		0x03ff0000
+#define WIDGET_LLP_MAXRETRY_SHFT	16
+#define WIDGET_LLP_NULLTIMEOUT		0x0000fc00
+#define WIDGET_LLP_NULLTIMEOUT_SHFT	10
+#define WIDGET_LLP_MAXBURST		0x000003ff
+#define WIDGET_LLP_MAXBURST_SHFT	0
+
+/*
+ * according to the crosstalk spec, only 32-bits access to the widget
+ * configuration registers is allowed.  some widgets may allow 64-bits
+ * access but software should not depend on it.  registers beyond the
+ * widget target flush register are widget dependent thus will not be
+ * defined here
+ */
+#if _LANGUAGE_C
+typedef u32 widgetreg_t;
+
+/* widget configuration registers */
+typedef volatile struct widget_cfg {
+	widgetreg_t		w_pad_0;		/* 0x00 */
+	widgetreg_t		w_id;			/* 0x04 */
+	widgetreg_t		w_pad_1;		/* 0x08 */
+	widgetreg_t		w_status;		/* 0x0c */
+	widgetreg_t		w_pad_2;		/* 0x10 */
+	widgetreg_t		w_err_upper_addr;	/* 0x14 */
+	widgetreg_t		w_pad_3;		/* 0x18 */
+	widgetreg_t		w_err_lower_addr;	/* 0x1c */
+	widgetreg_t		w_pad_4;		/* 0x20 */
+	widgetreg_t		w_control;		/* 0x24 */
+	widgetreg_t		w_pad_5;		/* 0x28 */
+	widgetreg_t		w_req_timeout;		/* 0x2c */
+	widgetreg_t		w_pad_6;		/* 0x30 */
+	widgetreg_t		w_intdest_upper_addr;	/* 0x34 */
+	widgetreg_t		w_pad_7;		/* 0x38 */
+	widgetreg_t		w_intdest_lower_addr;	/* 0x3c */
+	widgetreg_t		w_pad_8;		/* 0x40 */
+	widgetreg_t		w_err_cmd_word;		/* 0x44 */
+	widgetreg_t		w_pad_9;		/* 0x48 */
+	widgetreg_t		w_llp_cfg;		/* 0x4c */
+	widgetreg_t		w_pad_10;		/* 0x50 */
+	widgetreg_t		w_tflush;		/* 0x54 */
+} widget_cfg_t;
+
+typedef struct {
+	unsigned	didn:4;
+	unsigned	sidn:4;
+	unsigned	pactyp:4;
+	unsigned	tnum:5;
+	unsigned	ct:1;
+	unsigned	ds:2;
+	unsigned	gbr:1;
+	unsigned	vbpm:1;
+	unsigned	error:1;
+	unsigned	bo:1;
+	unsigned	other:8;
+} w_err_cmd_word_f;
+
+typedef union {
+	widgetreg_t		r;
+	w_err_cmd_word_f	f;
+} w_err_cmd_word_u;
+
+typedef struct xwidget_info_s *xwidget_info_t;
+
+/*
+ * Crosstalk Widget Hardware Identification, as defined in the Crosstalk spec.
+ */
+typedef struct xwidget_hwid_s {
+	xwidget_part_num_t	part_num;
+	xwidget_rev_num_t	rev_num;
+	xwidget_mfg_num_t	mfg_num;
+} *xwidget_hwid_t;
+
+
+/*
+ * Returns 1 if a driver that handles devices described by hwid1 is able
+ * to manage a device with hardwareid hwid2.  NOTE: We don't check rev
+ * numbers at all.
+ */
+#define XWIDGET_HARDWARE_ID_MATCH(hwid1, hwid2) \
+	(((hwid1)->part_num == (hwid2)->part_num) && \
+	(((hwid1)->mfg_num == XWIDGET_MFG_NUM_NONE) || \
+	((hwid2)->mfg_num == XWIDGET_MFG_NUM_NONE) || \
+	((hwid1)->mfg_num == (hwid2)->mfg_num)))
+
+#endif				/* _LANGUAGE_C */
+
+#endif /* _ASM_XTALK_XWIDGET_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-ppc/hw_irq.h linux/include/asm-ppc/hw_irq.h
--- v2.3.47/linux/include/asm-ppc/hw_irq.h	Tue Jan 11 22:31:44 2000
+++ linux/include/asm-ppc/hw_irq.h	Tue Feb 22 22:27:42 2000
@@ -6,30 +6,13 @@
 #ifndef _PPC_HW_IRQ_H
 #define _PPC_HW_IRQ_H
 
-#if 0
-/* Structure describing interrupts */
-struct hw_interrupt_type {
-	const char * typename;
-	void (*startup)(unsigned int irq);
-	void (*shutdown)(unsigned int irq);
-	void (*enable)(unsigned int irq);
-	void (*disable)(unsigned int irq);
-	void (*mask_and_ack)(unsigned int irq);
-	int irq_offset;
-};
-
-struct irqdesc {
-	struct irqaction *action;
-	struct hw_interrupt_type *ctl;
-};
-#endif
-
 struct int_control_struct
 {
 	void (*int_cli)(void);
 	void (*int_sti)(void);
 	void (*int_restore_flags)(unsigned long);
 	void (*int_save_flags)(unsigned long *);
+	void (*int_set_lost)(unsigned long);
 };
 extern struct int_control_struct int_control;
 extern unsigned long timer_interrupt_intercept;
@@ -40,12 +23,14 @@
 extern void __no_use_cli(void);
 extern void __no_use_restore_flags(unsigned long);
 extern void __no_use_save_flags(unsigned long *);
+extern void __no_use_set_lost(unsigned long);
 
 #define __cli() int_control.int_cli()
 #define __sti() int_control.int_sti()
 #define __save_flags(flags) int_control.int_save_flags(&flags)
 #define __restore_flags(flags) int_control.int_restore_flags(flags)
 #define __save_and_cli(flags) ({__save_flags(flags);__cli();})
+#define __set_lost(irq) ({ if ((ulong)int_control.int_set_lost) int_control.int_set_lost(irq); })
 
 extern void do_lost_interrupts(unsigned long);
 extern atomic_t ppc_n_lost_interrupts;
diff -u --recursive --new-file v2.3.47/linux/include/asm-ppc/io.h linux/include/asm-ppc/io.h
--- v2.3.47/linux/include/asm-ppc/io.h	Fri Jan 21 18:19:17 2000
+++ linux/include/asm-ppc/io.h	Tue Feb 22 22:27:42 2000
@@ -38,73 +38,73 @@
 #endif /* CONFIG_APUS */
 #endif
 
-#define readb(addr) in_8((volatile unsigned char *)(addr))
-#define writeb(b,addr) out_8((volatile unsigned char *)(addr), (b))
+#define readb(addr) in_8((volatile u8 *)(addr))
+#define writeb(b,addr) out_8((volatile u8 *)(addr), (b))
 #if defined(CONFIG_APUS)
-#define readw(addr) (*(volatile unsigned short *) (addr))
-#define readl(addr) (*(volatile unsigned int *) (addr))
-#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
-#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+#define readw(addr) (*(volatile u16 *) (addr))
+#define readl(addr) (*(volatile u32 *) (addr))
+#define writew(b,addr) ((*(volatile u16 *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile u32 *) (addr)) = (b))
 #else
-#define readw(addr) in_le16((volatile unsigned short *)(addr))
-#define readl(addr) in_le32((volatile unsigned *)(addr))
-#define writew(b,addr) out_le16((volatile unsigned short *)(addr),(b))
-#define writel(b,addr) out_le32((volatile unsigned *)(addr),(b))
+#define readw(addr) in_le16((volatile u16 *)(addr))
+#define readl(addr) in_le32((volatile u32 *)(addr))
+#define writew(b,addr) out_le16((volatile u16 *)(addr),(b))
+#define writel(b,addr) out_le32((volatile u32 *)(addr),(b))
 #endif
 
-#define insb(port, buf, ns)	_insb((unsigned char *)((port)+_IO_BASE), (buf), (ns))
-#define outsb(port, buf, ns)	_outsb((unsigned char *)((port)+_IO_BASE), (buf), (ns))
-#define insw(port, buf, ns)	_insw((unsigned short *)((port)+_IO_BASE), (buf), (ns))
-#define outsw(port, buf, ns)	_outsw((unsigned short *)((port)+_IO_BASE), (buf), (ns))
-#define insl(port, buf, nl)	_insl((unsigned long *)((port)+_IO_BASE), (buf), (nl))
-#define outsl(port, buf, nl)	_outsl((unsigned long *)((port)+_IO_BASE), (buf), (nl))
+#define insb(port, buf, ns)	_insb((u8 *)((port)+_IO_BASE), (buf), (ns))
+#define outsb(port, buf, ns)	_outsb((u8 *)((port)+_IO_BASE), (buf), (ns))
+#define insw(port, buf, ns)	_insw((u16 *)((port)+_IO_BASE), (buf), (ns))
+#define outsw(port, buf, ns)	_outsw((u16 *)((port)+_IO_BASE), (buf), (ns))
+#define insl(port, buf, nl)	_insl((u32 *)((port)+_IO_BASE), (buf), (nl))
+#define outsl(port, buf, nl)	_outsl((u32 *)((port)+_IO_BASE), (buf), (nl))
 
-#define inb(port)		in_8((unsigned char *)((port)+_IO_BASE))
-#define outb(val, port)		out_8((unsigned char *)((port)+_IO_BASE), (val))
+#define inb(port)		in_8((u8 *)((port)+_IO_BASE))
+#define outb(val, port)		out_8((u8 *)((port)+_IO_BASE), (val))
 #if defined(CONFIG_APUS)
-#define inw(port)		in_be16((unsigned short *)((port)+_IO_BASE))
-#define outw(val, port)		out_be16((unsigned short *)((port)+_IO_BASE), (val))
-#define inl(port)		in_be32((unsigned *)((port)+_IO_BASE))
-#define outl(val, port)		out_be32((unsigned *)((port)+_IO_BASE), (val))
+#define inw(port)		in_be16((u16 *)((port)+_IO_BASE))
+#define outw(val, port)		out_be16((u16 *)((port)+_IO_BASE), (val))
+#define inl(port)		in_be32((u32 *)((port)+_IO_BASE))
+#define outl(val, port)		out_be32((u32 *)((port)+_IO_BASE), (val))
 #else
-#define inw(port)		in_le16((unsigned short *)((port)+_IO_BASE))
-#define outw(val, port)		out_le16((unsigned short *)((port)+_IO_BASE), (val))
-#define inl(port)		in_le32((unsigned *)((port)+_IO_BASE))
-#define outl(val, port)		out_le32((unsigned *)((port)+_IO_BASE), (val))
+#define inw(port)		in_le16((u16 *)((port)+_IO_BASE))
+#define outw(val, port)		out_le16((u16 *)((port)+_IO_BASE), (val))
+#define inl(port)		in_le32((u32 *)((port)+_IO_BASE))
+#define outl(val, port)		out_le32((u32 *)((port)+_IO_BASE), (val))
 #endif
 
-#define inb_p(port)		in_8((unsigned char *)((port)+_IO_BASE))
-#define outb_p(val, port)	out_8((unsigned char *)((port)+_IO_BASE), (val))
-#define inw_p(port)		in_le16((unsigned short *)((port)+_IO_BASE))
-#define outw_p(val, port)	out_le16((unsigned short *)((port)+_IO_BASE), (val))
-#define inl_p(port)		in_le32((unsigned *)((port)+_IO_BASE))
-#define outl_p(val, port)	out_le32((unsigned *)((port)+_IO_BASE), (val))
-
-extern void _insb(volatile unsigned char *port, void *buf, int ns);
-extern void _outsb(volatile unsigned char *port, const void *buf, int ns);
-extern void _insw(volatile unsigned short *port, void *buf, int ns);
-extern void _outsw(volatile unsigned short *port, const void *buf, int ns);
-extern void _insl(volatile unsigned long *port, void *buf, int nl);
-extern void _outsl(volatile unsigned long *port, const void *buf, int nl);
+#define inb_p(port)		in_8((u8 *)((port)+_IO_BASE))
+#define outb_p(val, port)	out_8((u8 *)((port)+_IO_BASE), (val))
+#define inw_p(port)		in_le16((u16 *)((port)+_IO_BASE))
+#define outw_p(val, port)	out_le16((u16 *)((port)+_IO_BASE), (val))
+#define inl_p(port)		in_le32((u32 *)((port)+_IO_BASE))
+#define outl_p(val, port)	out_le32((u32 *)((port)+_IO_BASE), (val))
+
+extern void _insb(volatile u8 *port, void *buf, int ns);
+extern void _outsb(volatile u8 *port, const void *buf, int ns);
+extern void _insw(volatile u16 *port, void *buf, int ns);
+extern void _outsw(volatile u16 *port, const void *buf, int ns);
+extern void _insl(volatile u32 *port, void *buf, int nl);
+extern void _outsl(volatile u32 *port, const void *buf, int nl);
 
 /*
  * The *_ns versions below don't do byte-swapping.
  */
-#define insw_ns(port, buf, ns)	_insw_ns((unsigned short *)((port)+_IO_BASE), (buf), (ns))
-#define outsw_ns(port, buf, ns)	_outsw_ns((unsigned short *)((port)+_IO_BASE), (buf), (ns))
-#define insl_ns(port, buf, nl)	_insl_ns((unsigned long *)((port)+_IO_BASE), (buf), (nl))
-#define outsl_ns(port, buf, nl)	_outsl_ns((unsigned long *)((port)+_IO_BASE), (buf), (nl))
-
-extern void _insw_ns(volatile unsigned short *port, void *buf, int ns);
-extern void _outsw_ns(volatile unsigned short *port, const void *buf, int ns);
-extern void _insl_ns(volatile unsigned long *port, void *buf, int nl);
-extern void _outsl_ns(volatile unsigned long *port, const void *buf, int nl);
+#define insw_ns(port, buf, ns)	_insw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
+#define outsw_ns(port, buf, ns)	_outsw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
+#define insl_ns(port, buf, nl)	_insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
+#define outsl_ns(port, buf, nl)	_outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
+
+extern void _insw_ns(volatile u16 *port, void *buf, int ns);
+extern void _outsw_ns(volatile u16 *port, const void *buf, int ns);
+extern void _insl_ns(volatile u32 *port, void *buf, int nl);
+extern void _outsl_ns(volatile u32 *port, const void *buf, int nl);
 
 #define IO_SPACE_LIMIT ~0
 
-#define memset_io(a,b,c)	memset((a),(b),(c))
-#define memcpy_fromio(a,b,c)	memcpy((a),(b),(c))
-#define memcpy_toio(a,b,c)	memcpy((a),(b),(c))
+#define memset_io(a,b,c)       memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)   memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
 
 #ifdef __KERNEL__
 /*
diff -u --recursive --new-file v2.3.47/linux/include/asm-ppc/irq.h linux/include/asm-ppc/irq.h
--- v2.3.47/linux/include/asm-ppc/irq.h	Thu Feb 10 17:11:20 2000
+++ linux/include/asm-ppc/irq.h	Tue Feb 22 22:27:43 2000
@@ -117,15 +117,48 @@
 	return irq;
 }
 
-#else
+#else /* CONFIG_4xx + CONFIG_8xx */
 
-#ifdef CONFIG_APUS
-#define enable_irq m68k_enable_irq
-#define disable_irq m68k_disable_irq
-#include <asm-m68k/irq.h>
-#undef enable_irq
-#undef disable_irq
-#else /* CONFIG_APUS */
+#if defined(CONFIG_APUS)
+/*
+ * This structure is used to chain together the ISRs for a particular
+ * interrupt source (if it supports chaining).
+ */
+typedef struct irq_node {
+	void		(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+	struct irq_node *next;
+} irq_node_t;
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+typedef struct irq_handler {
+	void		(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+} irq_handler_t;
+
+/* count of spurious interrupts */
+extern volatile unsigned int num_spurious;
+
+extern int sys_request_irq(unsigned int, 
+	void (*)(int, void *, struct pt_regs *), 
+	unsigned long, const char *, void *);
+extern void sys_free_irq(unsigned int, void *);
+
+/*
+ * This function returns a new irq_node_t
+ */
+extern irq_node_t *new_irq_node(void);
+
+/* Number of m68k interrupts */
+#define SYS_IRQS 8
+
+#endif /* CONFIG_APUS */
 
 /*
  * this is the # irq's for all ppc arch's (pmac/chrp/prep)
@@ -133,14 +166,11 @@
  */
 #define NR_IRQS			256
 
-#endif /* CONFIG_APUS */
-
 #define NUM_8259_INTERRUPTS	16
 #define IRQ_8259_CASCADE	16
 #define openpic_to_irq(n)	((n)+NUM_8259_INTERRUPTS)
 #define irq_to_openpic(n)	((n)-NUM_8259_INTERRUPTS)
 
-#ifndef CONFIG_APUS
 /*
  * This gets called from serial.c, which is now used on
  * powermacs as well as prep/chrp boxes.
@@ -157,8 +187,10 @@
 		return irq;
 	}
 }
-#endif /* !CONFIG_APUS */
 
 #endif
+
+#define NR_MASK_WORDS	((NR_IRQS + 31) / 32)
+extern unsigned int ppc_lost_interrupts[NR_MASK_WORDS];
 
 #endif /* _ASM_IRQ_H */
diff -u --recursive --new-file v2.3.47/linux/include/asm-ppc/pci.h linux/include/asm-ppc/pci.h
--- v2.3.47/linux/include/asm-ppc/pci.h	Sun Feb 20 21:12:39 2000
+++ linux/include/asm-ppc/pci.h	Thu Feb 24 22:43:13 2000
@@ -62,7 +62,8 @@
 		BUG();
 	/* nothing to do */
 }
-extern inline void pci_dma_syng_sg(struct pci_dev *hwdev,
+
+extern inline void pci_dma_sync_sg(struct pci_dev *hwdev,
 				   struct scatterlist *sg,
 				   int nelems, int direction)
 {
diff -u --recursive --new-file v2.3.47/linux/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h
--- v2.3.47/linux/include/asm-ppc/processor.h	Sun Feb 13 19:29:04 2000
+++ linux/include/asm-ppc/processor.h	Tue Feb 22 22:27:43 2000
@@ -692,16 +692,7 @@
 #endif /* ndef ASSEMBLY*/
 
 #ifdef CONFIG_MACH_SPECIFIC
-#if defined(CONFIG_PREP)
-#define _machine _MACH_prep
-#define have_of 0
-#elif defined(CONFIG_CHRP)
-#define _machine _MACH_chrp
-#define have_of 1
-#elif defined(CONFIG_PMAC)
-#define _machine _MACH_Pmac
-#define have_of 1
-#elif defined(CONFIG_8xx)
+#if defined(CONFIG_8xx)
 #define _machine _MACH_8xx
 #define have_of 0
 #elif defined(CONFIG_OAK)
diff -u --recursive --new-file v2.3.47/linux/include/asm-ppc/system.h linux/include/asm-ppc/system.h
--- v2.3.47/linux/include/asm-ppc/system.h	Wed Dec 29 13:13:21 1999
+++ linux/include/asm-ppc/system.h	Tue Feb 22 22:27:43 2000
@@ -66,6 +66,7 @@
 extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
 extern void cvt_df(double *from, float *to, unsigned long *fpscr);
 extern int call_rtas(const char *, int, int, unsigned long *, ...);
+extern int abs(int);
 
 struct device_node;
 extern void note_scsi_host(struct device_node *, void *);
diff -u --recursive --new-file v2.3.47/linux/include/asm-ppc/types.h linux/include/asm-ppc/types.h
--- v2.3.47/linux/include/asm-ppc/types.h	Sun Feb 13 19:29:04 2000
+++ linux/include/asm-ppc/types.h	Tue Feb 22 22:27:43 2000
@@ -26,8 +26,6 @@
 /*
  * These aren't exported outside the kernel to avoid name space clashes
  */
-#ifdef __KERNEL__
-
 typedef signed char s8;
 typedef unsigned char u8;
 
@@ -40,14 +38,15 @@
 typedef signed long long s64;
 typedef unsigned long long u64;
 
-#define BITS_PER_LONG 32
-
 typedef struct {
 	u32 u[4];
 } __attribute((aligned(16))) vector128;
 
-/* DMA addresses are 32-bits wide */
+#ifdef __KERNEL__
+
+#define BITS_PER_LONG 32
 
+/* DMA addresses are 32-bits wide */
 typedef u32 dma_addr_t;
 
 #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.3.47/linux/include/asm-ppc/vga.h linux/include/asm-ppc/vga.h
--- v2.3.47/linux/include/asm-ppc/vga.h	Thu Feb 10 17:11:21 2000
+++ linux/include/asm-ppc/vga.h	Tue Feb 22 22:27:42 2000
@@ -23,12 +23,12 @@
 
 extern inline void scr_writew(u16 val, u16 *addr)
 {
-    writew(val, (unsigned long)addr);
+    st_le16(addr, val);
 }
 
 extern inline u16 scr_readw(const u16 *addr)
 {
-    return readw((unsigned long)addr);
+    return ld_le16(addr);
 }
 
 #define VT_BUF_HAVE_MEMCPYW
diff -u --recursive --new-file v2.3.47/linux/include/asm-sparc/termbits.h linux/include/asm-sparc/termbits.h
--- v2.3.47/linux/include/asm-sparc/termbits.h	Fri Jan 28 15:09:09 2000
+++ linux/include/asm-sparc/termbits.h	Mon Feb 21 16:32:27 2000
@@ -165,10 +165,13 @@
 #define B1152000  0x0000100d
 #define B1500000  0x0000100e
 #define B2000000  0x0000100f
+/* These have totally bogus values and nobody uses them
+   so far. Later on we'd have to use say 0x10000x and
+   adjust CBAUD constant and drivers accordingly.
 #define B2500000  0x00001010
 #define B3000000  0x00001011
 #define B3500000  0x00001012
-#define B4000000  0x00001013
+#define B4000000  0x00001013  */
 #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
 #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
 #define CRTSCTS	  0x80000000  /* flow control */
diff -u --recursive --new-file v2.3.47/linux/include/asm-sparc64/io.h linux/include/asm-sparc64/io.h
--- v2.3.47/linux/include/asm-sparc64/io.h	Sun Feb 20 21:12:39 2000
+++ linux/include/asm-sparc64/io.h	Sat Feb 26 20:46:44 2000
@@ -1,4 +1,4 @@
-/* $Id: io.h,v 1.32 2000/02/15 10:04:54 jj Exp $ */
+/* $Id: io.h,v 1.33 2000/02/25 05:47:38 davem Exp $ */
 #ifndef __SPARC64_IO_H
 #define __SPARC64_IO_H
 
@@ -225,10 +225,8 @@
 #define sbus_writew(__w, __addr)	(_sbus_writew((__w), (unsigned long)(__addr)))
 #define sbus_writel(__l, __addr)	(_sbus_writel((__l), (unsigned long)(__addr)))
 
-static inline void *sbus_memset_io(void *__dst, int c, __kernel_size_t n)
+static inline void *_sbus_memset_io(unsigned long dst, int c, __kernel_size_t n)
 {
-	unsigned long dst = (unsigned long)__dst;
-
 	while(n--) {
 		sbus_writeb(c, dst);
 		dst++;
@@ -236,8 +234,11 @@
 	return (void *) dst;
 }
 
+#define sbus_memset_io(d,c,sz)	\
+	_sbus_memset_io((unsigned long)d,(int)c,(__kernel_size_t)sz)
+
 static inline void *
-memset_io(void *dst, int c, __kernel_size_t n)
+_memset_io(void *dst, int c, __kernel_size_t n)
 {
 	char *d = dst;
 
@@ -249,8 +250,11 @@
 	return dst;
 }
 
+#define memset_io(d,c,sz)	\
+	_memset_io((void *)d,(int)c,(__kernel_size_t)sz)
+
 static inline void *
-memcpy_fromio(void *dst, unsigned long src, __kernel_size_t n)
+_memcpy_fromio(void *dst, unsigned long src, __kernel_size_t n)
 {
 	char *d = dst;
 
@@ -263,8 +267,11 @@
 	return dst;
 }
 
+#define memcpy_fromio(d,s,sz)	\
+	_memcpy_fromio((void *)d,(unsigned long)s,(__kernel_size_t)sz)
+
 static inline void *
-memcpy_toio(unsigned long dst, const void *src, __kernel_size_t n)
+_memcpy_toio(unsigned long dst, const void *src, __kernel_size_t n)
 {
 	const char *s = src;
 	unsigned long d = dst;
@@ -276,6 +283,9 @@
 	}
 	return (void *)dst;
 }
+
+#define memcpy_toio(d,s,sz)	\
+	_memcpy_toio((unsigned long)d,(const void *)s,(__kernel_size_t)sz)
 
 static inline int check_signature(unsigned long io_addr,
 				  const unsigned char *signature,
diff -u --recursive --new-file v2.3.47/linux/include/asm-sparc64/siginfo.h linux/include/asm-sparc64/siginfo.h
--- v2.3.47/linux/include/asm-sparc64/siginfo.h	Fri Jan 28 15:09:09 2000
+++ linux/include/asm-sparc64/siginfo.h	Sat Feb 26 20:46:44 2000
@@ -65,7 +65,7 @@
 
 		/* SIGPOLL */
 		struct {
-			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			long _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
 	} _sifields;
diff -u --recursive --new-file v2.3.47/linux/include/asm-sparc64/termbits.h linux/include/asm-sparc64/termbits.h
--- v2.3.47/linux/include/asm-sparc64/termbits.h	Fri Jan 28 15:09:09 2000
+++ linux/include/asm-sparc64/termbits.h	Mon Feb 21 16:32:27 2000
@@ -166,10 +166,13 @@
 #define B1152000  0x0000100d
 #define B1500000  0x0000100e
 #define B2000000  0x0000100f
+/* These have totally bogus values and nobody uses them
+   so far. Later on we'd have to use say 0x10000x and
+   adjust CBAUD constant and drivers accordingly.
 #define B2500000  0x00001010
 #define B3000000  0x00001011
 #define B3500000  0x00001012
-#define B4000000  0x00001013
+#define B4000000  0x00001013  */
 #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
 #define CMSPAR    0x40000000  /* mark or space (stick) parity */
 #define CRTSCTS	  0x80000000  /* flow control */
diff -u --recursive --new-file v2.3.47/linux/include/linux/ac97_codec.h linux/include/linux/ac97_codec.h
--- v2.3.47/linux/include/linux/ac97_codec.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/ac97_codec.h	Sat Feb 26 20:22:08 2000
@@ -0,0 +1,159 @@
+#ifndef _AC97_CODEC_H_
+#define _AC97_CODEC_H_
+
+
+/* AC97 1.0 */
+#define  AC97_RESET               0x0000      //
+#define  AC97_MASTER_VOL_STEREO   0x0002      // Line Out
+#define  AC97_HEADPHONE_VOL       0x0004      // 
+#define  AC97_MASTER_VOL_MONO     0x0006      // TAD Output
+#define  AC97_MASTER_TONE         0x0008      //
+#define  AC97_PCBEEP_VOL          0x000a      // none
+#define  AC97_PHONE_VOL           0x000c      // TAD Input (mono)
+#define  AC97_MIC_VOL             0x000e      // MIC Input (mono)
+#define  AC97_LINEIN_VOL          0x0010      // Line Input (stereo)
+#define  AC97_CD_VOL              0x0012      // CD Input (stereo)
+#define  AC97_VIDEO_VOL           0x0014      // none
+#define  AC97_AUX_VOL             0x0016      // Aux Input (stereo)
+#define  AC97_PCMOUT_VOL          0x0018      // Wave Output (stereo)
+#define  AC97_RECORD_SELECT       0x001a      //
+#define  AC97_RECORD_GAIN         0x001c
+#define  AC97_RECORD_GAIN_MIC     0x001e
+#define  AC97_GENERAL_PURPOSE     0x0020
+#define  AC97_3D_CONTROL          0x0022
+#define  AC97_MODEM_RATE          0x0024
+#define  AC97_POWER_CONTROL       0x0026
+
+/* AC'97 2.0 */
+#define AC97_EXTENDED_ID          0x0028       /* Extended Audio ID */
+#define AC97_EXTENDED_STATUS      0x002A       /* Extended Audio Status */
+#define AC97_PCM_FRONT_DAC_RATE   0x002C       /* PCM Front DAC Rate */
+#define AC97_PCM_SURR_DAC_RATE    0x002E       /* PCM Surround DAC Rate */
+#define AC97_PCM_LFE_DAC_RATE     0x0030       /* PCM LFE DAC Rate */
+#define AC97_PCM_LR_DAC_RATE      0x0032       /* PCM LR DAC Rate */
+#define AC97_PCM_MIC_ADC_RATE     0x0034       /* PCM MIC ADC Rate */
+#define AC97_CENTER_LFE_MASTER    0x0036       /* Center + LFE Master Volume */
+#define AC97_SURROUND_MASTER      0x0038       /* Surround (Rear) Master Volume */
+#define AC97_RESERVED_3A          0x003A       /* Reserved */
+
+/* range 0x3c-0x58 - MODEM */
+
+/* registers 0x005a - 0x007a are vendor reserved */
+
+#define AC97_VENDOR_ID1           0x007c
+#define AC97_VENDOR_ID2           0x007e
+
+/* volume control bit defines */
+#define AC97_MUTE                 0x8000
+#define AC97_MICBOOST             0x0040
+#define AC97_LEFTVOL              0x3f00
+#define AC97_RIGHTVOL             0x003f
+
+/* record mux defines */
+#define AC97_RECMUX_MIC           0x0000
+#define AC97_RECMUX_CD            0x0101
+#define AC97_RECMUX_VIDEO         0x0202       /* not used */
+#define AC97_RECMUX_AUX           0x0303      
+#define AC97_RECMUX_LINE          0x0404      
+#define AC97_RECMUX_STEREO_MIX    0x0505
+#define AC97_RECMUX_MONO_MIX      0x0606
+#define AC97_RECMUX_PHONE         0x0707
+
+
+/* general purpose register bit defines */
+#define AC97_GP_LPBK              0x0080       /* Loopback mode */
+#define AC97_GP_MS                0x0100       /* Mic Select 0=Mic1, 1=Mic2 */
+#define AC97_GP_MIX               0x0200       /* Mono output select 0=Mix, 1=Mic */
+#define AC97_GP_RLBK              0x0400       /* Remote Loopback - Modem line codec */
+#define AC97_GP_LLBK              0x0800       /* Local Loopback - Modem Line codec */
+#define AC97_GP_LD                0x1000       /* Loudness 1=on */
+#define AC97_GP_3D                0x2000       /* 3D Enhancement 1=on */
+#define AC97_GP_ST                0x4000       /* Stereo Enhancement 1=on */
+#define AC97_GP_POP               0x8000       /* Pcm Out Path, 0=pre 3D, 1=post 3D */
+
+
+/* powerdown control and status bit defines */
+
+/* status */
+#define AC97_PWR_MDM              0x0010       /* Modem section ready */
+#define AC97_PWR_REF              0x0008       /* Vref nominal */
+#define AC97_PWR_ANL              0x0004       /* Analog section ready */
+#define AC97_PWR_DAC              0x0002       /* DAC section ready */
+#define AC97_PWR_ADC              0x0001       /* ADC section ready */
+
+/* control */
+#define AC97_PWR_PR0              0x0100       /* ADC and Mux powerdown */
+#define AC97_PWR_PR1              0x0200       /* DAC powerdown */
+#define AC97_PWR_PR2              0x0400       /* Output mixer powerdown (Vref on) */
+#define AC97_PWR_PR3              0x0800       /* Output mixer powerdown (Vref off) */
+#define AC97_PWR_PR4              0x1000       /* AC-link powerdown */
+#define AC97_PWR_PR5              0x2000       /* Internal Clk disable */
+#define AC97_PWR_PR6              0x4000       /* HP amp powerdown */
+#define AC97_PWR_PR7              0x8000       /* Modem off - if supported */
+
+/* useful power states */
+#define AC97_PWR_D0               0x0000      /* everything on */
+#define AC97_PWR_D1              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4
+#define AC97_PWR_D2              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4
+#define AC97_PWR_D3              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4
+#define AC97_PWR_ANLOFF          AC97_PWR_PR2|AC97_PWR_PR3  /* analog section off */
+
+/* Total number of defined registers.  */
+#define AC97_REG_CNT 64
+
+
+/* OSS interface to the ac97s.. */
+#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|SOUND_MASK_PCM|\
+	SOUND_MASK_LINE|SOUND_MASK_CD|\
+	SOUND_MASK_ALTPCM|SOUND_MASK_IGAIN|\
+	SOUND_MASK_LINE1|SOUND_MASK_VIDEO)
+
+#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \
+	SOUND_MASK_BASS|SOUND_MASK_TREBLE|\
+	SOUND_MASK_SPEAKER|SOUND_MASK_MIC|\
+	SOUND_MASK_PHONEIN|SOUND_MASK_PHONEOUT)
+
+#define AC97_RECORD_MASK (SOUND_MASK_MIC|\
+	SOUND_MASK_CD|SOUND_MASK_VIDEO|\
+	SOUND_MASK_LINE1| SOUND_MASK_LINE|\
+	SOUND_MASK_PHONEIN)
+
+#define supported_mixer(CODEC,FOO) ( CODEC->supported_mixers & (1<<FOO) )
+
+struct ac97_codec {
+	/* AC97 controller connected with */
+	void *private_data;
+
+	char *name;
+	int id;
+	int dev_mixer; 
+
+	/* codec specific init/reset routines, used mainly for 4 or 6 channel support */
+	int  (*codec_init)  (struct ac97_codec *codec);
+
+	/* controller specific lower leverl ac97 accessing routines */
+	u16  (*codec_read)  (struct ac97_codec *codec, u8 reg);
+	void (*codec_write) (struct ac97_codec *codec, u8 reg, u16 val);
+
+	/* OSS mixer masks */
+	int modcnt;
+	int supported_mixers;
+	int stereo_mixers;
+	int record_sources;
+	
+	/* OSS mixer interface */
+	int  (*read_mixer) (struct ac97_codec *codec, int oss_channel);
+	void (*write_mixer)(struct ac97_codec *codec, int oss_channel,
+			    unsigned int left, unsigned int right);
+	int  (*recmask_io) (struct ac97_codec *codec, int rw, int mask);
+	int  (*mixer_ioctl)(struct ac97_codec *codec, unsigned int cmd, unsigned long arg);
+
+	/* saved OSS mixer states */
+	unsigned int mixer_state[SOUND_MIXER_NRDEVICES];
+};
+
+extern int ac97_read_proc (char *page_out, char **start, off_t off,
+			   int count, int *eof, void *data);
+extern int ac97_probe_codec(struct ac97_codec *);
+
+#endif /* _AC97_CODEC_H_ */
diff -u --recursive --new-file v2.3.47/linux/include/linux/affs_fs.h linux/include/linux/affs_fs.h
--- v2.3.47/linux/include/linux/affs_fs.h	Thu Feb 10 17:11:21 2000
+++ linux/include/linux/affs_fs.h	Sat Feb 26 20:48:30 2000
@@ -103,8 +103,10 @@
 /* jump tables */
 
 extern struct inode_operations	 affs_file_inode_operations;
-extern struct inode_operations	 affs_file_inode_operations_ofs;
 extern struct inode_operations	 affs_dir_inode_operations;
+extern struct file_operations	 affs_file_operations;
+extern struct file_operations	 affs_file_operations_ofs;
+extern struct file_operations	 affs_dir_operations;
 extern struct address_space_operations	 affs_symlink_aops;
 extern struct address_space_operations	 affs_aops;
 
diff -u --recursive --new-file v2.3.47/linux/include/linux/bfs_fs.h linux/include/linux/bfs_fs.h
--- v2.3.47/linux/include/linux/bfs_fs.h	Thu Feb 10 17:11:21 2000
+++ linux/include/linux/bfs_fs.h	Sat Feb 26 20:33:09 2000
@@ -83,10 +83,12 @@
 
 /* file.c */
 extern struct inode_operations bfs_file_inops;
+extern struct file_operations bfs_file_operations;
 extern struct address_space_operations bfs_aops;
 
 /* dir.c */
 extern struct inode_operations bfs_dir_inops;
+extern struct file_operations bfs_dir_operations;
 
 #endif /* __KERNEL__ */
 #endif	/* _LINUX_BFS_FS_H */
diff -u --recursive --new-file v2.3.47/linux/include/linux/blkdev.h linux/include/linux/blkdev.h
--- v2.3.47/linux/include/linux/blkdev.h	Sun Feb 20 21:12:39 2000
+++ linux/include/linux/blkdev.h	Sat Feb 26 20:46:35 2000
@@ -53,7 +53,7 @@
 				 int);
 typedef void (request_fn_proc) (request_queue_t *q);
 typedef request_queue_t * (queue_proc) (kdev_t dev);
-typedef void (make_request_fn) (int rw, struct buffer_head *bh);
+typedef int (make_request_fn) (request_queue_t *q, int rw, struct buffer_head *bh);
 typedef void (plug_device_fn) (request_queue_t *q, kdev_t device);
 typedef void (unplug_device_fn) (void *q);
 
@@ -129,7 +129,8 @@
 extern void grok_partitions(struct gendisk *dev, int drive, unsigned minors, long size);
 extern void register_disk(struct gendisk *dev, kdev_t first, unsigned minors, struct block_device_operations *ops, long size);
 extern void generic_unplug_device(void * data);
-extern void generic_make_request(int rw, struct buffer_head * bh);
+extern int generic_make_request(request_queue_t *q, int rw,
+						struct buffer_head * bh);
 extern request_queue_t * blk_get_queue(kdev_t dev);
 
 /*
diff -u --recursive --new-file v2.3.47/linux/include/linux/coda_linux.h linux/include/linux/coda_linux.h
--- v2.3.47/linux/include/linux/coda_linux.h	Thu Feb 10 17:11:21 2000
+++ linux/include/linux/coda_linux.h	Sat Feb 26 20:33:43 2000
@@ -39,6 +39,7 @@
 int coda_release(struct inode *i, struct file *f);
 int coda_permission(struct inode *inode, int mask);
 int coda_revalidate_inode(struct dentry *);
+int coda_notify_change(struct dentry *, struct iattr *);
 
 /* global variables */
 extern int coda_debug;
diff -u --recursive --new-file v2.3.47/linux/include/linux/dlists.h linux/include/linux/dlists.h
--- v2.3.47/linux/include/linux/dlists.h	Mon Jun 16 16:36:00 1997
+++ linux/include/linux/dlists.h	Wed Dec 31 16:00:00 1969
@@ -1,108 +0,0 @@
-#ifndef DLISTS_H
-#define DLISTS_H
-/*
- * include/linux/dlists.h - macros for double linked lists
- *
- * Copyright (C) 1997, Thomas Schoebel-Theuer,
- * <schoebel@informatik.uni-stuttgart.de>.
- */
-
-/* dlists are cyclic ringlists, so the last element cannot be tested
- * for NULL. Use the following construct for traversing cyclic lists:
- * ptr = anchor;
- * if(ptr) do {
- *      ...
- *      ptr = ptr->{something}_{next,prev};
- * } while(ptr != anchor);
- * The effort here is paid off with much simpler inserts/removes.
- * Examples for usage of these macros can be found in fs/ninode.c.
- * To access the last element in constant time, simply use
- * anchor->{something}_prev.
- */
-
-#define DEF_GENERIC_INSERT(CHANGE,PREFIX,NAME,TYPE,NEXT,PREV) \
-static inline void PREFIX##NAME(TYPE ** anchor, TYPE * elem)\
-{\
-	TYPE * oldfirst = *anchor;\
-	if(!oldfirst) {\
-		elem->NEXT = elem->PREV = *anchor = elem;\
-	} else {\
-		elem->PREV = oldfirst->PREV;\
-		elem->NEXT = oldfirst;\
-		oldfirst->PREV->NEXT = elem;\
-		oldfirst->PREV = elem;\
-		if(CHANGE)\
-			*anchor = elem;\
-	}\
-}
-
-/* insert_* is always at the first position */
-#define DEF_INSERT(NAME,TYPE,NEXT,PREV) \
-                   DEF_GENERIC_INSERT(1,insert_,NAME,TYPE,NEXT,PREV)
-
-/* append_* is always at the tail  */
-#define DEF_APPEND(NAME,TYPE,NEXT,PREV) \
-                   DEF_GENERIC_INSERT(0,append_,NAME,TYPE,NEXT,PREV)
-
-/* use this to insert _before_ oldelem somewhere in the middle of the list.
- * the list must not be empty, and oldelem must be already a member.*/
-#define DEF_INSERT_MIDDLE(NAME,TYPE) \
-static inline void insert_middle_##NAME(TYPE ** anchor, TYPE * oldelem, TYPE * elem)\
-{\
-	int status = (oldelem == *anchor);\
-	insert_##NAME(&oldelem, elem);\
-	if(status)\
-		*anchor = oldelem;\
-}
-
-/* remove can be done with any element in the list */
-#define DEF_REMOVE(NAME,TYPE,NEXT,PREV) \
-static inline void remove_##NAME(TYPE ** anchor, TYPE * elem)\
-{\
-	TYPE * next = elem->NEXT;\
-	if(next == elem) {\
-		*anchor = NULL;\
-	} else {\
-		TYPE * prev = elem->PREV;\
-		prev->NEXT = next;\
-		next->PREV = prev;\
-		elem->NEXT = elem->PREV = NULL;/*leave this during debugging*/\
-		if(*anchor == elem)\
-			*anchor = next;\
-	}\
-}
-
-
-/* According to ideas from David S. Miller, here is a slightly
- * more efficient plug-in compatible version using non-cyclic lists,
- * but allowing neither backward traversals nor constant time access
- * to the last element.
- * Note that although the interface is the same, the PPREV pointer must be
- * declared doubly indirect and the test for end-of-list is different. */
-
-/* as above, this inserts always at the head */
-#define DEF_LIN_INSERT(NAME,TYPE,NEXT,PPREV) \
-static inline void insert_##NAME(TYPE ** anchor, TYPE * elem)\
-{\
-	TYPE * first;\
-	if((elem->NEXT = first = *anchor))\
-		first->PPREV = &elem->NEXT;\
-	*anchor = elem;\
-	elem->PPREV = anchor;\
-}
-
-/* as above, this works with any list element */
-#define DEF_LIN_REMOVE(NAME,TYPE,NEXT,PPREV) \
-static inline void remove_##NAME(TYPE ** anchor, TYPE * elem)\
-{\
-	TYPE * pprev;\
-	if((pprev = elem->PPREV)) {\
-		TYPE * next;\
-		if((next = elem->NEXT))\
-			next->PPREV = pprev;\
-		*pprev = next;\
-		elem->PPREV = elem->NEXT = NULL; /*leave this for debugging*/\
-	}\
-}
-
-#endif
diff -u --recursive --new-file v2.3.47/linux/include/linux/efs_fs.h linux/include/linux/efs_fs.h
--- v2.3.47/linux/include/linux/efs_fs.h	Thu Feb 10 17:11:21 2000
+++ linux/include/linux/efs_fs.h	Sat Feb 26 20:48:30 2000
@@ -46,7 +46,7 @@
 #endif
 
 extern struct inode_operations efs_dir_inode_operations;
-extern struct inode_operations efs_file_inode_operations;
+extern struct file_operations efs_dir_operations;
 extern struct address_space_operations efs_symlink_aops;
 
 extern int init_module(void);
diff -u --recursive --new-file v2.3.47/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h
--- v2.3.47/linux/include/linux/ext2_fs.h	Thu Feb 10 17:11:21 2000
+++ linux/include/linux/ext2_fs.h	Sat Feb 26 20:45:58 2000
@@ -576,17 +576,7 @@
 		       unsigned long);
 
 /* namei.c */
-extern void ext2_release (struct inode *, struct file *);
-extern struct dentry *ext2_lookup (struct inode *, struct dentry *);
-extern int ext2_create (struct inode *,struct dentry *,int);
-extern int ext2_mkdir (struct inode *,struct dentry *,int);
-extern int ext2_rmdir (struct inode *,struct dentry *);
-extern int ext2_unlink (struct inode *,struct dentry *);
-extern int ext2_symlink (struct inode *,struct dentry *,const char *);
-extern int ext2_link (struct dentry *, struct inode *, struct dentry *);
-extern int ext2_mknod (struct inode *, struct dentry *, int, int);
-extern int ext2_rename (struct inode *, struct dentry *,
-			struct inode *, struct dentry *);
+extern struct inode_operations ext2_dir_inode_operations;
 
 /* super.c */
 extern void ext2_error (struct super_block *, const char *, const char *, ...)
@@ -610,10 +600,11 @@
  */
 
 /* dir.c */
-extern struct inode_operations ext2_dir_inode_operations;
+extern struct file_operations ext2_dir_operations;
 
 /* file.c */
 extern struct inode_operations ext2_file_inode_operations;
+extern struct file_operations ext2_file_operations;
 
 /* symlink.c */
 extern struct inode_operations ext2_fast_symlink_inode_operations;
diff -u --recursive --new-file v2.3.47/linux/include/linux/fb.h linux/include/linux/fb.h
--- v2.3.47/linux/include/linux/fb.h	Wed Feb 16 17:03:52 2000
+++ linux/include/linux/fb.h	Mon Feb 21 11:08:22 2000
@@ -24,6 +24,7 @@
 #define FBIOGET_CON2FBMAP	0x460F
 #define FBIOPUT_CON2FBMAP	0x4610
 #define FBIOBLANK		0x4611		/* arg: 0 or vesa level + 1 */
+#define FBIOGET_VBLANK		_IOR('F', 0x12, struct fb_vblank)
 
 #define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
 #define FB_TYPE_PLANES			1	/* Non interleaved planes */
@@ -209,6 +210,24 @@
 	__u16 vfmin;			/* vfreq lower limit (Hz) */
 	__u16 vfmax;			/* vfreq upper limit (Hz) */
 	unsigned dpms : 1;		/* supports DPMS */
+};
+
+#define FB_VBLANK_VBLANKING	0x001	/* currently in a vertical blank */
+#define FB_VBLANK_HBLANKING	0x002	/* currently in a horizontal blank */
+#define FB_VBLANK_HAVE_VBLANK	0x004	/* vertical blanks can be detected */
+#define FB_VBLANK_HAVE_HBLANK	0x008	/* horizontal blanks can be detected */
+#define FB_VBLANK_HAVE_COUNT	0x010	/* global retrace counter is available */
+#define FB_VBLANK_HAVE_VCOUNT	0x020	/* the vcount field is valid */
+#define FB_VBLANK_HAVE_HCOUNT	0x040	/* the hcount field is valid */
+#define FB_VBLANK_VSYNCING	0x080	/* currently in a vsync */
+#define FB_VBLANK_HAVE_VSYNC	0x100	/* verical syncs can be detected */
+
+struct fb_vblank {
+	__u32 flags;			/* FB_VBLANK flags */
+	__u32 count;			/* counter of retraces since boot */
+	__u32 vcount;			/* current scanline position */
+	__u32 hcount;			/* current scandot position */
+	__u32 reserved[4];		/* reserved for future compatibility */
 };
 
 #ifdef __KERNEL__
diff -u --recursive --new-file v2.3.47/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.3.47/linux/include/linux/fs.h	Sun Feb 20 21:12:40 2000
+++ linux/include/linux/fs.h	Sat Feb 26 20:46:01 2000
@@ -385,6 +385,7 @@
 	unsigned long		i_version;
 	struct semaphore	i_sem;
 	struct inode_operations	*i_op;
+	struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
 	struct super_block	*i_sb;
 	wait_queue_head_t	i_wait;
 	struct file_lock	*i_flock;
@@ -668,7 +669,6 @@
 };
 
 struct inode_operations {
-	struct file_operations * default_file_ops;
 	int (*create) (struct inode *,struct dentry *,int);
 	struct dentry * (*lookup) (struct inode *,struct dentry *);
 	int (*link) (struct dentry *,struct inode *,struct dentry *);
@@ -684,6 +684,8 @@
 	void (*truncate) (struct inode *);
 	int (*permission) (struct inode *, int);
 	int (*revalidate) (struct dentry *);
+	int (*setattr) (struct dentry *, struct iattr *);
+	int (*getattr) (struct dentry *, struct iattr *);
 };
 
 /*
@@ -695,7 +697,6 @@
 	void (*write_inode) (struct inode *);
 	void (*put_inode) (struct inode *);
 	void (*delete_inode) (struct inode *);
-	int (*notify_change) (struct dentry *, struct iattr *);
 	void (*put_super) (struct super_block *);
 	void (*write_super) (struct super_block *);
 	int (*statfs) (struct super_block *, struct statfs *, int);
@@ -796,6 +797,7 @@
 extern void bdput(struct block_device *);
 extern int blkdev_open(struct inode *, struct file *);
 extern struct file_operations def_blk_fops;
+extern struct file_operations def_fifo_fops;
 extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
 extern int blkdev_get(struct block_device *, mode_t, unsigned, int);
 extern int blkdev_put(struct block_device *, int);
@@ -811,9 +813,6 @@
 extern const char * kdevname(kdev_t);
 extern void init_special_inode(struct inode *, umode_t, int);
 
-extern struct inode_operations fifo_inode_operations;
-extern struct inode_operations blkdev_inode_operations;
-
 /* Invalid inode operations -- fs/bad_inode.c */
 extern void make_bad_inode(struct inode *);
 extern int is_bad_inode(struct inode *);
@@ -1019,11 +1018,15 @@
 extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *);
 extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t);
 
+extern ssize_t generic_read_dir(struct file *, char *, size_t, loff_t *);
+
+extern struct file_operations generic_ro_fops;
+
 extern int vfs_readlink(struct dentry *, char *, int, const char *);
 extern struct dentry *vfs_follow_link(struct dentry *, struct dentry *, unsigned, const char *);
 extern int page_readlink(struct dentry *, char *, int);
 extern struct dentry *page_follow_link(struct dentry *, struct dentry *, unsigned);
-struct inode_operations page_symlink_inode_operations;
+extern struct inode_operations page_symlink_inode_operations;
 
 extern struct super_block *get_super(kdev_t);
 struct super_block *get_empty_super(void);
diff -u --recursive --new-file v2.3.47/linux/include/linux/hdreg.h linux/include/linux/hdreg.h
--- v2.3.47/linux/include/linux/hdreg.h	Fri Jan 28 15:09:09 2000
+++ linux/include/linux/hdreg.h	Sat Feb 26 20:45:59 2000
@@ -86,6 +86,7 @@
 #define WIN_SRST		0x08	/* ATAPI soft reset command */
 #define WIN_PACKETCMD		0xA0	/* Send a packet command. */
 
+#define DISABLE_SEAGATE		0xFB
 #define EXABYTE_ENABLE_NEST	0xF0
 
 /* WIN_SMART sub-commands */
@@ -104,6 +105,7 @@
 
 #define SETFEATURES_EN_WCACHE	0x02	/* Enable write cache */
 #define SETFEATURES_XFER	0x03	/* Set transfer mode */
+#	define XFER_UDMA_7	0x47	/* 0100|0111 */
 #	define XFER_UDMA_6	0x46	/* 0100|0110 */
 #	define XFER_UDMA_5	0x45	/* 0100|0101 */
 #	define XFER_UDMA_4	0x44	/* 0100|0100 */
@@ -123,6 +125,7 @@
 #	define XFER_PIO_1	0x09	/* 0000|1001 */
 #	define XFER_PIO_0	0x08	/* 0000|1000 */
 #	define XFER_PIO_SLOW	0x00	/* 0000|0000 */
+#define SETFEATURES_DIS_DEFECT	0x04	/* Disable Defect Management */
 #define SETFEATURES_EN_APM	0x05	/* Enable advanced power management */
 #define SETFEATURES_DIS_MSN	0x31	/* Disable Media Status Notification */
 #define SETFEATURES_DIS_RLA	0x55	/* Disable read look-ahead feature */
@@ -130,9 +133,11 @@
 #define SETFEATURES_EN_SI	0x5E	/* Enable SERVICE interrupt */
 #define SETFEATURES_DIS_RPOD	0x66	/* Disable reverting to power on defaults */
 #define SETFEATURES_DIS_WCACHE	0x82	/* Disable write cache */
+#define SETFEATURES_EN_DEFECT	0x84	/* Enable Defect Management */
 #define SETFEATURES_DIS_APM	0x85	/* Disable advanced power management */
 #define SETFEATURES_EN_MSN	0x95	/* Enable Media Status Notification */
 #define SETFEATURES_EN_RLA	0xAA	/* Enable read look-ahead feature */
+#define SETFEATURES_PREFETCH	0xAB	/* Sets drive prefetch value */
 #define SETFEATURES_EN_RPOD	0xCC	/* Enable reverting to power on defaults */
 #define SETFEATURES_DIS_RI	0xDD	/* Disable release interrupt */
 #define SETFEATURES_DIS_SI	0xDE	/* Disable SERVICE interrupt */
@@ -232,26 +237,11 @@
 	unsigned short  eide_dma_time;	/* recommended mword dma cycle time (ns) */
 	unsigned short  eide_pio;       /* min cycle time (ns), no IORDY  */
 	unsigned short  eide_pio_iordy; /* min cycle time (ns), with IORDY */
-#if 0
-	unsigned short  words69_74[6];	/* reserved words 69-74 */
-#else
-	unsigned short  word69;		/* reserved (word 69) */
-	unsigned short  word70;		/* reserved (word 70) */
+	unsigned short	words69_70[2];	/* reserved words 69-70 */
 	/* HDIO_GET_IDENTITY currently returns only words 0 through 70 */
-	unsigned short  word71;		/* reserved (word 71) */
-	unsigned short  word72;		/* reserved (word 72) */
-	unsigned short  word73;		/* reserved (word 73) */
-	unsigned short  word74;		/* reserved (word 74) */
-#endif
+	unsigned short	words71_74[4];	/* reserved words 71-74 */
 	unsigned short  queue_depth;	/*  */
-#if 0
 	unsigned short  words76_79[4];	/* reserved words 76-79 */
-#else
-	unsigned short  word76;		/* reserved (word 76) */
-	unsigned short  word77;		/* reserved (word 77) */
-	unsigned short  word78;		/* reserved (word 78) */
-	unsigned short  word79;		/* reserved (word 79) */
-#endif
 	unsigned short  major_rev_num;	/*  */
 	unsigned short  minor_rev_num;	/*  */
 	unsigned short  command_set_1;	/* bits 0:Smart 1:Security 2:Removable 3:PM */
@@ -266,43 +256,8 @@
 	unsigned short	CurAPMvalues;	/* current APM values */
 	unsigned short	word92;		/* reserved (word 92) */
 	unsigned short	hw_config;	/* hardware config */
-#if 0
-	unsigned short  words94_126[34];/* reserved words 94-126 */
-#else
-	unsigned short	word94;		/* reserved (word 94) */
-	unsigned short	word95;		/* reserved (word 95) */
-	unsigned short	word96;		/* reserved (word 96) */
-	unsigned short	word97;		/* reserved (word 97) */
-	unsigned short	word98;		/* reserved (word 98) */
-	unsigned short	word99;		/* reserved (word 99) */
-	unsigned short	word100;	/* reserved (word 100) */
-	unsigned short	word101;	/* reserved (word 101) */
-	unsigned short	word102;	/* reserved (word 102) */
-	unsigned short	word103;	/* reserved (word 103) */
-	unsigned short	word104;	/* reserved (word 104) */
-	unsigned short	word105;	/* reserved (word 105) */
-	unsigned short	word106;	/* reserved (word 106) */
-	unsigned short	word107;	/* reserved (word 107) */
-	unsigned short	word108;	/* reserved (word 108) */
-	unsigned short	word109;	/* reserved (word 109) */
-	unsigned short	word110;	/* reserved (word 110) */
-	unsigned short	word111;	/* reserved (word 111) */
-	unsigned short	word112;	/* reserved (word 112) */
-	unsigned short	word113;	/* reserved (word 113) */
-	unsigned short	word114;	/* reserved (word 114) */
-	unsigned short	word115;	/* reserved (word 115) */
-	unsigned short	word116;	/* reserved (word 116) */
-	unsigned short	word117;	/* reserved (word 117) */
-	unsigned short	word118;	/* reserved (word 118) */
-	unsigned short	word119;	/* reserved (word 119) */
-	unsigned short	word120;	/* reserved (word 120) */
-	unsigned short	word121;	/* reserved (word 121) */
-	unsigned short	word122;	/* reserved (word 122) */
-	unsigned short	word123;	/* reserved (word 123) */
-	unsigned short	word124;	/* reserved (word 124) */
-	unsigned short	word125;	/* reserved (word 125) */
-	unsigned short	word126;	/* reserved (word 126) */
-#endif
+	unsigned short  words94_125[33];/* reserved words 94-125 */
+	unsigned short	last_lun;	/* reserved (word 126) */
 	unsigned short	word127;	/* reserved (word 127) */
 	unsigned short	dlf;		/* device lock function
 					 * 15:9	reserved
@@ -322,7 +277,8 @@
 					 * 1	read-look-ahead
 					 * 0	write cache
 					 */
-	unsigned short	reserved[126];
+	unsigned short	words130_159[30];/* reserved vendor words 130-159 */
+	unsigned short	words160_255[96];/* reserved words 160-255 */
 };
 
 /*
diff -u --recursive --new-file v2.3.47/linux/include/linux/hfs_fs.h linux/include/linux/hfs_fs.h
--- v2.3.47/linux/include/linux/hfs_fs.h	Fri Jan 21 18:19:17 2000
+++ linux/include/linux/hfs_fs.h	Sat Feb 26 20:54:43 2000
@@ -234,8 +234,6 @@
 					 const struct hfs_cat_key *);
 
 /* dir.c */
-extern hfs_rwret_t hfs_dir_read(struct file *, char *, hfs_rwarg_t,
-				loff_t *);
 extern int hfs_create(struct inode *, struct dentry *, int);
 extern int hfs_mkdir(struct inode *, struct dentry *, int);
 extern int hfs_unlink(struct inode *, struct dentry *);
@@ -249,12 +247,14 @@
 extern struct inode_operations hfs_cap_ndir_inode_operations;
 extern struct inode_operations hfs_cap_fdir_inode_operations;
 extern struct inode_operations hfs_cap_rdir_inode_operations;
+extern struct file_operations hfs_cap_dir_operations;
 extern void hfs_cap_drop_dentry(struct dentry *, const ino_t);
 
 /* dir_dbl.c */
 extern const struct hfs_name hfs_dbl_reserved1[];
 extern const struct hfs_name hfs_dbl_reserved2[];
 extern struct inode_operations hfs_dbl_dir_inode_operations;
+extern struct file_operations hfs_dbl_dir_operations;
 extern void hfs_dbl_drop_dentry(struct dentry *, const ino_t);
 
 /* dir_nat.c */
@@ -262,13 +262,9 @@
 extern const struct hfs_name hfs_nat_reserved2[];
 extern struct inode_operations hfs_nat_ndir_inode_operations;
 extern struct inode_operations hfs_nat_hdir_inode_operations;
+extern struct file_operations hfs_nat_dir_operations;
 extern void hfs_nat_drop_dentry(struct dentry *, const ino_t);
 
-/* dir_sngl.c */
-extern const struct hfs_name hfs_sngl_reserved1[];
-extern const struct hfs_name hfs_sngl_reserved2[];
-extern struct inode_operations hfs_sngl_dir_inode_operations;
-
 /* file.c */
 extern hfs_s32 hfs_do_read(struct inode *, struct hfs_fork *, hfs_u32,
 			   char *, hfs_u32, int);
@@ -276,21 +272,27 @@
 			    const char *, hfs_u32);
 extern void hfs_file_fix_mode(struct hfs_cat_entry *entry);
 extern struct inode_operations hfs_file_inode_operations;
+extern struct file_operations hfs_file_operations;
 
 /* file_cap.c */
 extern struct inode_operations hfs_cap_info_inode_operations;
+extern struct file_operations hfs_cap_info_operations;
 
 /* file_hdr.c */
 extern struct inode_operations hfs_hdr_inode_operations;
+extern struct file_operations hfs_hdr_operations;
 extern const struct hfs_hdr_layout hfs_dbl_fil_hdr_layout;
 extern const struct hfs_hdr_layout hfs_dbl_dir_hdr_layout;
 extern const struct hfs_hdr_layout hfs_nat_hdr_layout;
 extern const struct hfs_hdr_layout hfs_nat2_hdr_layout;
 extern const struct hfs_hdr_layout hfs_sngl_hdr_layout;
+extern void hdr_truncate(struct inode *,size_t);
 
 /* inode.c */
 extern void hfs_put_inode(struct inode *);
 extern int hfs_notify_change(struct dentry *, struct iattr *);
+extern int hfs_notify_change_cap(struct dentry *, struct iattr *);
+extern int hfs_notify_change_hdr(struct dentry *, struct iattr *);
 extern struct inode *hfs_iget(struct hfs_cat_entry *, ino_t, struct dentry *);
 
 extern void hfs_cap_ifill(struct inode *, ino_t, const int);
diff -u --recursive --new-file v2.3.47/linux/include/linux/ide.h linux/include/linux/ide.h
--- v2.3.47/linux/include/linux/ide.h	Sun Feb 20 21:12:40 2000
+++ linux/include/linux/ide.h	Sat Feb 26 20:51:08 2000
@@ -181,12 +181,17 @@
 struct hwif_s;
 typedef int (ide_ack_intr_t)(struct hwif_s *);
 
+#ifndef NO_DMA
+#define NO_DMA  255
+#endif
+
 /*
  * Structure to hold all information about the location of this port
  */
 typedef struct hw_regs_s {
 	ide_ioreg_t	io_ports[IDE_NR_PORTS];	/* task file registers */
 	int		irq;			/* our irq number */
+	int		dma;			/* our dma entry */
 	ide_ack_intr_t	*ack_intr;		/* acknowledge interrupt */
 	void		*priv;			/* interface specific data */
 } hw_regs_t;
@@ -356,6 +361,7 @@
 		ide_cmd646,	ide_cy82c693,	ide_4drives
 } hwif_chipset_t;
 
+#ifdef CONFIG_BLK_DEV_IDEPCI
 typedef struct ide_pci_devid_s {
 	unsigned short	vid;
 	unsigned short	did;
@@ -363,6 +369,7 @@
 
 #define IDE_PCI_DEVID_NULL	((ide_pci_devid_t){0,0})
 #define IDE_PCI_DEVID_EQ(a,b)	(a.vid == b.vid && a.did == b.did)
+#endif /* CONFIG_BLK_DEV_IDEPCI */
 
 typedef struct hwif_s {
 	struct hwif_s	*next;		/* for linked-list in ide_hwgroup_t */
@@ -399,8 +406,10 @@
 	unsigned	autodma    : 1;	/* automatically try to enable DMA at boot */
 	unsigned	udma_four  : 1;	/* 1=ATA-66 capable, 0=default */
 	byte		channel;	/* for dual-port chips: 0=primary, 1=secondary */
+#ifdef CONFIG_BLK_DEV_IDEPCI
 	struct pci_dev	*pci_dev;	/* for pci chipsets */
 	ide_pci_devid_t	pci_devid;	/* for pci chipsets: {VID,DID} */
+#endif /* CONFIG_BLK_DEV_IDEPCI */
 #if (DISK_RECOVERY_TIME > 0)
 	unsigned long	last_time;	/* time when previous rq was done */
 #endif
@@ -579,7 +588,8 @@
  */
 #ifndef _IDE_C
 extern	ide_hwif_t	ide_hwifs[];		/* master data repository */
-extern  ide_module_t	*ide_modules;
+extern	ide_module_t	*ide_modules;
+extern	ide_module_t	*ide_probe;
 #endif
 
 /*
@@ -850,5 +860,7 @@
 void ide_setup_dma (ide_hwif_t *hwif, unsigned long dmabase, unsigned int num_ports) __init;
 unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) __init;
 #endif
+
+void hwif_unregister (ide_hwif_t *hwif);
 
 #endif /* _IDE_H */
diff -u --recursive --new-file v2.3.47/linux/include/linux/irq.h linux/include/linux/irq.h
--- v2.3.47/linux/include/linux/irq.h	Sun Feb 20 21:12:40 2000
+++ linux/include/linux/irq.h	Sat Feb 26 20:45:58 2000
@@ -12,6 +12,7 @@
 #define IRQ_AUTODETECT	16	/* IRQ is being autodetected */
 #define IRQ_WAITING	32	/* IRQ not yet seen - for autodetection */
 #define IRQ_LEVEL	64	/* IRQ level triggered */
+#define IRQ_MASKED	128	/* IRQ masked - shouldn't be seen again */
 
 /*
  * Interrupt controller descriptor. This is all we need
@@ -25,6 +26,7 @@
 	void (*disable)(unsigned int irq);
 	void (*ack)(unsigned int irq);
 	void (*end)(unsigned int irq);
+	void (*set_affinity)(unsigned int irq, unsigned int mask);
 };
 
 typedef struct hw_interrupt_type  hw_irq_controller;
@@ -37,17 +39,33 @@
  * Pad this out to 32 bytes for cache and indexing reasons.
  */
 typedef struct {
-	unsigned int status;	/* IRQ status
-				  - IRQ_INPROGRESS, IRQ_DISABLED */
-	hw_irq_controller *handler;	/* never derefed in arch
-					   independent code */
-	struct irqaction *action;		/* IRQ action list */
-	unsigned int depth;			/* Disable depth for nested irq disables */
+	unsigned int status;		/* IRQ status */
+	hw_irq_controller *handler;
+	struct irqaction *action;	/* IRQ action list */
+	unsigned int depth;		/* nested irq disables */
+	spinlock_t lock;
+	unsigned int __pad[3];
 } ____cacheline_aligned irq_desc_t;
 
-#include <asm/hw_irq.h> /* the arch dependent stuff */
+extern irq_desc_t irq_desc [NR_IRQS];
+
+typedef struct {
+	unsigned int __local_irq_count;
+	unsigned int __local_bh_count;
+	atomic_t __nmi_counter;
+	unsigned int __pad[5];
+} ____cacheline_aligned irq_cpustat_t;
+
+extern irq_cpustat_t irq_stat [NR_CPUS];
 
-extern irq_desc_t irq_desc[NR_IRQS];
+/*
+ * Simple wrappers reducing source bloat
+ */
+#define local_irq_count(cpu) (irq_stat[(cpu)].__local_irq_count)
+#define local_bh_count(cpu) (irq_stat[(cpu)].__local_bh_count)
+#define nmi_counter(cpu) (irq_stat[(cpu)].__nmi_counter)
+
+#include <asm/hw_irq.h> /* the arch dependent stuff */
 
 extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
 extern spinlock_t irq_controller_lock;
diff -u --recursive --new-file v2.3.47/linux/include/linux/isdn.h linux/include/linux/isdn.h
--- v2.3.47/linux/include/linux/isdn.h	Wed Feb 16 17:03:52 2000
+++ linux/include/linux/isdn.h	Sat Feb 26 20:20:13 2000
@@ -1,4 +1,4 @@
-/* $Id: isdn.h,v 1.90 2000/02/06 21:50:00 detabc Exp $
+/* $Id: isdn.h,v 1.94 2000/02/26 00:29:40 keil Exp $
  *
  * Main header for the Linux ISDN subsystem (linklevel).
  *
@@ -21,6 +21,19 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: isdn.h,v $
+ * Revision 1.94  2000/02/26 00:29:40  keil
+ * more softnet changes
+ *
+ * Revision 1.93  2000/02/25 11:29:17  paul
+ * changed chargetime to ulong from int (after about 20 days the "chargetime of
+ * ipppX is now 1234" message displays a negative number on alpha).
+ *
+ * Revision 1.92  2000/02/17 13:15:56  keil
+ * fix backward compatibility for 2.2
+ *
+ * Revision 1.91  2000/02/16 14:56:27  paul
+ * translated ISDN_MODEM_ANZREG to ISDN_MODEM_NUMREG for english speakers
+ *
  * Revision 1.90  2000/02/06 21:50:00  detabc
  * add rewriting of socket's and frame's saddr for udp-ipv4 dynip-connections.
  * Include checksum-recompute of ip- and udp-header's.
@@ -444,7 +457,7 @@
 #define ISDN_USAGE_EXCLUSIVE 64 /* This bit is set, if channel is exclusive */
 #define ISDN_USAGE_OUTGOING 128 /* This bit is set, if channel is outgoing  */
 
-#define ISDN_MODEM_ANZREG    24        /* Number of Modem-Registers        */
+#define ISDN_MODEM_NUMREG    24        /* Number of Modem-Registers        */
 #define ISDN_LMSNLEN         255 /* Length of tty's Listen-MSN string */
 #define ISDN_CMSGLEN	     50	 /* Length of CONNECT-Message to add for Modem */
 
@@ -672,7 +685,7 @@
                                        /*   0 = Transparent                */
   int                    huptimer;     /* Timeout-counter for auto-hangup  */
   int                    charge;       /* Counter for charging units       */
-  int                    chargetime;   /* Timer for Charging info          */
+  ulong                  chargetime;   /* Timer for Charging info          */
   int                    hupflags;     /* Flags for charge-unit-hangup:    */
 				       /* bit0: chargeint is invalid       */
 				       /* bit1: Getting charge-interval    */
@@ -777,8 +790,8 @@
 
 /* Private data of AT-command-interpreter */
 typedef struct atemu {
-	u_char       profile[ISDN_MODEM_ANZREG]; /* Modem-Regs. Profile 0              */
-	u_char       mdmreg[ISDN_MODEM_ANZREG];  /* Modem-Registers                    */
+	u_char       profile[ISDN_MODEM_NUMREG]; /* Modem-Regs. Profile 0              */
+	u_char       mdmreg[ISDN_MODEM_NUMREG];  /* Modem-Registers                    */
 	char         pmsn[ISDN_MSNLEN];          /* EAZ/MSNs Profile 0                 */
 	char         msn[ISDN_MSNLEN];           /* EAZ/MSN                            */
 	char         plmsn[ISDN_LMSNLEN];        /* Listening MSNs Profile 0           */
@@ -985,10 +998,10 @@
 	devfs_handle_t devfs_handle_isdnctrl;
 	devfs_handle_t devfs_handle_isdnX[ISDN_MAX_CHANNELS];
 	devfs_handle_t devfs_handle_isdnctrlX[ISDN_MAX_CHANNELS];
-#  ifdef CONFIG_ISDN_PPP
+#ifdef CONFIG_ISDN_PPP
 	devfs_handle_t devfs_handle_ipppX[ISDN_MAX_CHANNELS];
-#  endif
 #endif
+#endif /* CONFIG_DEVFS_FS */
 } isdn_dev;
 
 extern isdn_dev *dev;
diff -u --recursive --new-file v2.3.47/linux/include/linux/iso_fs.h linux/include/linux/iso_fs.h
--- v2.3.47/linux/include/linux/iso_fs.h	Thu Feb 10 17:11:22 2000
+++ linux/include/linux/iso_fs.h	Sat Feb 26 20:46:00 2000
@@ -189,8 +189,8 @@
 extern int init_iso9660_fs(void);
 extern int isofs_lookup_grandparent(struct inode *, int);
 
-extern struct inode_operations isofs_file_inode_operations;
 extern struct inode_operations isofs_dir_inode_operations;
+extern struct file_operations isofs_dir_operations;
 extern struct address_space_operations isofs_symlink_aops;
 
 /* The following macros are used to check for memory leaks. */
diff -u --recursive --new-file v2.3.47/linux/include/linux/list.h linux/include/linux/list.h
--- v2.3.47/linux/include/linux/list.h	Sun Jul 11 22:50:27 1999
+++ linux/include/linux/list.h	Thu Feb 24 10:15:54 2000
@@ -104,6 +104,9 @@
 #define list_entry(ptr, type, member) \
 	((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
 
+#define list_for_each(pos, head) \
+	for (pos = (head)->next; pos != (head); pos = pos->next)
+
 #endif /* __KERNEL__ */
 
 #endif
diff -u --recursive --new-file v2.3.47/linux/include/linux/lists.h linux/include/linux/lists.h
--- v2.3.47/linux/include/linux/lists.h	Sun Feb 20 21:12:40 2000
+++ linux/include/linux/lists.h	Wed Dec 31 16:00:00 1969
@@ -1,62 +0,0 @@
-/*
- * lists.h:  Simple list macros for Linux
- */
-
-#define DLNODE(ptype)			       	       	       	\
-	struct {			 			\
-		ptype * dl_prev;	 			\
-		ptype * dl_next;	 			\
-	}
-
-#define DNODE_SINGLE(node) {(node),(node)}
-#define DNODE_NULL {0,0}
-
-#define DLIST_INIT(listnam)	                                \
-	(listnam).dl_prev = &(listnam);				\
-	(listnam).dl_next = &(listnam);
-
-#define DLIST_NEXT(listnam)	listnam.dl_next
-#define DLIST_PREV(listnam)	listnam.dl_prev
-
-#define DLIST_INSERT_AFTER(node, new, listnam)	do {		\
-	(new)->listnam.dl_prev = (node);			\
-	(new)->listnam.dl_next = (node)->listnam.dl_next;	\
-	(node)->listnam.dl_next->listnam.dl_prev = (new);	\
-	(node)->listnam.dl_next = (new);			\
-	} while (0)
-
-#define DLIST_INSERT_BEFORE(node, new, listnam)	do {		\
-	(new)->listnam.dl_next = (node);			\
-	(new)->listnam.dl_prev = (node)->listnam.dl_prev;	\
-	(node)->listnam.dl_prev->listnam.dl_next = (new);	\
-	(node)->listnam.dl_prev = (new);			\
-	} while (0)
-
-#define DLIST_DELETE(node, listnam)	do {		\
-	node->listnam.dl_prev->listnam.dl_next =		\
-		node->listnam.dl_next;				\
-	node->listnam.dl_next->listnam.dl_prev =		\
-		node->listnam.dl_prev;				\
-	} while (0)
-
-/*
- * queue-style operations, which have a head and tail
- */
-
-#define QUEUE_INIT(head, listnam, ptype)				\
-	(head)->listnam.dl_prev = (head)->listnam.dl_next = (ptype)(head);
-
-#define QUEUE_FIRST(head, listnam) (head)->DLIST_NEXT(listnam)
-#define QUEUE_LAST(head, listnam) (head)->DLIST_PREV(listnam)
-#define QUEUE_IS_EMPTY(head, listnam) \
-	((QUEUE_FIRST(head, listnam) == QUEUE_LAST(head, listnam)) && \
-	 ((u_long)QUEUE_FIRST(head, listnam) == (u_long)head)) 
-
-#define QUEUE_ENTER(head, new, listnam, ptype) do {		\
-	(new)->listnam.dl_prev = (ptype)(head);			\
-	(new)->listnam.dl_next = (head)->listnam.dl_next;	\
-	(head)->listnam.dl_next->listnam.dl_prev = (new);	\
-	(head)->listnam.dl_next = (new);			\
-	} while (0)
-
-#define QUEUE_REMOVE(head, node, listnam) DLIST_DELETE(node, listnam)
diff -u --recursive --new-file v2.3.47/linux/include/linux/matroxfb.h linux/include/linux/matroxfb.h
--- v2.3.47/linux/include/linux/matroxfb.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/matroxfb.h	Mon Feb 21 11:08:22 2000
@@ -0,0 +1,32 @@
+#ifndef __LINUX_MATROXFB_H__
+#define __LINUX_MATROXFB_H__
+
+#include <asm/ioctl.h>
+#include <asm/types.h>
+
+struct matroxioc_output_mode {
+	__u32	output;		/* which output */
+#define MATROXFB_OUTPUT_PRIMARY		0x0000
+#define MATROXFB_OUTPUT_SECONDARY	0x0001
+	__u32	mode;		/* which mode */
+#define MATROXFB_OUTPUT_MODE_PAL	0x0001
+#define MATROXFB_OUTPUT_MODE_NTSC	0x0002
+#define MATROXFB_OUTPUT_MODE_MONITOR	0x0080
+};
+#define MATROXFB_SET_OUTPUT_MODE	_IOW('n',0xFA,sizeof(struct matroxioc_output_mode))
+#define MATROXFB_GET_OUTPUT_MODE	_IOWR('n',0xFA,sizeof(struct matroxioc_output_mode))
+
+/* bitfield */
+#define MATROXFB_OUTPUT_CONN_PRIMARY	(1 << MATROXFB_OUTPUT_PRIMARY)
+#define MATROXFB_OUTPUT_CONN_SECONDARY	(1 << MATROXFB_OUTPUT_SECONDARY)
+/* connect these outputs to this framebuffer */
+#define MATROXFB_SET_OUTPUT_CONNECTION	_IOW('n',0xF8,sizeof(__u32))
+/* which outputs are connected to this framebuffer */
+#define MATROXFB_GET_OUTPUT_CONNECTION	_IOR('n',0xF8,sizeof(__u32))
+/* which outputs are available for this framebuffer */
+#define MATROXFB_GET_AVAILABLE_OUTPUTS	_IOR('n',0xF9,sizeof(__u32))
+/* which outputs exist on this framebuffer */
+#define MATROXFB_GET_ALL_OUTPUTS	_IOR('n',0xFB,sizeof(__u32))
+
+#endif
+
diff -u --recursive --new-file v2.3.47/linux/include/linux/minix_fs.h linux/include/linux/minix_fs.h
--- v2.3.47/linux/include/linux/minix_fs.h	Thu Feb 10 17:11:22 2000
+++ linux/include/linux/minix_fs.h	Sat Feb 26 20:33:09 2000
@@ -89,17 +89,6 @@
 
 #ifdef __KERNEL__
 
-extern struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry);
-extern int minix_create(struct inode * dir, struct dentry *dentry, int mode);
-extern int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode);
-extern int minix_rmdir(struct inode * dir, struct dentry *dentry);
-extern int minix_unlink(struct inode * dir, struct dentry *dentry);
-extern int minix_symlink(struct inode * inode, struct dentry *dentry,
-	const char * symname);
-extern int minix_link(struct dentry * old_dentry, struct inode * dir, struct dentry *dentry);
-extern int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev);
-extern int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
-			struct inode * new_dir, struct dentry *new_dentry);
 extern struct inode * minix_new_inode(const struct inode * dir, int * error);
 extern void minix_free_inode(struct inode * inode);
 extern unsigned long minix_count_free_inodes(struct super_block *sb);
@@ -118,6 +107,8 @@
 extern struct address_space_operations minix_aops;
 extern struct inode_operations minix_file_inode_operations;
 extern struct inode_operations minix_dir_inode_operations;
+extern struct file_operations minix_file_operations;
+extern struct file_operations minix_dir_operations;
 extern struct dentry_operations minix_dentry_operations;
 
 #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.3.47/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.3.47/linux/include/linux/mm.h	Sun Feb 13 19:29:04 2000
+++ linux/include/linux/mm.h	Sat Feb 26 20:50:43 2000
@@ -378,6 +378,8 @@
 
 extern void clear_page_tables(struct mm_struct *, unsigned long, int);
 
+extern int map_zero_setup(struct vm_area_struct *);
+
 extern void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size);
 extern int copy_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma);
 extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size, pgprot_t prot);
@@ -393,7 +395,6 @@
 extern int pgt_cache_water[2];
 extern int check_pgt_cache(void);
 
-extern void paging_init(void);
 extern void free_area_init(unsigned long * zones_size);
 extern void free_area_init_node(int nid, pg_data_t *pgdat, 
 		unsigned long * zones_size, unsigned long zone_start_paddr);
diff -u --recursive --new-file v2.3.47/linux/include/linux/mmzone.h linux/include/linux/mmzone.h
--- v2.3.47/linux/include/linux/mmzone.h	Sat Feb 12 11:22:11 2000
+++ linux/include/linux/mmzone.h	Sat Feb 26 20:50:34 2000
@@ -28,7 +28,8 @@
 	spinlock_t lock;
 	unsigned long offset;
 	unsigned long free_pages;
-	int low_on_memory;
+	char low_on_memory;
+	char zone_wake_kswapd;
 	unsigned long pages_min, pages_low, pages_high;
 
 	/*
@@ -84,9 +85,11 @@
 	unsigned long node_start_mapnr;
 	unsigned long node_size;
 	int node_id;
+	struct pglist_data *node_next;
 } pg_data_t;
 
 extern int numnodes;
+extern pg_data_t *pgdat_list;
 
 #define memclass(pgzone, tzone)	(((pgzone)->zone_pgdat == (tzone)->zone_pgdat) \
 			&& (((pgzone) - (pgzone)->zone_pgdat->node_zones) <= \
diff -u --recursive --new-file v2.3.47/linux/include/linux/msdos_fs.h linux/include/linux/msdos_fs.h
--- v2.3.47/linux/include/linux/msdos_fs.h	Thu Feb 10 17:11:22 2000
+++ linux/include/linux/msdos_fs.h	Sat Feb 26 20:48:28 2000
@@ -267,6 +267,7 @@
 extern struct inode_operations fat_file_inode_operations;
 extern struct inode_operations fat_file_inode_operations_1024;
 extern struct inode_operations fat_file_inode_operations_readpage;
+extern struct file_operations fat_file_operations;
 extern ssize_t fat_file_read(struct file *, char *, size_t, loff_t *);
 extern ssize_t fat_file_write(struct file *, const char *, size_t, loff_t *);
 extern void fat_truncate(struct inode *inode);
diff -u --recursive --new-file v2.3.47/linux/include/linux/ncp_fs.h linux/include/linux/ncp_fs.h
--- v2.3.47/linux/include/linux/ncp_fs.h	Fri Jan 21 18:19:17 2000
+++ linux/include/linux/ncp_fs.h	Sat Feb 26 20:54:43 2000
@@ -232,6 +232,7 @@
 
 /* linux/fs/ncpfs/dir.c */
 extern struct inode_operations ncp_dir_inode_operations;
+extern struct file_operations ncp_dir_operations;
 int ncp_conn_logged_in(struct super_block *);
 int ncp_date_dos2unix(__u16 time, __u16 date);
 void ncp_date_unix2dos(int unix_date, __u16 * time, __u16 * date);
@@ -252,6 +253,7 @@
 
 /* linux/fs/ncpfs/file.c */
 extern struct inode_operations ncp_file_inode_operations;
+extern struct file_operations ncp_file_operations;
 int ncp_make_open(struct inode *, int);
 
 /* linux/fs/ncpfs/mmap.c */
diff -u --recursive --new-file v2.3.47/linux/include/linux/netdevice.h linux/include/linux/netdevice.h
--- v2.3.47/linux/include/linux/netdevice.h	Sun Feb 20 21:12:40 2000
+++ linux/include/linux/netdevice.h	Sat Feb 26 20:50:43 2000
@@ -478,26 +478,6 @@
 	return test_bit(__LINK_STATE_START, &dev->state);
 }
 
-/* Hot-plugging. */
-extern __inline__ int netif_device_present(struct net_device *dev)
-{
-	return test_bit(__LINK_STATE_PRESENT, &dev->state);
-}
-
-extern __inline__ void netif_device_detach(struct net_device *dev)
-{
-	if (test_and_clear_bit(__LINK_STATE_PRESENT, &dev->state) &&
-	    netif_running(dev))
-		netif_stop_queue(dev);
-}
-
-extern __inline__ void netif_device_attach(struct net_device *dev)
-{
-	if (test_and_set_bit(__LINK_STATE_PRESENT, &dev->state) &&
-	    netif_running(dev))
-		netif_wake_queue(dev);
-}
-
 /* Use this variant when it is known for sure that it
  * is executing from interrupt context.
  */
@@ -553,6 +533,35 @@
 #define __dev_put(dev) atomic_dec(&(dev)->refcnt)
 #define dev_hold(dev) atomic_inc(&(dev)->refcnt)
 
+/* Hot-plugging. */
+extern __inline__ int netif_device_present(struct net_device *dev)
+{
+	return test_bit(__LINK_STATE_PRESENT, &dev->state);
+}
+
+extern __inline__ void netif_device_detach(struct net_device *dev)
+{
+	if (test_and_clear_bit(__LINK_STATE_PRESENT, &dev->state) &&
+	    netif_running(dev)) {
+		netif_stop_queue(dev);
+		if (dev->tx_timeout &&
+		    del_timer(&dev->watchdog_timer))
+			__dev_put(dev);
+	}
+}
+
+extern __inline__ void netif_device_attach(struct net_device *dev)
+{
+	if (test_and_set_bit(__LINK_STATE_PRESENT, &dev->state) &&
+	    netif_running(dev)) {
+		netif_wake_queue(dev);
+		if (dev->tx_timeout) {
+			dev->watchdog_timer.expires = jiffies + dev->watchdog_timeo;
+			add_timer(&dev->watchdog_timer);
+			dev_hold(dev);
+		}
+	}
+}
 
 /* These functions live elsewhere (drivers/net/net_init.c, but related) */
 
diff -u --recursive --new-file v2.3.47/linux/include/linux/nfs_fs.h linux/include/linux/nfs_fs.h
--- v2.3.47/linux/include/linux/nfs_fs.h	Thu Feb 10 17:11:22 2000
+++ linux/include/linux/nfs_fs.h	Sat Feb 26 20:46:24 2000
@@ -185,17 +185,20 @@
 extern int nfs_open(struct inode *, struct file *);
 extern int nfs_release(struct inode *, struct file *);
 extern int __nfs_revalidate_inode(struct nfs_server *, struct dentry *);
+extern int nfs_notify_change(struct dentry *, struct iattr *);
 
 /*
  * linux/fs/nfs/file.c
  */
 extern struct inode_operations nfs_file_inode_operations;
+extern struct file_operations nfs_file_operations;
 extern struct address_space_operations nfs_file_aops;
 
 /*
  * linux/fs/nfs/dir.c
  */
 extern struct inode_operations nfs_dir_inode_operations;
+extern struct file_operations nfs_dir_operations;
 extern struct dentry_operations nfs_dentry_operations;
 extern void nfs_flush_dircache(struct inode *);
 extern void nfs_free_dircache(struct inode *);
diff -u --recursive --new-file v2.3.47/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.3.47/linux/include/linux/pci.h	Sun Feb 20 21:12:40 2000
+++ linux/include/linux/pci.h	Sat Feb 26 20:50:43 2000
@@ -285,6 +285,7 @@
 #include <linux/config.h>
 #include <linux/ioport.h>
 #include <linux/list.h>
+#include <linux/errno.h>
 
 /* This defines the direction arg to the DMA mapping routines. */
 #define PCI_DMA_BIDIRECTIONAL	0
diff -u --recursive --new-file v2.3.47/linux/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- v2.3.47/linux/include/linux/pci_ids.h	Sun Feb 20 21:12:40 2000
+++ linux/include/linux/pci_ids.h	Sat Feb 26 20:32:15 2000
@@ -1021,6 +1021,9 @@
 #define PCI_VENDOR_ID_NETGEAR		0x1385
 #define PCI_DEVICE_ID_NETGEAR_GA620	0x620a
 
+#define PCI_VENDOR_ID_3WARE		0x13C1
+#define PCI_DEVICE_ID_3WARE_1000	0x1000
+
 #define PCI_VENDOR_ID_LAVA		0x1407
 #define PCI_DEVICE_ID_LAVA_DSERIAL	0x0100 /* 2x 16550 */
 #define PCI_DEVICE_ID_LAVA_QUATRO_A	0x0101 /* 2x 16550, half of 4 port */
@@ -1094,8 +1097,8 @@
 #define PCI_DEVICE_ID_S3_ViRGE_MXPMV	0x8c03
 #define PCI_DEVICE_ID_S3_SONICVIBES	0xca00
 
-#define PCI_VENDOR_ID_DCI       0x6666
-#define PCI_DEVICE_ID_DCI_PCCOM4    0x0001
+#define PCI_VENDOR_ID_DCI		0x6666
+#define PCI_DEVICE_ID_DCI_PCCOM4	0x0001
 
 #define PCI_VENDOR_ID_GENROCO		0x5555
 #define PCI_DEVICE_ID_GENROCO_HFP832	0x0003
@@ -1155,6 +1158,7 @@
 #define PCI_DEVICE_ID_INTEL_82443BX_0	0x7190
 #define PCI_DEVICE_ID_INTEL_82443BX_1	0x7191
 #define PCI_DEVICE_ID_INTEL_82443BX_2	0x7192
+#define PCI_DEVICE_ID_INTEL_82372FB_1	0x7601
 #define PCI_DEVICE_ID_INTEL_82454GX	0x84c4
 #define PCI_DEVICE_ID_INTEL_82450GX	0x84c5
 #define PCI_DEVICE_ID_INTEL_82451NX	0x84ca
diff -u --recursive --new-file v2.3.47/linux/include/linux/pm.h linux/include/linux/pm.h
--- v2.3.47/linux/include/linux/pm.h	Sun Feb 20 21:12:40 2000
+++ linux/include/linux/pm.h	Sat Feb 26 20:46:00 2000
@@ -101,6 +101,7 @@
 
 	unsigned long	 flags;
 	int		 state;
+	int		 prev_state;
 
 	struct list_head entry;
 };
@@ -129,9 +130,14 @@
 void pm_unregister_all(pm_callback callback);
 
 /*
+ * Send a request to a single device
+ */
+int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data);
+
+/*
  * Send a request to all devices
  */
-int pm_send_request(pm_request_t rqst, void *data);
+int pm_send_all(pm_request_t rqst, void *data);
 
 /*
  * Find a device
@@ -156,7 +162,12 @@
 
 extern inline void pm_unregister_all(pm_callback callback) {}
 
-extern inline int pm_send_request(pm_request_t rqst, void *data)
+extern inline int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data)
+{
+	return 0;
+}
+
+extern inline int pm_send_all(pm_request_t rqst, void *data)
 {
 	return 0;
 }
diff -u --recursive --new-file v2.3.47/linux/include/linux/prctl.h linux/include/linux/prctl.h
--- v2.3.47/linux/include/linux/prctl.h	Sat Oct  9 11:47:50 1999
+++ linux/include/linux/prctl.h	Thu Feb 24 10:14:29 2000
@@ -10,4 +10,10 @@
 #define PR_GET_DUMPABLE   3
 #define PR_SET_DUMPABLE   4
 
+/* Get/set unaligned access control bits (if meaningful) */
+#define PR_GET_UNALIGN	  5
+#define PR_SET_UNALIGN	  6
+# define PR_UNALIGN_NOPRINT	1	/* silently fix up unaligned user accesses */
+# define PR_UNALIGN_SIGBUS	2	/* generate SIGBUS on unaligned user access */
+
 #endif /* _LINUX_PRCTL_H */
diff -u --recursive --new-file v2.3.47/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- v2.3.47/linux/include/linux/proc_fs.h	Thu Feb 10 17:11:22 2000
+++ linux/include/linux/proc_fs.h	Sat Feb 26 20:50:43 2000
@@ -59,7 +59,8 @@
 	uid_t uid;
 	gid_t gid;
 	unsigned long size;
-	struct inode_operations * ops;
+	struct inode_operations * proc_iops;
+	struct file_operations * proc_fops;
 	get_info_t *get_info;
 	struct module *owner;
 	struct proc_dir_entry *next, *parent, *subdir;
@@ -80,7 +81,7 @@
 extern struct proc_dir_entry *proc_net;
 extern struct proc_dir_entry *proc_bus;
 extern struct proc_dir_entry *proc_root_driver;
-extern struct proc_dir_entry proc_root_kcore;
+extern struct proc_dir_entry *proc_root_kcore;
 
 extern void proc_root_init(void);
 extern void proc_misc_init(void);
@@ -112,10 +113,9 @@
 extern int proc_readdir(struct file *, void *, filldir_t);
 extern struct dentry *proc_lookup(struct inode *, struct dentry *);
 
-extern struct inode_operations proc_sys_inode_operations;
-extern struct inode_operations proc_kcore_inode_operations;
-extern struct inode_operations proc_kmsg_inode_operations;
-extern struct inode_operations proc_ppc_htab_inode_operations;
+extern struct file_operations proc_kcore_operations;
+extern struct file_operations proc_kmsg_operations;
+extern struct file_operations ppc_htab_operations;
 
 /*
  * proc_tty.c
diff -u --recursive --new-file v2.3.47/linux/include/linux/qnx4_fs.h linux/include/linux/qnx4_fs.h
--- v2.3.47/linux/include/linux/qnx4_fs.h	Thu Feb 10 17:11:22 2000
+++ linux/include/linux/qnx4_fs.h	Sat Feb 26 20:33:09 2000
@@ -108,6 +108,8 @@
 extern int qnx4_create(struct inode *dir, struct dentry *dentry, int mode);
 extern struct inode_operations qnx4_file_inode_operations;
 extern struct inode_operations qnx4_dir_inode_operations;
+extern struct file_operations qnx4_file_operations;
+extern struct file_operations qnx4_dir_operations;
 extern int qnx4_is_free(struct super_block *sb, long block);
 extern int qnx4_set_bitmap(struct super_block *sb, long block, int busy);
 extern int qnx4_create(struct inode *inode, struct dentry *dentry, int mode);
diff -u --recursive --new-file v2.3.47/linux/include/linux/raid/md_k.h linux/include/linux/raid/md_k.h
--- v2.3.47/linux/include/linux/raid/md_k.h	Wed Feb 16 17:03:52 2000
+++ linux/include/linux/raid/md_k.h	Wed Feb 23 09:13:52 2000
@@ -75,6 +75,8 @@
 
 extern inline mddev_t * kdev_to_mddev (kdev_t dev)
 {
+	if (MAJOR(dev) != MD_MAJOR)
+		BUG();
         return mddev_map[MINOR(dev)].mddev;
 }
 
@@ -213,7 +215,7 @@
 	char *name;
 	int (*map)(mddev_t *mddev, kdev_t dev, kdev_t *rdev,
 		unsigned long *rsector, unsigned long size);
-	int (*make_request)(mddev_t *mddev, int rw, struct buffer_head * bh);
+	int (*make_request)(request_queue_t *q, mddev_t *mddev, int rw, struct buffer_head * bh);
 	void (*end_request)(struct buffer_head * bh, int uptodate);
 	int (*run)(mddev_t *mddev);
 	int (*stop)(mddev_t *mddev);
diff -u --recursive --new-file v2.3.47/linux/include/linux/smb_fs.h linux/include/linux/smb_fs.h
--- v2.3.47/linux/include/linux/smb_fs.h	Thu Feb 10 17:11:22 2000
+++ linux/include/linux/smb_fs.h	Sat Feb 26 20:54:43 2000
@@ -101,10 +101,12 @@
 
 /* linux/fs/smbfs/file.c */
 extern struct inode_operations smb_file_inode_operations;
+extern struct file_operations smb_file_operations;
 extern struct address_space_operations smb_file_aops;
 
 /* linux/fs/smbfs/dir.c */
 extern struct inode_operations smb_dir_inode_operations;
+extern struct file_operations smb_dir_operations;
 void smb_renew_times(struct dentry *);
 
 /* linux/fs/smbfs/ioctl.c */
diff -u --recursive --new-file v2.3.47/linux/include/linux/sysctl.h linux/include/linux/sysctl.h
--- v2.3.47/linux/include/linux/sysctl.h	Thu Feb 10 17:11:22 2000
+++ linux/include/linux/sysctl.h	Thu Feb 24 10:15:58 2000
@@ -21,11 +21,11 @@
  ****************************************************************
  */
 
-#include <linux/lists.h>
-
 #ifndef _LINUX_SYSCTL_H
 #define _LINUX_SYSCTL_H
 
+#include <linux/list.h>
+
 #define CTL_MAXNAME 10
 
 struct __sysctl_args {
@@ -664,7 +664,7 @@
 struct ctl_table_header
 {
 	ctl_table *ctl_table;
-	DLNODE(struct ctl_table_header) ctl_entry;	
+	struct list_head ctl_entry;
 };
 
 struct ctl_table_header * register_sysctl_table(ctl_table * table, 
diff -u --recursive --new-file v2.3.47/linux/include/linux/sysv_fs.h linux/include/linux/sysv_fs.h
--- v2.3.47/linux/include/linux/sysv_fs.h	Thu Feb 10 17:11:22 2000
+++ linux/include/linux/sysv_fs.h	Sat Feb 26 20:48:28 2000
@@ -367,16 +367,6 @@
  * Function prototypes
  */
 
-extern struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry);
-extern int sysv_create(struct inode * dir, struct dentry * dentry, int mode);
-extern int sysv_mkdir(struct inode * dir, struct dentry * dentry, int mode);
-extern int sysv_rmdir(struct inode * dir, struct dentry * dentry);
-extern int sysv_unlink(struct inode * dir, struct dentry * dentry);
-extern int sysv_symlink(struct inode * inode, struct dentry * dentry, const char * symname);
-extern int sysv_link(struct dentry * old_dentry, struct inode * dir, struct dentry * dentry);
-extern int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev);
-extern int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
-		       struct inode * new_dir, struct dentry * new_dentry);
 extern struct inode * sysv_new_inode(const struct inode * dir);
 extern void sysv_free_inode(struct inode * inode);
 extern unsigned long sysv_count_free_inodes(struct super_block *sb);
@@ -391,9 +381,13 @@
 extern void sysv_write_inode(struct inode *);
 extern int sysv_sync_inode(struct inode *);
 extern int sysv_sync_file(struct file *, struct dentry *);
+extern int sysv_notify_change(struct dentry *, struct iattr *);
 
 extern struct inode_operations sysv_file_inode_operations;
+extern struct inode_operations sysv_symlink_inode_operations;
 extern struct inode_operations sysv_dir_inode_operations;
+extern struct file_operations sysv_file_operations;
+extern struct file_operations sysv_dir_operations;
 extern struct address_space_operations sysv_aops;
 
 #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.3.47/linux/include/linux/timer.h linux/include/linux/timer.h
--- v2.3.47/linux/include/linux/timer.h	Thu Feb 10 17:11:22 2000
+++ linux/include/linux/timer.h	Sat Feb 26 20:45:58 2000
@@ -20,7 +20,6 @@
 #define GSCD_TIMER	9	/* Goldstar CDROM */
 #define COMTROL_TIMER	10	/* Comtrol serial */
 #define DIGI_TIMER	11	/* Digi serial */
-#define GDTH_TIMER	12	/* Ugh - gdth scsi driver */
 
 #define COPRO_TIMER	31	/* 387 timeout for buggy hardware (boot only) */
 
diff -u --recursive --new-file v2.3.47/linux/include/linux/ufs_fs.h linux/include/linux/ufs_fs.h
--- v2.3.47/linux/include/linux/ufs_fs.h	Thu Feb 10 17:11:22 2000
+++ linux/include/linux/ufs_fs.h	Sat Feb 26 20:45:58 2000
@@ -504,9 +504,6 @@
 
 #ifdef __KERNEL__
 
-/* acl.c */
-extern int ufs_permission (struct inode *, int);
-
 /* balloc.c */
 extern void ufs_free_fragments (struct inode *, unsigned, unsigned);
 extern void ufs_free_blocks (struct inode *, unsigned, unsigned);
@@ -518,7 +515,6 @@
 
 /* dir.c */
 extern struct inode_operations ufs_dir_inode_operations;
-extern struct file_operations ufs_dir_operations;
 extern int ufs_check_dir_entry (const char *, struct inode *, struct ufs_dir_entry *, struct buffer_head *, unsigned long);
 
 /* file.c */
@@ -543,18 +539,9 @@
 extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *);
 
 /* namei.c */
-extern struct dentry *ufs_lookup (struct inode *, struct dentry *);
-extern int ufs_mkdir(struct inode *, struct dentry *, int);
-extern int ufs_rmdir (struct inode *, struct dentry *);
-extern int ufs_unlink (struct inode *, struct dentry *);
-extern int ufs_create (struct inode *, struct dentry *, int);
-extern int ufs_rename (struct inode *, struct dentry *, struct inode *, struct dentry *);
-extern int ufs_mknod (struct inode *, struct dentry *, int, int);
-extern int ufs_symlink (struct inode *, struct dentry *, const char *);
-extern int ufs_link (struct dentry *, struct inode *, struct dentry *);
+extern struct file_operations ufs_dir_operations;
         
 /* super.c */
-extern struct super_operations ufs_super_ops;
 extern struct file_system_type ufs_fs_type;
 extern void ufs_warning (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4)));
 extern void ufs_error (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4)));
diff -u --recursive --new-file v2.3.47/linux/include/linux/umsdos_fs.h linux/include/linux/umsdos_fs.h
--- v2.3.47/linux/include/linux/umsdos_fs.h	Thu Feb 10 17:11:22 2000
+++ linux/include/linux/umsdos_fs.h	Sat Feb 26 20:48:28 2000
@@ -174,6 +174,9 @@
 #endif
 
 extern struct inode_operations umsdos_dir_inode_operations;
+extern struct inode_operations umsdos_rdir_inode_operations;
+extern struct file_operations umsdos_dir_operations;
+extern struct file_operations umsdos_rdir_operations;
 extern int init_umsdos_fs (void);
 
 #include <linux/umsdos_fs.p>
diff -u --recursive --new-file v2.3.47/linux/include/linux/wait.h linux/include/linux/wait.h
--- v2.3.47/linux/include/linux/wait.h	Fri Sep 10 23:57:37 1999
+++ linux/include/linux/wait.h	Sat Feb 26 20:45:58 2000
@@ -4,6 +4,7 @@
 #define WNOHANG		0x00000001
 #define WUNTRACED	0x00000002
 
+#define __WALL		0x40000000
 #define __WCLONE	0x80000000
 
 #ifdef __KERNEL__
diff -u --recursive --new-file v2.3.47/linux/include/net/atmclip.h linux/include/net/atmclip.h
--- v2.3.47/linux/include/net/atmclip.h	Thu Feb 10 17:11:22 2000
+++ linux/include/net/atmclip.h	Sat Feb 26 20:55:41 2000
@@ -1,6 +1,6 @@
 /* net/atm/atmarp.h - RFC1577 ATM ARP */
  
-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */
+/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
  
  
 #ifndef _ATMCLIP_H
@@ -11,6 +11,7 @@
 #include <linux/atm.h>
 #include <linux/atmdev.h>
 #include <linux/atmarp.h>
+#include <linux/spinlock.h>
 #include <net/neighbour.h>
 
 
@@ -22,6 +23,7 @@
 	struct atm_vcc	*vcc;		/* VCC descriptor */
 	struct atmarp_entry *entry;	/* ATMARP table entry, NULL if IP addr.
 					   isn't known yet */
+	int		xoff;		/* 1 if send buffer is full */
 	unsigned char	encap;		/* 0: NULL, 1: LLC/SNAP */
 	unsigned long	last_use;	/* last send or receive operation */
 	unsigned long	idle_timeout;	/* keep open idle for so many jiffies*/
@@ -48,8 +50,9 @@
 struct clip_priv {
 	char name[8];			/* interface name */
 	int number;			/* for convenience ... */
+	spinlock_t xoff_lock;		/* ensures that pop is atomic (SMP) */
 	struct net_device_stats stats;
-	struct net_device *next;		/* next CLIP interface */
+	struct net_device *next;	/* next CLIP interface */
 };
 
 
diff -u --recursive --new-file v2.3.47/linux/include/net/tcp.h linux/include/net/tcp.h
--- v2.3.47/linux/include/net/tcp.h	Thu Feb 10 17:11:23 2000
+++ linux/include/net/tcp.h	Sat Feb 26 20:54:52 2000
@@ -339,7 +339,7 @@
 
 #if HZ == 20
 # define TCP_TW_RECYCLE_TICK (5+2-TCP_TW_RECYCLE_SLOTS_LOG)
-#elif HZ == 100
+#elif HZ == 100 || HZ == 128
 # define TCP_TW_RECYCLE_TICK (7+2-TCP_TW_RECYCLE_SLOTS_LOG)
 #elif HZ == 1024
 # define TCP_TW_RECYCLE_TICK (10+2-TCP_TW_RECYCLE_SLOTS_LOG)
diff -u --recursive --new-file v2.3.47/linux/include/video/newport.h linux/include/video/newport.h
--- v2.3.47/linux/include/video/newport.h	Wed Dec 31 16:00:00 1969
+++ linux/include/video/newport.h	Fri Feb 25 10:30:57 2000
@@ -0,0 +1,596 @@
+/* $Id: newport.h,v 1.5 1999/08/04 06:01:51 ulfc Exp $
+ *
+ * newport.h: Defines and register layout for NEWPORT graphics
+ *            hardware.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * 
+ * Ulf Carlsson - Compability with the IRIX structures added
+ */
+
+#ifndef _SGI_NEWPORT_H
+#define _SGI_NEWPORT_H
+
+
+typedef volatile unsigned int npireg_t;
+
+union npfloat {
+	volatile float flt;
+	npireg_t       word;
+};
+
+typedef union npfloat npfreg_t;
+
+union np_dcb {
+	npireg_t byword;
+	struct { volatile unsigned short s0, s1; } byshort;
+	struct { volatile unsigned char b0, b1, b2, b3; } bybytes;
+};
+
+struct newport_rexregs {
+	npireg_t drawmode1;      /* GL extra mode bits */
+	
+#define DM1_PLANES         0x00000007
+#define    DM1_NOPLANES    0x00000000
+#define    DM1_RGBPLANES   0x00000001
+#define    DM1_RGBAPLANES  0x00000002
+#define    DM1_OLAYPLANES  0x00000004
+#define    DM1_PUPPLANES   0x00000005
+#define    DM1_CIDPLANES   0x00000006
+	
+#define NPORT_DMODE1_DDMASK      0x00000018
+#define NPORT_DMODE1_DD4         0x00000000
+#define NPORT_DMODE1_DD8         0x00000008
+#define NPORT_DMODE1_DD12        0x00000010
+#define NPORT_DMODE1_DD24        0x00000018
+#define NPORT_DMODE1_DSRC        0x00000020
+#define NPORT_DMODE1_YFLIP       0x00000040
+#define NPORT_DMODE1_RWPCKD      0x00000080
+#define NPORT_DMODE1_HDMASK      0x00000300
+#define NPORT_DMODE1_HD4         0x00000000
+#define NPORT_DMODE1_HD8         0x00000100
+#define NPORT_DMODE1_HD12        0x00000200
+#define NPORT_DMODE1_HD32        0x00000300
+#define NPORT_DMODE1_RWDBL       0x00000400
+#define NPORT_DMODE1_ESWAP       0x00000800 /* Endian swap */
+#define NPORT_DMODE1_CCMASK      0x00007000
+#define NPORT_DMODE1_CCLT        0x00001000
+#define NPORT_DMODE1_CCEQ        0x00002000
+#define NPORT_DMODE1_CCGT        0x00004000
+#define NPORT_DMODE1_RGBMD       0x00008000
+#define NPORT_DMODE1_DENAB       0x00010000 /* Dither enable */
+#define NPORT_DMODE1_FCLR        0x00020000 /* Fast clear */
+#define NPORT_DMODE1_BENAB       0x00040000 /* Blend enable */
+#define NPORT_DMODE1_SFMASK      0x00380000
+#define NPORT_DMODE1_SF0         0x00000000
+#define NPORT_DMODE1_SF1         0x00080000
+#define NPORT_DMODE1_SFDC        0x00100000
+#define NPORT_DMODE1_SFMDC       0x00180000
+#define NPORT_DMODE1_SFSA        0x00200000
+#define NPORT_DMODE1_SFMSA       0x00280000
+#define NPORT_DMODE1_DFMASK      0x01c00000
+#define NPORT_DMODE1_DF0         0x00000000
+#define NPORT_DMODE1_DF1         0x00400000
+#define NPORT_DMODE1_DFSC        0x00800000
+#define NPORT_DMODE1_DFMSC       0x00c00000
+#define NPORT_DMODE1_DFSA        0x01000000
+#define NPORT_DMODE1_DFMSA       0x01400000
+#define NPORT_DMODE1_BBENAB      0x02000000 /* Back blend enable */
+#define NPORT_DMODE1_PFENAB      0x04000000 /* Pre-fetch enable */
+#define NPORT_DMODE1_ABLEND      0x08000000 /* Alpha blend */
+#define NPORT_DMODE1_LOMASK      0xf0000000
+#define NPORT_DMODE1_LOZERO      0x00000000
+#define NPORT_DMODE1_LOAND       0x10000000
+#define NPORT_DMODE1_LOANDR      0x20000000
+#define NPORT_DMODE1_LOSRC       0x30000000
+#define NPORT_DMODE1_LOANDI      0x40000000
+#define NPORT_DMODE1_LODST       0x50000000
+#define NPORT_DMODE1_LOXOR       0x60000000
+#define NPORT_DMODE1_LOOR        0x70000000
+#define NPORT_DMODE1_LONOR       0x80000000
+#define NPORT_DMODE1_LOXNOR      0x90000000
+#define NPORT_DMODE1_LONDST      0xa0000000
+#define NPORT_DMODE1_LOORR       0xb0000000
+#define NPORT_DMODE1_LONSRC      0xc0000000
+#define NPORT_DMODE1_LOORI       0xd0000000
+#define NPORT_DMODE1_LONAND      0xe0000000
+#define NPORT_DMODE1_LOONE       0xf0000000
+
+	npireg_t drawmode0;      /* REX command register */
+
+	/* These bits define the graphics opcode being performed. */
+#define NPORT_DMODE0_OPMASK   0x00000003 /* Opcode mask */
+#define NPORT_DMODE0_NOP      0x00000000 /* No operation */
+#define NPORT_DMODE0_RD       0x00000001 /* Read operation */
+#define NPORT_DMODE0_DRAW     0x00000002 /* Draw operation */
+#define NPORT_DMODE0_S2S      0x00000003 /* Screen to screen operation */
+
+	/* The following decide what addressing mode(s) are to be used */
+#define NPORT_DMODE0_AMMASK   0x0000001c /* Address mode mask */
+#define NPORT_DMODE0_SPAN     0x00000000 /* Spanning address mode */
+#define NPORT_DMODE0_BLOCK    0x00000004 /* Block address mode */
+#define NPORT_DMODE0_ILINE    0x00000008 /* Iline address mode */
+#define NPORT_DMODE0_FLINE    0x0000000c /* Fline address mode */
+#define NPORT_DMODE0_ALINE    0x00000010 /* Aline address mode */
+#define NPORT_DMODE0_TLINE    0x00000014 /* Tline address mode */
+#define NPORT_DMODE0_BLINE    0x00000018 /* Bline address mode */
+
+	/* And now some misc. operation control bits. */
+#define NPORT_DMODE0_DOSETUP  0x00000020
+#define NPORT_DMODE0_CHOST    0x00000040
+#define NPORT_DMODE0_AHOST    0x00000080
+#define NPORT_DMODE0_STOPX    0x00000100
+#define NPORT_DMODE0_STOPY    0x00000200
+#define NPORT_DMODE0_SK1ST    0x00000400
+#define NPORT_DMODE0_SKLST    0x00000800
+#define NPORT_DMODE0_ZPENAB   0x00001000
+#define NPORT_DMODE0_LISPENAB 0x00002000
+#define NPORT_DMODE0_LISLST   0x00004000
+#define NPORT_DMODE0_L32      0x00008000
+#define NPORT_DMODE0_ZOPQ     0x00010000
+#define NPORT_DMODE0_LISOPQ   0x00020000
+#define NPORT_DMODE0_SHADE    0x00040000
+#define NPORT_DMODE0_LRONLY   0x00080000
+#define NPORT_DMODE0_XYOFF    0x00100000
+#define NPORT_DMODE0_CLAMP    0x00200000
+#define NPORT_DMODE0_ENDPF    0x00400000
+#define NPORT_DMODE0_YSTR     0x00800000
+
+	npireg_t lsmode;      /* Mode for line stipple ops */
+	npireg_t lspattern;   /* Pattern for line stipple ops */
+	npireg_t lspatsave;   /* Backup save pattern */
+	npireg_t zpattern;    /* Pixel zpattern */
+	npireg_t colorback;   /* Background color */
+	npireg_t colorvram;   /* Clear color for fast vram */
+	npireg_t alpharef;    /* Reference value for afunctions */
+	unsigned int pad0;
+	npireg_t smask0x;     /* Window GL relative screen mask 0 */
+	npireg_t smask0y;     /* Window GL relative screen mask 0 */
+	npireg_t _setup;
+	npireg_t _stepz;
+	npireg_t _lsrestore;
+	npireg_t _lssave;
+
+	unsigned int _pad1[0x30];
+
+	/* Iterators, full state for context switch */
+	npfreg_t _xstart;	/* X-start point (current) */
+	npfreg_t _ystart;	/* Y-start point (current) */
+	npfreg_t _xend;		/* x-end point */
+	npfreg_t _yend;		/* y-end point */
+	npireg_t xsave;		/* copy of xstart integer value for BLOCk addressing MODE */
+	npireg_t xymove;	/* x.y offset from xstart, ystart for relative operations */
+	npfreg_t bresd;
+	npfreg_t bress1;
+	npireg_t bresoctinc1;
+	volatile int bresrndinc2;
+	npireg_t brese1;
+	npireg_t bress2;
+	npireg_t aweight0;
+	npireg_t aweight1;
+	npfreg_t xstartf;
+	npfreg_t ystartf;
+	npfreg_t xendf;
+	npfreg_t yendf;
+	npireg_t xstarti;
+	npfreg_t xendf1;
+	npireg_t xystarti;
+	npireg_t xyendi;
+	npireg_t xstartendi;
+
+	unsigned int _unused2[0x29];
+
+	npfreg_t colorred;
+	npfreg_t coloralpha;
+	npfreg_t colorgrn;
+	npfreg_t colorblue;
+	npfreg_t slopered;
+	npfreg_t slopealpha;
+	npfreg_t slopegrn;
+	npfreg_t slopeblue;
+	npireg_t wrmask;
+	npireg_t colori;
+	npfreg_t colorx;
+	npfreg_t slopered1;
+	npireg_t hostrw0;
+	npireg_t hostrw1;
+	npireg_t dcbmode;
+#define NPORT_DMODE_WMASK   0x00000003
+#define NPORT_DMODE_W4      0x00000000
+#define NPORT_DMODE_W1      0x00000001
+#define NPORT_DMODE_W2      0x00000002
+#define NPORT_DMODE_W3      0x00000003
+#define NPORT_DMODE_EDPACK  0x00000004
+#define NPORT_DMODE_ECINC   0x00000008
+#define NPORT_DMODE_CMASK   0x00000070
+#define NPORT_DMODE_AMASK   0x00000780
+#define NPORT_DMODE_AVC2    0x00000000
+#define NPORT_DMODE_ACMALL  0x00000080
+#define NPORT_DMODE_ACM0    0x00000100
+#define NPORT_DMODE_ACM1    0x00000180
+#define NPORT_DMODE_AXMALL  0x00000200
+#define NPORT_DMODE_AXM0    0x00000280
+#define NPORT_DMODE_AXM1    0x00000300
+#define NPORT_DMODE_ABT     0x00000380
+#define NPORT_DMODE_AVCC1   0x00000400
+#define NPORT_DMODE_AVAB1   0x00000480
+#define NPORT_DMODE_ALG3V0  0x00000500
+#define NPORT_DMODE_A1562   0x00000580
+#define NPORT_DMODE_ESACK   0x00000800
+#define NPORT_DMODE_EASACK  0x00001000
+#define NPORT_DMODE_CWMASK  0x0003e000
+#define NPORT_DMODE_CHMASK  0x007c0000
+#define NPORT_DMODE_CSMASK  0x0f800000
+#define NPORT_DMODE_SENDIAN 0x10000000
+
+	unsigned int _unused3;
+
+	union np_dcb dcbdata0;
+	npireg_t dcbdata1;
+};
+
+struct newport_cregs {
+	npireg_t smask1x;
+	npireg_t smask1y;
+	npireg_t smask2x;
+	npireg_t smask2y;
+	npireg_t smask3x;
+	npireg_t smask3y;
+	npireg_t smask4x;
+	npireg_t smask4y;
+	npireg_t topscan;
+	npireg_t xywin;
+	npireg_t clipmode;
+#define NPORT_CMODE_SM0   0x00000001
+#define NPORT_CMODE_SM1   0x00000002
+#define NPORT_CMODE_SM2   0x00000004
+#define NPORT_CMODE_SM3   0x00000008
+#define NPORT_CMODE_SM4   0x00000010
+#define NPORT_CMODE_CMSK  0x00001e00
+
+	unsigned int _unused0;
+	unsigned int config;
+#define NPORT_CFG_G32MD   0x00000001
+#define NPORT_CFG_BWIDTH  0x00000002
+#define NPORT_CFG_ERCVR   0x00000004
+#define NPORT_CFG_BDMSK   0x00000078
+#define NPORT_CFG_BFAINT  0x00000080
+#define NPORT_CFG_GDMSK   0x00001f80
+#define NPORT_CFG_GD0     0x00000100
+#define NPORT_CFG_GD1     0x00000200
+#define NPORT_CFG_GD2     0x00000400
+#define NPORT_CFG_GD3     0x00000800
+#define NPORT_CFG_GD4     0x00001000
+#define NPORT_CFG_GFAINT  0x00002000
+#define NPORT_CFG_TOMSK   0x0001c000
+#define NPORT_CFG_VRMSK   0x000e0000
+#define NPORT_CFG_FBTYP   0x00100000
+
+	npireg_t _unused1;
+	npireg_t status;
+#define NPORT_STAT_VERS   0x00000007
+#define NPORT_STAT_GBUSY  0x00000008
+#define NPORT_STAT_BBUSY  0x00000010
+#define NPORT_STAT_VRINT  0x00000020
+#define NPORT_STAT_VIDINT 0x00000040
+#define NPORT_STAT_GLMSK  0x00001f80
+#define NPORT_STAT_BLMSK  0x0007e000
+#define NPORT_STAT_BFIRQ  0x00080000
+#define NPORT_STAT_GFIRQ  0x00100000
+
+	npireg_t ustatus;
+	npireg_t dcbreset;
+};
+
+struct newport_regs {
+	struct newport_rexregs set;
+	unsigned int _unused0[0x16e];
+	struct newport_rexregs go;
+	unsigned int _unused1[0x22e];
+	struct newport_cregs cset;
+	unsigned int _unused2[0x1ef];
+	struct newport_cregs cgo;
+};
+extern struct newport_regs *npregs;
+
+
+typedef struct {
+	unsigned int drawmode1;
+	unsigned int drawmode0;
+	unsigned int lsmode;   
+	unsigned int lspattern;
+	unsigned int lspatsave;
+	unsigned int zpattern; 
+	unsigned int colorback;
+	unsigned int colorvram;
+	unsigned int alpharef; 
+	unsigned int smask0x;  
+	unsigned int smask0y;  
+	unsigned int _xstart;  
+	unsigned int _ystart;  
+	unsigned int _xend;    
+	unsigned int _yend;    
+	unsigned int xsave;    
+	unsigned int xymove;   
+	unsigned int bresd;    
+	unsigned int bress1;   
+	unsigned int bresoctinc1;
+	unsigned int bresrndinc2;
+	unsigned int brese1;     
+	unsigned int bress2;     
+	
+	unsigned int aweight0;    
+	unsigned int aweight1;    
+	unsigned int colorred;    
+	unsigned int coloralpha;  
+	unsigned int colorgrn;    
+	unsigned int colorblue;   
+	unsigned int slopered;    
+	unsigned int slopealpha;  
+	unsigned int slopegrn;    
+	unsigned int slopeblue;   
+	unsigned int wrmask;      
+	unsigned int hostrw0;     
+	unsigned int hostrw1;     
+	
+        /* configregs */
+	
+	unsigned int smask1x;    
+	unsigned int smask1y;    
+	unsigned int smask2x;    
+	unsigned int smask2y;    
+	unsigned int smask3x;    
+	unsigned int smask3y;    
+	unsigned int smask4x;    
+	unsigned int smask4y;    
+	unsigned int topscan;    
+	unsigned int xywin;      
+	unsigned int clipmode;   
+	unsigned int config;     
+	
+        /* dcb registers */
+	unsigned int dcbmode;   
+	unsigned int dcbdata0;  
+	unsigned int dcbdata1;
+} newport_ctx;
+
+/* Reading/writing VC2 registers. */
+#define VC2_REGADDR_INDEX      0x00000000
+#define VC2_REGADDR_IREG       0x00000010
+#define VC2_REGADDR_RAM        0x00000030
+#define VC2_PROTOCOL           (NPORT_DMODE_EASACK | 0x00800000 | 0x00040000)
+
+#define VC2_VLINET_ADDR        0x000
+#define VC2_VFRAMET_ADDR       0x400
+#define VC2_CGLYPH_ADDR        0x500
+
+/* Now the Indexed registers of the VC2. */
+#define VC2_IREG_VENTRY        0x00
+#define VC2_IREG_CENTRY        0x01
+#define VC2_IREG_CURSX         0x02
+#define VC2_IREG_CURSY         0x03
+#define VC2_IREG_CCURSX        0x04
+#define VC2_IREG_DENTRY        0x05
+#define VC2_IREG_SLEN          0x06
+#define VC2_IREG_RADDR         0x07
+#define VC2_IREG_VFPTR         0x08
+#define VC2_IREG_VLSPTR        0x09
+#define VC2_IREG_VLIR          0x0a
+#define VC2_IREG_VLCTR         0x0b
+#define VC2_IREG_CTPTR         0x0c
+#define VC2_IREG_WCURSY        0x0d
+#define VC2_IREG_DFPTR         0x0e
+#define VC2_IREG_DLTPTR        0x0f
+#define VC2_IREG_CONTROL       0x10
+#define VC2_IREG_CONFIG        0x20
+
+extern __inline__ void newport_vc2_set(struct newport_regs *regs, unsigned char vc2ireg,
+				   unsigned short val)
+{
+	regs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_INDEX | NPORT_DMODE_W3 |
+			   NPORT_DMODE_ECINC | VC2_PROTOCOL);
+	regs->set.dcbdata0.byword = (vc2ireg << 24) | (val << 8);
+}
+
+extern __inline__ unsigned short newport_vc2_get(struct newport_regs *regs,
+					     unsigned char vc2ireg)
+{
+	regs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_INDEX | NPORT_DMODE_W1 |
+			   NPORT_DMODE_ECINC | VC2_PROTOCOL);
+	regs->set.dcbdata0.bybytes.b3 = vc2ireg;
+	regs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_IREG | NPORT_DMODE_W2 |
+			   NPORT_DMODE_ECINC | VC2_PROTOCOL);
+	return regs->set.dcbdata0.byshort.s1;
+}
+
+/* VC2 Control register bits */
+#define VC2_CTRL_EVIRQ     0x0001
+#define VC2_CTRL_EDISP     0x0002
+#define VC2_CTRL_EVIDEO    0x0004
+#define VC2_CTRL_EDIDS     0x0008
+#define VC2_CTRL_ECURS     0x0010
+#define VC2_CTRL_EGSYNC    0x0020
+#define VC2_CTRL_EILACE    0x0040
+#define VC2_CTRL_ECDISP    0x0080
+#define VC2_CTRL_ECCURS    0x0100
+#define VC2_CTRL_ECG64     0x0200
+#define VC2_CTRL_GLSEL     0x0400
+
+/* Controlling the color map on NEWPORT. */
+#define NCMAP_REGADDR_AREG   0x00000000
+#define NCMAP_REGADDR_ALO    0x00000000
+#define NCMAP_REGADDR_AHI    0x00000010
+#define NCMAP_REGADDR_PBUF   0x00000020
+#define NCMAP_REGADDR_CREG   0x00000030
+#define NCMAP_REGADDR_SREG   0x00000040
+#define NCMAP_REGADDR_RREG   0x00000060
+#define NCMAP_PROTOCOL       (0x00008000 | 0x00040000 | 0x00800000)
+
+static __inline__ void newport_cmap_setaddr(struct newport_regs *regs,
+					unsigned short addr)
+{
+	regs->set.dcbmode = (NPORT_DMODE_ACMALL | NCMAP_PROTOCOL |
+			   NPORT_DMODE_SENDIAN | NPORT_DMODE_ECINC |
+			   NCMAP_REGADDR_AREG | NPORT_DMODE_W2);
+	regs->set.dcbdata0.byshort.s1 = addr;
+	regs->set.dcbmode = (NPORT_DMODE_ACMALL | NCMAP_PROTOCOL |
+			   NCMAP_REGADDR_PBUF | NPORT_DMODE_W3);
+}
+
+static __inline__ void newport_cmap_setrgb(struct newport_regs *regs,
+				       unsigned char red,
+				       unsigned char green,
+				       unsigned char blue)
+{
+	regs->set.dcbdata0.byword =
+		(red << 24) |
+		(green << 16) |
+		(blue << 8);
+}
+
+/* Miscellaneous NEWPORT routines. */
+#define BUSY_TIMEOUT 100000
+static __inline__ int newport_wait(void)
+{
+	int i = 0;
+
+	while(i < BUSY_TIMEOUT)
+		if(!(npregs->cset.status & NPORT_STAT_GBUSY))
+			break;
+	if(i == BUSY_TIMEOUT)
+		return 1;
+	return 0;
+}
+
+static __inline__ int newport_bfwait(void)
+{
+	int i = 0;
+
+	while(i < BUSY_TIMEOUT)
+		if(!(npregs->cset.status & NPORT_STAT_BBUSY))
+			break;
+	if(i == BUSY_TIMEOUT)
+		return 1;
+	return 0;
+}
+
+/* newport.c and cons_newport.c routines */
+extern struct graphics_ops *newport_probe (int, const char **);
+
+void newport_save    (void *);
+void newport_restore (void *);
+void newport_reset   (void);
+int  newport_ioctl   (int card, int cmd, unsigned long arg);
+
+/*
+ * DCBMODE register defines:
+ */
+
+/* Widht of the data being transfered for each DCBDATA[01] word */
+#define DCB_DATAWIDTH_4 0x0
+#define DCB_DATAWIDTH_1 0x1
+#define DCB_DATAWIDTH_2 0x2
+#define DCB_DATAWIDTH_3 0x3
+
+/* If set, all of DCBDATA will be moved, otherwise only DATAWIDTH bytes */
+#define DCB_ENDATAPACK   (1 << 2)
+
+/* Enables DCBCRS auto increment after each DCB transfer */
+#define DCB_ENCRSINC     (1 << 3)
+
+/* shift for accessing the control register select address (DBCCRS, 3 bits) */
+#define DCB_CRS_SHIFT    4
+
+/* DCBADDR (4 bits): display bus slave address */
+#define DCB_ADDR_SHIFT   7
+#define DCB_VC2          (0 <<  DCB_ADDR_SHIFT)
+#define DCB_CMAP_ALL     (1 <<  DCB_ADDR_SHIFT)
+#define DCB_CMAP0        (2 <<  DCB_ADDR_SHIFT)
+#define DCB_CMAP1        (3 <<  DCB_ADDR_SHIFT)
+#define DCB_XMAP_ALL     (4 <<  DCB_ADDR_SHIFT)
+#define DCB_XMAP0        (5 <<  DCB_ADDR_SHIFT)
+#define DCB_XMAP1        (6 <<  DCB_ADDR_SHIFT)
+#define DCB_BT445        (7 <<  DCB_ADDR_SHIFT)
+#define DCB_VCC1         (8 <<  DCB_ADDR_SHIFT)
+#define DCB_VAB1         (9 <<  DCB_ADDR_SHIFT)
+#define DCB_LG3_BDVERS0  (10 << DCB_ADDR_SHIFT)
+#define DCB_LG3_ICS1562  (11 << DCB_ADDR_SHIFT)
+#define DCB_RESERVED     (15 << DCB_ADDR_SHIFT)
+
+/* DCB protocol ack types */
+#define DCB_ENSYNCACK    (1 << 11)
+#define DCB_ENASYNCACK   (1 << 12)
+
+#define DCB_CSWIDTH_SHIFT 13
+#define DCB_CSHOLD_SHIFT  18
+#define DCB_CSSETUP_SHIFT 23
+
+/* XMAP9 specific defines */
+/*   XMAP9 -- registers as seen on the DCBMODE register*/
+#   define XM9_CRS_CONFIG            (0 << DCB_CRS_SHIFT)
+#       define XM9_PUPMODE           (1 << 0)
+#       define XM9_ODD_PIXEL         (1 << 1)
+#       define XM9_8_BITPLANES       (1 << 2)
+#       define XM9_SLOW_DCB          (1 << 3)
+#       define XM9_VIDEO_RGBMAP_MASK (3 << 4)
+#       define XM9_EXPRESS_VIDEO     (1 << 6)
+#       define XM9_VIDEO_OPTION      (1 << 7)
+#   define XM9_CRS_REVISION          (1 << DCB_CRS_SHIFT)
+#   define XM9_CRS_FIFO_AVAIL        (2 << DCB_CRS_SHIFT)
+#       define XM9_FIFO_0_AVAIL      0
+#       define XM9_FIFO_1_AVAIL      1
+#       define XM9_FIFO_2_AVAIL      3
+#       define XM9_FIFO_3_AVAIL      2
+#       define XM9_FIFO_FULL         XM9_FIFO_0_AVAIL
+#       define XM9_FIFO_EMPTY        XM9_FIFO_3_AVAIL
+#   define XM9_CRS_CURS_CMAP_MSB     (3 << DCB_CRS_SHIFT)
+#   define XM9_CRS_PUP_CMAP_MSB      (4 << DCB_CRS_SHIFT)
+#   define XM9_CRS_MODE_REG_DATA     (5 << DCB_CRS_SHIFT)
+#   define XM9_CRS_MODE_REG_INDEX    (7 << DCB_CRS_SHIFT)
+
+
+#define DCB_CYCLES(setup,hold,width)                \
+                  ((hold << DCB_CSHOLD_SHIFT)  |    \
+		   (setup << DCB_CSSETUP_SHIFT)|    \
+		   (width << DCB_CSWIDTH_SHIFT))
+
+#define W_DCB_XMAP9_PROTOCOL       DCB_CYCLES (2, 1, 0)
+#define WSLOW_DCB_XMAP9_PROTOCOL   DCB_CYCLES (5, 5, 0)
+#define WAYSLOW_DCB_XMAP9_PROTOCOL DCB_CYCLES (12, 12, 0)
+#define R_DCB_XMAP9_PROTOCOL       DCB_CYCLES (2, 1, 3)
+
+static __inline__ void
+xmap9FIFOWait (struct newport_regs *rex)
+{
+        rex->set.dcbmode = DCB_XMAP0 | XM9_CRS_FIFO_AVAIL |
+		DCB_DATAWIDTH_1 | R_DCB_XMAP9_PROTOCOL;
+        newport_bfwait ();
+	
+        while ((rex->set.dcbdata0.bybytes.b3 & 3) != XM9_FIFO_EMPTY)
+		;
+}
+
+static __inline__ void
+xmap9SetModeReg (struct newport_regs *rex, unsigned int modereg, unsigned int data24, int cfreq)
+{
+        if (cfreq > 119)
+            rex->set.dcbmode = DCB_XMAP_ALL | XM9_CRS_MODE_REG_DATA |
+                        DCB_DATAWIDTH_4 | W_DCB_XMAP9_PROTOCOL;
+        else if (cfreq > 59)
+            rex->set.dcbmode = DCB_XMAP_ALL | XM9_CRS_MODE_REG_DATA |
+		    DCB_DATAWIDTH_4 | WSLOW_DCB_XMAP9_PROTOCOL;    
+        else
+            rex->set.dcbmode = DCB_XMAP_ALL | XM9_CRS_MODE_REG_DATA |
+                        DCB_DATAWIDTH_4 | WAYSLOW_DCB_XMAP9_PROTOCOL; 
+        rex->set.dcbdata0.byword = ((modereg) << 24) | (data24 & 0xffffff);
+}
+
+#define BT445_PROTOCOL		DCB_CYCLES(1,1,3)
+
+#define BT445_CSR_ADDR_REG	(0 << DCB_CRS_SHIFT)
+#define BT445_CSR_REVISION	(2 << DCB_CRS_SHIFT)
+
+#define BT445_REVISION_REG	0x01
+
+#endif /* !(_SGI_NEWPORT_H) */
+
diff -u --recursive --new-file v2.3.47/linux/init/main.c linux/init/main.c
--- v2.3.47/linux/init/main.c	Wed Feb 16 17:03:52 2000
+++ linux/init/main.c	Fri Feb 25 15:15:54 2000
@@ -481,7 +481,6 @@
 	lock_kernel();
 	printk(linux_banner);
 	setup_arch(&command_line);
-	paging_init();
 	trap_init();
 	init_IRQ();
 	sched_init();
diff -u --recursive --new-file v2.3.47/linux/ipc/shm.c linux/ipc/shm.c
--- v2.3.47/linux/ipc/shm.c	Tue Feb  1 01:35:44 2000
+++ linux/ipc/shm.c	Sat Feb 26 20:23:36 2000
@@ -11,6 +11,7 @@
  * HIGHMEM support, Ingo Molnar <mingo@redhat.com>
  * avoid vmalloc and make shmmax, shmall, shmmni sysctl'able,
  *                         Christoph Rohland <hans-christoph.rohland@sap.com>
+ * Shared /dev/zero support, Kanoj Sarcar <kanoj@sgi.com>
  */
 
 #include <linux/config.h>
@@ -70,6 +71,13 @@
 static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
 #endif
 
+static void zshm_swap (int prio, int gfp_mask, zone_t *zone);
+static void zmap_unuse(swp_entry_t entry, struct page *page);
+static void shmzero_open(struct vm_area_struct *shmd);
+static void shmzero_close(struct vm_area_struct *shmd);
+static int zero_id;
+static struct shmid_kernel zshmid_kernel;
+
 size_t shm_ctlmax = SHMMAX;
 int shm_ctlall = SHMALL;
 int shm_ctlmni = SHMMNI;
@@ -103,6 +111,8 @@
 #ifdef CONFIG_PROC_FS
 	create_proc_read_entry("sysvipc/shm", 0, 0, sysvipc_shm_read_proc, NULL);
 #endif
+	zero_id = ipc_addid(&shm_ids, &zshmid_kernel.shm_perm, shm_ctlmni);
+	shm_unlock(zero_id);
 	return;
 }
 
@@ -179,6 +189,26 @@
 	return 0;
 }
 
+static inline struct shmid_kernel *newseg_alloc(int numpages)
+{
+	struct shmid_kernel *shp;
+
+	shp = (struct shmid_kernel *) kmalloc (sizeof (*shp), GFP_KERNEL);
+	if (!shp)
+		return 0;
+
+	shp->shm_dir = shm_alloc (numpages);
+	if (!shp->shm_dir) {
+		kfree(shp);
+		return 0;
+	}
+	shp->shm_npages = numpages;
+	shp->attaches = NULL;
+	shp->shm_nattch = 0;
+	init_MUTEX(&shp->sem);
+	return(shp);
+}
+
 static int newseg (key_t key, int shmflg, size_t size)
 {
 	struct shmid_kernel *shp;
@@ -193,15 +223,8 @@
 	if (shm_tot + numpages >= shm_ctlall)
 		return -ENOSPC;
 
-	shp = (struct shmid_kernel *) kmalloc (sizeof (*shp), GFP_KERNEL);
-	if (!shp)
-		return -ENOMEM;
-
-	shp->shm_dir = shm_alloc (numpages);
-	if (!shp->shm_dir) {
-		kfree(shp);
+	if (!(shp = newseg_alloc(numpages)))
 		return -ENOMEM;
-	}
 	id = ipc_addid(&shm_ids, &shp->shm_perm, shm_ctlmni);
 	if(id == -1) {
 		shm_free(shp->shm_dir,numpages);
@@ -212,13 +235,10 @@
 	shp->shm_perm.mode = (shmflg & S_IRWXUGO);
 	shp->shm_segsz = size;
 	shp->shm_cpid = current->pid;
-	shp->attaches = NULL;
-	shp->shm_lpid = shp->shm_nattch = 0;
+	shp->shm_lpid = 0;
 	shp->shm_atime = shp->shm_dtime = 0;
 	shp->shm_ctime = CURRENT_TIME;
-	shp->shm_npages = numpages;
 	shp->id = shm_buildid(id,shp->shm_perm.seq);
-	init_MUTEX(&shp->sem);
 
 	shm_tot += numpages;
 	shm_unlock(id);
@@ -255,6 +275,35 @@
 	return err;
 }
 
+static void killseg_core(struct shmid_kernel *shp, int doacc)
+{
+	int i, numpages, rss, swp;
+
+	numpages = shp->shm_npages;
+	for (i = 0, rss = 0, swp = 0; i < numpages ; i++) {
+		pte_t pte;
+		pte = SHM_ENTRY (shp,i);
+		if (pte_none(pte))
+			continue;
+		if (pte_present(pte)) {
+			__free_page (pte_page(pte));
+			rss++;
+		} else {
+			swap_free(pte_to_swp_entry(pte));
+			swp++;
+		}
+	}
+	shm_free (shp->shm_dir, numpages);
+	kfree(shp);
+	if (doacc) {
+		shm_lockall();
+		shm_rss -= rss;
+		shm_swp -= swp;
+		shm_tot -= numpages;
+		shm_unlockall();
+	}
+}
+
 /*
  * Only called after testing nattch and SHM_DEST.
  * Here pages, pgtable and shmid_kernel are freed.
@@ -262,8 +311,6 @@
 static void killseg (int shmid)
 {
 	struct shmid_kernel *shp;
-	int i, numpages;
-	int rss, swp;
 
 	down(&shm_ids.sem);
 	shp = shm_lock(shmid);
@@ -284,28 +331,8 @@
 		BUG();
 	shm_unlock(shmid);
 	up(&shm_ids.sem);
+	killseg_core(shp, 1);
 
-	numpages = shp->shm_npages;
-	for (i = 0, rss = 0, swp = 0; i < numpages ; i++) {
-		pte_t pte;
-		pte = SHM_ENTRY (shp,i);
-		if (pte_none(pte))
-			continue;
-		if (pte_present(pte)) {
-			__free_page (pte_page(pte));
-			rss++;
-		} else {
-			swap_free(pte_to_swp_entry(pte));
-			swp++;
-		}
-	}
-	shm_free (shp->shm_dir, numpages);
-	kfree(shp);
-	shm_lockall();
-	shm_rss -= rss;
-	shm_swp -= swp;
-	shm_tot -= numpages;
-	shm_unlockall();
 	return;
 }
 
@@ -458,6 +485,10 @@
 		shp = shm_lock(shmid);
 		if(shp==NULL)
 			return -EINVAL;
+		if (shp == &zshmid_kernel) {
+			shm_unlock(shmid);
+			return -EINVAL;
+		}
 		if(cmd==SHM_STAT) {
 			err = -EINVAL;
 			if (shmid > shm_ids.max_id)
@@ -498,6 +529,10 @@
 		shp = shm_lock(shmid);
 		if(shp==NULL)
 			return -EINVAL;
+		if (shp == &zshmid_kernel) {
+			shm_unlock(shmid);
+			return -EINVAL;
+		}
 		err=-EIDRM;
 		if(shm_checkid(shp,shmid))
 			goto out_unlock;
@@ -532,6 +567,8 @@
 	err=-EINVAL;
 	if(shp==NULL)
 		goto out_up;
+	if (shp == &zshmid_kernel)
+		goto out_unlock_up;
 	err=-EIDRM;
 	if(shm_checkid(shp,shmid))
 		goto out_unlock_up;
@@ -653,6 +690,8 @@
 	shp = shm_lock(shmid);
 	if (!shp)
 		goto out_up;
+	if (shp == &zshmid_kernel)
+		goto out_unlock_up;
 
 	err = -EACCES;
 	if (ipcperms(&shp->shm_perm, flg))
@@ -835,10 +874,12 @@
 	struct shmid_kernel *shp;
 	unsigned int idx;
 	struct page * page;
+	int is_shmzero;
 
 	shp = (struct shmid_kernel *) shmd->vm_private_data;
 	idx = (address - shmd->vm_start) >> PAGE_SHIFT;
 	idx += shmd->vm_pgoff;
+	is_shmzero = (shp->id == zero_id);
 
 	/*
 	 * A shared mapping past the last page of the file is an error
@@ -850,7 +891,7 @@
 		return NULL;
 	}
 	down(&shp->sem);
-	if(shp != shm_lock(shp->id))
+	if ((shp != shm_lock(shp->id)) && (is_shmzero == 0))
 		BUG();
 
 	pte = SHM_ENTRY(shp,idx);
@@ -864,7 +905,7 @@
 			if (!page)
 				goto oom;
 			clear_highpage(page);
-			if(shp != shm_lock(shp->id))
+			if ((shp != shm_lock(shp->id)) && (is_shmzero == 0))
 				BUG();
 		} else {
 			swp_entry_t entry = pte_to_swp_entry(pte);
@@ -882,11 +923,11 @@
 			delete_from_swap_cache(page);
 			page = replace_with_highmem(page);
 			swap_free(entry);
-			if(shp != shm_lock(shp->id))
+			if ((shp != shm_lock(shp->id)) && (is_shmzero == 0))
 				BUG();
-			shm_swp--;
+			if (is_shmzero) shm_swp--;
 		}
-		shm_rss++;
+		if (is_shmzero) shm_rss++;
 		pte = pte_mkdirty(mk_pte(page, PAGE_SHARED));
 		SHM_ENTRY(shp, idx) = pte;
 	} else
@@ -904,6 +945,65 @@
 	return NOPAGE_OOM;
 }
 
+#define OKAY	0
+#define RETRY	1
+#define FAILED	2
+
+static int shm_swap_core(struct shmid_kernel *shp, unsigned long idx, swp_entry_t swap_entry, zone_t *zone, int *counter, struct page **outpage)
+{
+	pte_t page;
+	struct page *page_map;
+
+	page = SHM_ENTRY(shp, idx);
+	if (!pte_present(page))
+		return RETRY;
+	page_map = pte_page(page);
+	if (zone && (!memclass(page_map->zone, zone)))
+		return RETRY;
+	if (shp->id != zero_id) swap_attempts++;
+
+	if (--counter < 0) /* failed */
+		return FAILED;
+	if (page_count(page_map) != 1)
+		return RETRY;
+
+	if (!(page_map = prepare_highmem_swapout(page_map)))
+		return FAILED;
+	SHM_ENTRY (shp, idx) = swp_entry_to_pte(swap_entry);
+
+	/* add the locked page to the swap cache before allowing
+	   the swapin path to run lookup_swap_cache(). This avoids
+	   reading a not yet uptodate block from disk.
+	   NOTE: we just accounted the swap space reference for this
+	   swap cache page at __get_swap_page() time. */
+	add_to_swap_cache(*outpage = page_map, swap_entry);
+	return OKAY;
+}
+
+static void shm_swap_postop(struct page *page)
+{
+	lock_kernel();
+	rw_swap_page(WRITE, page, 0);
+	unlock_kernel();
+	__free_page(page);
+}
+
+static int shm_swap_preop(swp_entry_t *swap_entry)
+{
+	lock_kernel();
+	/* subtle: preload the swap count for the swap cache. We can't
+	   increase the count inside the critical section as we can't release
+	   the shm_lock there. And we can't acquire the big lock with the
+	   shm_lock held (otherwise we would deadlock too easily). */
+	*swap_entry = __get_swap_page(2);
+	if (!(*swap_entry).val) {
+		unlock_kernel();
+		return 1;
+	}
+	unlock_kernel();
+	return 0;
+}
+
 /*
  * Goes through counter = (shm_rss >> prio) present shm pages.
  */
@@ -912,28 +1012,19 @@
 
 int shm_swap (int prio, int gfp_mask, zone_t *zone)
 {
-	pte_t page;
 	struct shmid_kernel *shp;
 	swp_entry_t swap_entry;
 	unsigned long id, idx;
 	int loop = 0;
 	int counter;
 	struct page * page_map;
-	
+
+	zshm_swap(prio, gfp_mask, zone);
 	counter = shm_rss >> prio;
 	if (!counter)
 		return 0;
-	lock_kernel();
-	/* subtle: preload the swap count for the swap cache. We can't
-	   increase the count inside the critical section as we can't release
-	   the shm_lock there. And we can't acquire the big lock with the
-	   shm_lock held (otherwise we would deadlock too easily). */
-	swap_entry = __get_swap_page(2);
-	if (!swap_entry.val) {
-		unlock_kernel();
+	if (shm_swap_preop(&swap_entry))
 		return 0;
-	}
-	unlock_kernel();
 
 	shm_lockall();
 check_id:
@@ -943,8 +1034,12 @@
 		swap_idx = 0;
 		if (++swap_id > shm_ids.max_id) {
 			swap_id = 0;
-			if (loop)
-				goto failed;
+			if (loop) {
+failed:
+				shm_unlockall();
+				__swap_free(swap_entry, 2);
+				return 0;
+			}
 			loop = 1;
 		}
 		goto check_id;
@@ -956,43 +1051,16 @@
 	if (idx >= shp->shm_npages)
 		goto next_id;
 
-	page = SHM_ENTRY(shp, idx);
-	if (!pte_present(page))
-		goto check_table;
-	page_map = pte_page(page);
-	if (zone && (!memclass(page_map->zone, zone)))
-		goto check_table;
-	swap_attempts++;
-
-	if (--counter < 0) { /* failed */
-failed:
-		shm_unlockall();
-		__swap_free(swap_entry, 2);
-		return 0;
+	switch (shm_swap_core(shp, idx, swap_entry, zone, &counter, &page_map)) {
+		case RETRY: goto check_table;
+		case FAILED: goto failed;
 	}
-	if (page_count(page_map) != 1)
-		goto check_table;
-
-	if (!(page_map = prepare_highmem_swapout(page_map)))
-		goto failed;
-	SHM_ENTRY (shp, idx) = swp_entry_to_pte(swap_entry);
 	swap_successes++;
 	shm_swp++;
 	shm_rss--;
-
-	/* add the locked page to the swap cache before allowing
-	   the swapin path to run lookup_swap_cache(). This avoids
-	   reading a not yet uptodate block from disk.
-	   NOTE: we just accounted the swap space reference for this
-	   swap cache page at __get_swap_page() time. */
-	add_to_swap_cache(page_map, swap_entry);
 	shm_unlockall();
 
-	lock_kernel();
-	rw_swap_page(WRITE, page_map, 0);
-	unlock_kernel();
-
-	__free_page(page_map);
+	shm_swap_postop(page_map);
 	return 1;
 }
 
@@ -1014,31 +1082,41 @@
 	swap_free(entry);
 }
 
+static int shm_unuse_core(struct shmid_kernel *shp, swp_entry_t entry, struct page *page)
+{
+	int n;
+
+	for (n = 0; n < shp->shm_npages; n++) {
+		if (pte_none(SHM_ENTRY(shp,n)))
+			continue;
+		if (pte_present(SHM_ENTRY(shp,n)))
+			continue;
+		if (pte_to_swp_entry(SHM_ENTRY(shp,n)).val == entry.val) {
+			shm_unuse_page(shp, n, entry, page);
+			return 1;
+		}
+	}
+	return 0;
+}
+
 /*
  * unuse_shm() search for an eventually swapped out shm page.
  */
 void shm_unuse(swp_entry_t entry, struct page *page)
 {
-	int i, n;
+	int i;
 
 	shm_lockall();
 	for (i = 0; i <= shm_ids.max_id; i++) {
 		struct shmid_kernel *shp = shm_get(i);
 		if(shp==NULL)
 			continue;
-		for (n = 0; n < shp->shm_npages; n++) {
-			if (pte_none(SHM_ENTRY(shp,n)))
-				continue;
-			if (pte_present(SHM_ENTRY(shp,n)))
-				continue;
-			if (pte_to_swp_entry(SHM_ENTRY(shp,n)).val == entry.val) {
-				shm_unuse_page(shp, n, entry, page);
-				goto out;
-			}
-		}
+		if (shm_unuse_core(shp, entry, page))
+			goto out;
 	}
 out:
 	shm_unlockall();
+	zmap_unuse(entry, page);
 }
 
 #ifdef CONFIG_PROC_FS
@@ -1053,6 +1131,10 @@
 
     	for(i = 0; i <= shm_ids.max_id; i++) {
 		struct shmid_kernel* shp = shm_lock(i);
+		if (shp == &zshmid_kernel) {
+			shm_unlock(i);
+			continue;
+		}
 		if(shp!=NULL) {
 #define SMALL_STRING "%10d %10d  %4o %10u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
 #define BIG_STRING   "%10d %10d  %4o %21u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
@@ -1100,3 +1182,138 @@
 	return len;
 }
 #endif
+
+static struct shmid_kernel *zmap_list = 0;
+static spinlock_t zmap_list_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long zswap_idx = 0; /* next to swap */
+static struct shmid_kernel *zswap_shp = 0;
+
+static struct vm_operations_struct shmzero_vm_ops = {
+	open:		shmzero_open,
+	close:		shmzero_close,
+	nopage:		shm_nopage,
+	swapout:	shm_swapout,
+};
+
+int map_zero_setup(struct vm_area_struct *vma)
+{
+	struct shmid_kernel *shp;
+
+	if (!(shp = newseg_alloc((vma->vm_end - vma->vm_start) / PAGE_SIZE)))
+		return -ENOMEM;
+	shp->id = zero_id;	/* hack for shm_lock et al */
+	vma->vm_private_data = shp;
+	vma->vm_ops = &shmzero_vm_ops;
+	shmzero_open(vma);
+	spin_lock(&zmap_list_lock);
+	shp->attaches = (struct vm_area_struct *)zmap_list;
+	zmap_list = shp;
+	spin_unlock(&zmap_list_lock);
+	return 0;
+}
+
+static void shmzero_open(struct vm_area_struct *shmd)
+{
+	struct shmid_kernel *shp;
+
+	shp = (struct shmid_kernel *) shmd->vm_private_data;
+	down(&shp->sem);
+	shp->shm_nattch++;
+	up(&shp->sem);
+}
+
+static void shmzero_close(struct vm_area_struct *shmd)
+{
+	int done = 0;
+	struct shmid_kernel *shp, *prev, *cur;
+
+	shp = (struct shmid_kernel *) shmd->vm_private_data;
+	down(&shp->sem);
+	if (--shp->shm_nattch == 0)
+		done = 1;
+	up(&shp->sem);
+	if (done) {
+		spin_lock(&zmap_list_lock);
+		if (shp == zswap_shp)
+			zswap_shp = (struct shmid_kernel *)(shp->attaches);
+		if (shp == zmap_list)
+			zmap_list = (struct shmid_kernel *)(shp->attaches);
+		else {
+			prev = zmap_list;
+			cur = (struct shmid_kernel *)(prev->attaches);
+			while (cur != shp) {
+				prev = cur;
+				cur = (struct shmid_kernel *)(prev->attaches);
+			}
+			prev->attaches = (struct vm_area_struct *)(shp->attaches);
+		}
+		spin_unlock(&zmap_list_lock);
+		killseg_core(shp, 0);
+	}
+}
+
+static void zmap_unuse(swp_entry_t entry, struct page *page)
+{
+	struct shmid_kernel *shp;
+
+	spin_lock(&zmap_list_lock);
+	shp = zmap_list;
+	while (shp) {
+		if (shm_unuse_core(shp, entry, page))
+			break;
+		shp = (struct shmid_kernel *)shp->attaches;
+	}
+	spin_unlock(&zmap_list_lock);
+}
+
+static void zshm_swap (int prio, int gfp_mask, zone_t *zone)
+{
+	struct shmid_kernel *shp;
+	swp_entry_t swap_entry;
+	unsigned long idx;
+	int loop = 0;
+	int counter;
+	struct page * page_map;
+
+	counter = 10;	/* maybe we should use zshm_rss */
+	if (!counter)
+		return;
+next:
+	if (shm_swap_preop(&swap_entry))
+		return;
+
+	spin_lock(&zmap_list_lock);
+	if (zmap_list == 0)
+		goto failed;
+next_id:
+	if ((shp = zswap_shp) == 0) {
+		if (loop) {
+failed:
+			spin_unlock(&zmap_list_lock);
+			__swap_free(swap_entry, 2);
+			return;
+		}
+		zswap_shp = shp = zmap_list;
+		zswap_idx = 0;
+		loop = 1;
+	}
+
+check_table:
+	idx = zswap_idx++;
+	if (idx >= shp->shm_npages) {
+		zswap_shp = (struct shmid_kernel *)(zswap_shp->attaches);
+		zswap_idx = 0;
+		goto next_id;
+	}
+
+	switch (shm_swap_core(shp, idx, swap_entry, zone, &counter, &page_map)) {
+		case RETRY: goto check_table;
+		case FAILED: goto failed;
+	}
+	spin_unlock(&zmap_list_lock);
+
+	shm_swap_postop(page_map);
+	if (counter)
+		goto next;
+	return;
+}
diff -u --recursive --new-file v2.3.47/linux/ipc/util.c linux/ipc/util.c
--- v2.3.47/linux/ipc/util.c	Tue Jan 11 22:31:45 2000
+++ linux/ipc/util.c	Sat Feb 26 20:23:37 2000
@@ -317,4 +317,9 @@
 {
 }
 
+int map_zero_setup(struct vm_area_struct *vma)
+{
+	return -EINVAL;
+}
+
 #endif /* CONFIG_SYSVIPC */
diff -u --recursive --new-file v2.3.47/linux/kernel/exit.c linux/kernel/exit.c
--- v2.3.47/linux/kernel/exit.c	Thu Feb 10 17:11:23 2000
+++ linux/kernel/exit.c	Mon Feb 21 10:59:36 2000
@@ -445,7 +445,7 @@
 	DECLARE_WAITQUEUE(wait, current);
 	struct task_struct *p;
 
-	if (options & ~(WNOHANG|WUNTRACED|__WCLONE))
+	if (options & ~(WNOHANG|WUNTRACED|__WCLONE|__WALL))
 		return -EINVAL;
 
 	add_wait_queue(&current->wait_chldexit,&wait);
@@ -464,8 +464,13 @@
 			if (p->pgrp != -pid)
 				continue;
 		}
-		/* wait for cloned processes iff the __WCLONE flag is set */
-		if ((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0))
+		/* Wait for all children (clone and not) if __WALL is set;
+		 * otherwise, wait for clone children *only* if __WCLONE is
+		 * set; otherwise, wait for non-clone children *only*.  (Note:
+		 * A "clone" child here is one that reports to its parent
+		 * using a signal other than SIGCHLD.) */
+		if (((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0))
+		    && !(options & __WALL))
 			continue;
 		flag = 1;
 		switch (p->state) {
diff -u --recursive --new-file v2.3.47/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.3.47/linux/kernel/ksyms.c	Sun Feb 20 21:12:40 2000
+++ linux/kernel/ksyms.c	Sat Feb 26 20:33:09 2000
@@ -159,6 +159,8 @@
 EXPORT_SYMBOL(free_kiovec);
 EXPORT_SYMBOL(brw_kiovec);
 EXPORT_SYMBOL(alloc_kiovec);
+EXPORT_SYMBOL(expand_kiobuf);
+EXPORT_SYMBOL(unmap_kiobuf);
 EXPORT_SYMBOL(get_empty_filp);
 EXPORT_SYMBOL(init_private_file);
 EXPORT_SYMBOL(filp_open);
@@ -196,6 +198,7 @@
 EXPORT_SYMBOL(do_generic_file_read);
 EXPORT_SYMBOL(generic_file_write);
 EXPORT_SYMBOL(generic_file_mmap);
+EXPORT_SYMBOL(generic_ro_fops);
 EXPORT_SYMBOL(generic_buffer_fdatasync);
 EXPORT_SYMBOL(page_hash_bits);
 EXPORT_SYMBOL(page_hash_table);
@@ -216,6 +219,7 @@
 EXPORT_SYMBOL(vfs_rmdir);
 EXPORT_SYMBOL(vfs_unlink);
 EXPORT_SYMBOL(vfs_rename);
+EXPORT_SYMBOL(generic_read_dir);
 EXPORT_SYMBOL(__pollwait);
 EXPORT_SYMBOL(ROOT_DEV);
 EXPORT_SYMBOL(__find_get_page);
diff -u --recursive --new-file v2.3.47/linux/kernel/pm.c linux/kernel/pm.c
--- v2.3.47/linux/kernel/pm.c	Sun Feb 20 21:12:40 2000
+++ linux/kernel/pm.c	Wed Feb 23 20:05:12 2000
@@ -87,21 +87,27 @@
 }
 
 /*
- * Send request to an individual device
+ * Send request to a single device
  */
-static int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data)
+int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data)
 {
 	int status = 0;
-	int next_state;
+	int prev_state, next_state;
 	switch (rqst) {
 	case PM_SUSPEND:
 	case PM_RESUME:
+		prev_state = dev->state;
 		next_state = (int) data;
-		if (dev->state != next_state) {
+		if (prev_state != next_state) {
 			if (dev->callback)
 				status = (*dev->callback)(dev, rqst, data);
-			if (!status)
+			if (!status) {
 				dev->state = next_state;
+				dev->prev_state = prev_state;
+			}
+		}
+		else {
+			dev->prev_state = prev_state;
 		}
 		break;
 	default:
@@ -115,13 +121,19 @@
 /*
  * Undo incomplete request
  */
-static void pm_undo_request(struct pm_dev *last, pm_request_t undo, void *data)
+static void pm_undo_all(struct pm_dev *last)
 {
 	struct list_head *entry = last->entry.prev;
 	while (entry != &pm_devs) {
 		struct pm_dev *dev = list_entry(entry, struct pm_dev, entry);
-		if (dev->callback)
-			pm_send(dev, undo, data);
+		if (dev->state != dev->prev_state) {
+			/* previous state was zero (running) resume or
+			 * previous state was non-zero (suspended) suspend
+			 */
+			pm_request_t undo = (dev->prev_state
+					     ? PM_SUSPEND:PM_RESUME);
+			pm_send(dev, undo, (void*) dev->prev_state);
+		}
 		entry = entry->prev;
 	}
 }
@@ -129,7 +141,7 @@
 /*
  * Send a request to all devices
  */
-int pm_send_request(pm_request_t rqst, void *data)
+int pm_send_all(pm_request_t rqst, void *data)
 {
 	struct list_head *entry = pm_devs.next;
 	while (entry != &pm_devs) {
@@ -137,9 +149,11 @@
 		if (dev->callback) {
 			int status = pm_send(dev, rqst, data);
 			if (status) {
-				/* resume devices on failed suspend request */
+				/* return devices to previous state on
+				 * failed suspend request
+				 */
 				if (rqst == PM_SUSPEND)
-					pm_undo_request(dev, PM_RESUME, 0);
+					pm_undo_all(dev);
 				return status;
 			}
 		}
@@ -166,6 +180,7 @@
 EXPORT_SYMBOL(pm_register);
 EXPORT_SYMBOL(pm_unregister);
 EXPORT_SYMBOL(pm_unregister_all);
-EXPORT_SYMBOL(pm_send_request);
+EXPORT_SYMBOL(pm_send);
+EXPORT_SYMBOL(pm_send_all);
 EXPORT_SYMBOL(pm_find);
 EXPORT_SYMBOL(pm_active);
diff -u --recursive --new-file v2.3.47/linux/kernel/sched.c linux/kernel/sched.c
--- v2.3.47/linux/kernel/sched.c	Sun Feb 20 21:12:40 2000
+++ linux/kernel/sched.c	Thu Feb 24 10:15:58 2000
@@ -497,17 +497,15 @@
 	c = -1000;
 	if (prev->state == TASK_RUNNING)
 		goto still_running;
-still_running_back:
 
-	tmp = runqueue_head.next;
-	while (tmp != &runqueue_head) {
+still_running_back:
+	list_for_each(tmp, &runqueue_head) {
 		p = list_entry(tmp, struct task_struct, run_list);
 		if (can_schedule(p)) {
 			int weight = goodness(p, this_cpu, prev->active_mm);
 			if (weight > c)
 				c = weight, next = p;
 		}
-		tmp = tmp->next;
 	}
 
 	/* Do we need to re-calculate counters? */
@@ -658,12 +656,9 @@
         if (!head->next || !head->prev)
                 WQ_BUG();
 #endif
-	tmp = head->next;
-	while (tmp != head) {
+	list_for_each(tmp, head) {
 		unsigned int state;
                 wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list);
-
-		tmp = tmp->next;
 
 #if WAITQUEUE_DEBUG
 		CHECK_MAGIC(curr->__magic);
diff -u --recursive --new-file v2.3.47/linux/kernel/sys.c linux/kernel/sys.c
--- v2.3.47/linux/kernel/sys.c	Thu Feb 10 17:11:23 2000
+++ linux/kernel/sys.c	Thu Feb 24 10:14:29 2000
@@ -226,8 +226,7 @@
 	default:
 		unlock_kernel();
 		return -EINVAL;
-		break;
-	};
+	}
 	unlock_kernel();
 	return 0;
 }
@@ -1042,6 +1041,22 @@
 			}
 			current->dumpable = arg2;
 			break;
+	        case PR_SET_UNALIGN:
+#ifdef SET_UNALIGN_CTL
+			error = SET_UNALIGN_CTL(current, arg2);
+#else
+			error = -EINVAL;
+#endif
+			break;
+
+	        case PR_GET_UNALIGN:
+#ifdef GET_UNALIGN_CTL
+			error = GET_UNALIGN_CTL(current, arg2);
+#else
+			error = -EINVAL;
+#endif
+			break;
+
 		default:
 			error = -EINVAL;
 			break;
diff -u --recursive --new-file v2.3.47/linux/kernel/sysctl.c linux/kernel/sysctl.c
--- v2.3.47/linux/kernel/sysctl.c	Thu Feb 10 17:11:23 2000
+++ linux/kernel/sysctl.c	Sat Feb 26 20:33:09 2000
@@ -12,6 +12,8 @@
  *  Horn.
  * Added proc_doulongvec_ms_jiffies_minmax, 09/08/99, Carlos H. Bauer.
  * Added proc_doulongvec_minmax, 09/08/99, Carlos H. Bauer.
+ * Changed linked lists to use list.h instead of lists.h, 02/24/00, Bill
+ *  Wendling.
  */
 
 #include <linux/config.h>
@@ -86,8 +88,7 @@
 
 
 static ctl_table root_table[];
-static struct ctl_table_header root_table_header = 
-	{root_table, DNODE_SINGLE(&root_table_header)};
+static LIST_HEAD(root_table_header);
 
 static ctl_table kern_table[];
 static ctl_table vm_table[];
@@ -115,23 +116,9 @@
 	write:		proc_writesys,
 };
 
-struct inode_operations proc_sys_inode_operations =
+static struct inode_operations proc_sys_inode_operations =
 {
-	&proc_sys_file_operations,
-	NULL,		/* create */
-	NULL,		/* lookup */
-	NULL,		/* link */
-	NULL,		/* unlink */
-	NULL,		/* symlink */
-	NULL,		/* mkdir */
-	NULL,		/* rmdir */
-	NULL,		/* mknod */
-	NULL,		/* rename */
-	NULL,		/* readlink */
-	NULL,		/* follow_link */
-	NULL,		/* truncate */
-	proc_sys_permission, /* permission */
-	NULL		/* revalidate */
+	permission:	proc_sys_permission,
 };
 
 extern struct proc_dir_entry *proc_sys_root;
@@ -305,21 +292,23 @@
 	{0}
 };  
 
+extern void init_irq_proc (void);
 
 void __init sysctl_init(void)
 {
 #ifdef CONFIG_PROC_FS
 	register_proc_table(root_table, proc_sys_root);
+	init_irq_proc();
 #endif
-}
 
+}
 
 int do_sysctl (int *name, int nlen,
 	       void *oldval, size_t *oldlenp,
 	       void *newval, size_t newlen)
 {
 	int error;
-	struct ctl_table_header *tmp;
+	struct list_head *tmp;
 	void *context;
 	
 	if (nlen == 0 || nlen >= CTL_MAXNAME)
@@ -333,17 +322,17 @@
 		if(get_user(old_len, oldlenp))
 			return -EFAULT;
 	}
-	tmp = &root_table_header;
-	do {
+	list_for_each(tmp, &root_table_header) {
+		struct ctl_table_header *head =
+			list_entry(tmp, struct ctl_table_header, ctl_entry);
 		context = NULL;
 		error = parse_table(name, nlen, oldval, oldlenp, 
-				    newval, newlen, tmp->ctl_table, &context);
+				    newval, newlen, head->ctl_table, &context);
 		if (context)
 			kfree(context);
 		if (error != -ENOTDIR)
 			return error;
-		tmp = tmp->DLIST_NEXT(ctl_entry);
-	} while (tmp != &root_table_header);
+	}
 	return -ENOTDIR;
 }
 
@@ -438,7 +427,7 @@
 						   newval, newlen, context);
 			return error;
 		}
-	};
+	}
 	return -ENOTDIR;
 }
 
@@ -495,14 +484,15 @@
 					       int insert_at_head)
 {
 	struct ctl_table_header *tmp;
-	tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+	tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL);
 	if (!tmp)
 		return 0;
-	*tmp = ((struct ctl_table_header) {table, DNODE_NULL});
+	tmp->ctl_table = table;
+	INIT_LIST_HEAD(&tmp->ctl_entry);
 	if (insert_at_head)
-		DLIST_INSERT_AFTER(&root_table_header, tmp, ctl_entry);
+		list_add(&tmp->ctl_entry, &root_table_header);
 	else
-		DLIST_INSERT_BEFORE(&root_table_header, tmp, ctl_entry);
+		list_add_tail(&tmp->ctl_entry, &root_table_header);
 #ifdef CONFIG_PROC_FS
 	register_proc_table(table, proc_sys_root);
 #endif
@@ -514,7 +504,7 @@
  */
 void unregister_sysctl_table(struct ctl_table_header * header)
 {
-	DLIST_DELETE(header, ctl_entry);
+	list_del(&header->ctl_entry);
 #ifdef CONFIG_PROC_FS
 	unregister_proc_table(header->ctl_table, proc_sys_root);
 #endif
@@ -565,9 +555,10 @@
 			if (!de)
 				continue;
 			de->data = (void *) table;
-			if (table->proc_handler)
-				de->ops = &proc_sys_inode_operations;
-
+			if (table->proc_handler) {
+				de->proc_fops = &proc_sys_file_operations;
+				de->proc_iops = &proc_sys_inode_operations;
+			}
 		}
 		table->de = de;
 		if (de->mode & S_IFDIR)
diff -u --recursive --new-file v2.3.47/linux/mm/bootmem.c linux/mm/bootmem.c
--- v2.3.47/linux/mm/bootmem.c	Thu Feb 10 17:11:23 2000
+++ linux/mm/bootmem.c	Sat Feb 26 09:34:56 2000
@@ -82,7 +82,7 @@
 		BUG();
 	for (i = sidx; i < eidx; i++)
 		if (test_and_set_bit(i, bdata->node_bootmem_map))
-			BUG();
+			printk("hm, page %08lx reserved twice.\n", i*PAGE_SIZE);
 }
 
 static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr, unsigned long size)
diff -u --recursive --new-file v2.3.47/linux/mm/filemap.c linux/mm/filemap.c
--- v2.3.47/linux/mm/filemap.c	Sun Feb 20 21:12:40 2000
+++ linux/mm/filemap.c	Mon Feb 21 11:27:23 2000
@@ -1321,8 +1321,7 @@
 	 * of the file is an error and results in a SIGBUS, while a
 	 * private mapping just maps in a zero page.
 	 */
-	if ((pgoff >= size) &&
-		(area->vm_flags & VM_SHARED) && (area->vm_mm == current->mm))
+	if ((pgoff >= size) && (area->vm_mm == current->mm))
 		return NULL;
 
 	/*
@@ -1431,33 +1430,6 @@
 	return NULL;
 }
 
-/*
- * Tries to write a shared mapped page to its backing store. May return -EIO
- * if the disk is full.
- */
-static inline int do_write_page(struct inode * inode, struct file * file,
-	struct page * page, unsigned long index)
-{
-	int retval;
-	int (*writepage) (struct dentry *, struct page *);
-
-	/* refuse to extend file size.. */
-	if (S_ISREG(inode->i_mode)) {
-		unsigned long size_idx = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-
-		/* Ho humm.. We should have tested for this earlier */
-		if (size_idx <= index)
-			return -EIO;
-	}
-	writepage = inode->i_mapping->a_ops->writepage;
-	lock_page(page);
-
-	retval = writepage(file->f_dentry, page);
-
-	UnlockPage(page);
-	return retval;
-}
-
 static int filemap_write_page(struct file *file,
 			      unsigned long index,
 			      struct page * page,
@@ -1476,7 +1448,9 @@
 	 * vma/file is guaranteed to exist in the unmap/sync cases because
 	 * mmap_sem is held.
 	 */
-	result = do_write_page(inode, file, page, index);
+	lock_page(page);
+	result = inode->i_mapping->a_ops->writepage(dentry, page);
+	UnlockPage(page);
 	return result;
 }
 
diff -u --recursive --new-file v2.3.47/linux/mm/memory.c linux/mm/memory.c
--- v2.3.47/linux/mm/memory.c	Sun Feb 20 21:12:40 2000
+++ linux/mm/memory.c	Thu Feb 24 10:26:36 2000
@@ -418,7 +418,7 @@
 
 struct page * get_page_map(struct page *page, unsigned long vaddr)
 {
-	if (MAP_NR(page) >= max_mapnr)
+	if (MAP_NR(vaddr) >= max_mapnr)
 		return 0;
 	if (page == ZERO_PAGE(vaddr))
 		return 0;
@@ -712,6 +712,19 @@
 }
 
 /*
+ * Establish a new mapping:
+ *  - flush the old one
+ *  - update the page tables
+ *  - inform the TLB about the new one
+ */
+static inline void establish_pte(struct vm_area_struct * vma, unsigned long address, pte_t *page_table, pte_t entry)
+{
+	flush_tlb_page(vma, address);
+	set_pte(page_table, entry);
+	update_mmu_cache(vma, address, entry);
+}
+
+/*
  * This routine handles present pages, when users try to write
  * to a shared page. It is done by copying the page to a new address
  * and decrementing the shared-page counter for the old page.
@@ -769,8 +782,7 @@
 		/* FallThrough */
 	case 1:
 		flush_cache_page(vma, address);
-		set_pte(page_table, pte_mkyoung(pte_mkdirty(pte_mkwrite(pte))));
-		flush_tlb_page(vma, address);
+		establish_pte(vma, address, page_table, pte_mkyoung(pte_mkdirty(pte_mkwrite(pte))));
 		spin_unlock(&tsk->mm->page_table_lock);
 		return 1;
 	}
@@ -793,8 +805,7 @@
 		copy_cow_page(old_page, new_page, address);
 		flush_page_to_ram(new_page);
 		flush_cache_page(vma, address);
-		set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
-		flush_tlb_page(vma, address);
+		establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
 
 		/* Free the old page.. */
 		new_page = old_page;
@@ -862,6 +873,8 @@
 	struct vm_area_struct * mpnt;
 	struct address_space *mapping = inode->i_mapping;
 
+	if (inode->i_size < offset)
+		goto out;
 	inode->i_size = offset;
 	truncate_inode_pages(mapping, offset);
 	spin_lock(&mapping->i_shared_lock);
@@ -906,6 +919,9 @@
 	} while ((mpnt = mpnt->vm_next_share) != NULL);
 out_unlock:
 	spin_unlock(&mapping->i_shared_lock);
+out:
+	/* this should go into ->truncate */
+	inode->i_size = offset;
 	if (inode->i_op && inode->i_op->truncate)
 		inode->i_op->truncate(inode);
 }
@@ -1120,9 +1136,7 @@
 			entry = pte_mkdirty(entry);
 		}
 		entry = pte_mkyoung(entry);
-		set_pte(pte, entry);
-		flush_tlb_page(vma, address);
-		update_mmu_cache(vma, address, entry);
+		establish_pte(vma, address, pte, entry);
 	}
 	spin_unlock(&tsk->mm->page_table_lock);
 	return 1;
diff -u --recursive --new-file v2.3.47/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.3.47/linux/mm/page_alloc.c	Sun Feb 20 21:12:40 2000
+++ linux/mm/page_alloc.c	Sat Feb 26 20:50:34 2000
@@ -27,6 +27,7 @@
 int nr_swap_pages = 0;
 int nr_lru_pages;
 LIST_HEAD(lru_cache);
+pg_data_t *pgdat_list = (pg_data_t *)0;
 
 static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
 static int zone_balance_ratio[MAX_NR_ZONES] = { 128, 128, 128, };
@@ -264,24 +265,23 @@
 			{
 				if (z->low_on_memory)
 					z->low_on_memory = 0;
+				z->zone_wake_kswapd = 0;
 			}
 			else
 			{
 				extern wait_queue_head_t kswapd_wait;
 
-				if (z->low_on_memory)
-					goto balance;
-
-				if (free <= z->pages_low)
-				{
+				if (free <= z->pages_low) {
+					z->zone_wake_kswapd = 1;
 					wake_up_interruptible(&kswapd_wait);
+				} else
+					z->zone_wake_kswapd = 0;
 
-					if (free <= z->pages_min)
-					{
-						z->low_on_memory = 1;
-						goto balance;
-					}
-				}
+				if (free <= z->pages_min)
+					z->low_on_memory = 1;
+
+				if (z->low_on_memory)
+					goto balance;
 			}
 		}
 		/*
@@ -482,6 +482,9 @@
 	unsigned long totalpages, offset;
 	unsigned int cumulative = 0;
 
+	pgdat->node_next = pgdat_list;
+	pgdat_list = pgdat;
+
 	totalpages = 0;
 	for (i = 0; i < MAX_NR_ZONES; i++) {
 		unsigned long size = zones_size[i];
@@ -560,6 +563,7 @@
 		zone->pages_low = mask*2;
 		zone->pages_high = mask*3;
 		zone->low_on_memory = 0;
+		zone->zone_wake_kswapd = 0;
 		zone->zone_mem_map = mem_map + offset;
 		zone->zone_start_mapnr = offset;
 		zone->zone_start_paddr = zone_start_paddr;
diff -u --recursive --new-file v2.3.47/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.3.47/linux/mm/vmscan.c	Sat Feb 12 11:22:11 2000
+++ linux/mm/vmscan.c	Sat Feb 26 20:50:34 2000
@@ -8,6 +8,7 @@
  *  Removed kswapd_ctl limits, and swap out as many pages as needed
  *  to bring the system back to freepages.high: 2.4.97, Rik van Riel.
  *  Version: $Id: vmscan.c,v 1.5 1998/02/23 22:14:28 sct Exp $
+ *  Zone aware kswapd started 02/00, Kanoj Sarcar (kanoj@sgi.com).
  */
 
 #include <linux/slab.h>
@@ -468,7 +469,10 @@
  */
 int kswapd(void *unused)
 {
+	int i;
 	struct task_struct *tsk = current;
+	pg_data_t *pgdat;
+	zone_t *zone;
 
 	tsk->session = 1;
 	tsk->pgrp = 1;
@@ -496,12 +500,17 @@
 		 * up on a more timely basis.
 		 */
 		do {
-			/* kswapd is critical to provide GFP_ATOMIC
-			   allocations (not GFP_HIGHMEM ones). */
-			if (nr_free_pages() - nr_free_highpages() >= freepages.high)
-				break;
-			if (!do_try_to_free_pages(GFP_KSWAPD, 0))
-				break;
+			pgdat = pgdat_list;
+			while (pgdat) {
+				for (i = 0; i < MAX_NR_ZONES; i++) {
+					zone = pgdat->node_zones + i;
+					if ((!zone->size) || 
+							(!zone->zone_wake_kswapd))
+						continue;
+					do_try_to_free_pages(GFP_KSWAPD, zone);
+				}
+				pgdat = pgdat->node_next;
+			}
 			run_task_queue(&tq_disk);
 		} while (!tsk->need_resched);
 		tsk->state = TASK_INTERRUPTIBLE;
diff -u --recursive --new-file v2.3.47/linux/net/atm/clip.c linux/net/atm/clip.c
--- v2.3.47/linux/net/atm/clip.c	Sat Feb 12 11:22:11 2000
+++ linux/net/atm/clip.c	Mon Feb 21 16:32:27 2000
@@ -73,6 +73,7 @@
 	DPRINTK("link_vcc %p to entry %p (neigh %p)\n",clip_vcc,entry,
 	    entry->neigh);
 	clip_vcc->entry = entry;
+	clip_vcc->xoff = 0; /* @@@ may overrun buffer by one packet */
 	clip_vcc->next = entry->vccs;
 	entry->vccs = clip_vcc;
 	entry->neigh->used = jiffies;
@@ -95,6 +96,8 @@
 
 			*walk = clip_vcc->next; /* atomic */
 			clip_vcc->entry = NULL;
+			if (clip_vcc->xoff)
+				netif_wake_queue(entry->neigh->dev);
 			if (entry->vccs) return;
 			entry->expires = jiffies-1;
 				/* force resolution or expiration */
@@ -218,13 +221,27 @@
 }
 
 
+/*
+ * Note: these spinlocks _must_not_ block on non-SMP. The only goal is that
+ * clip_pop is atomic with respect to the critical section in clip_start_xmit.
+ */
+
+
 static void clip_pop(struct atm_vcc *vcc,struct sk_buff *skb)
 {
+	struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
+	int old;
+
 	DPRINTK("clip_pop(vcc %p)\n",vcc);
-	CLIP_VCC(vcc)->old_pop(vcc,skb);
+	clip_vcc->old_pop(vcc,skb);
 	/* skb->dev == NULL in outbound ARP packets */
-	if (atm_may_send(vcc,0) && skb->dev)
-		netif_wake_queue(skb->dev);
+	if (!skb->dev) return;
+	spin_lock(&PRIV(skb->dev)->xoff_lock);
+	if (atm_may_send(vcc,0)) {
+		old = xchg(&clip_vcc->xoff,0);
+		if (old) netif_wake_queue(skb->dev);
+	}
+	spin_unlock(&PRIV(skb->dev)->xoff_lock);
 }
 
 
@@ -354,8 +371,10 @@
 
 static int clip_start_xmit(struct sk_buff *skb,struct net_device *dev)
 {
+	struct clip_priv *clip_priv = PRIV(dev);
 	struct atmarp_entry *entry;
 	struct atm_vcc *vcc;
+	int old;
 
 	DPRINTK("clip_start_xmit (skb %p)\n",skb);
 	if (!skb->dst) {
@@ -368,7 +387,7 @@
 		skb->dst->neighbour = clip_find_neighbour(skb->dst,1);
 		if (!skb->dst->neighbour) {
 			dev_kfree_skb(skb); /* lost that one */
-			PRIV(dev)->stats.tx_dropped++;
+			clip_priv->stats.tx_dropped++;
 			return 0;
 		}
 #endif
@@ -386,7 +405,7 @@
 			skb_queue_tail(&entry->neigh->arp_queue,skb);
 		else {
 			dev_kfree_skb(skb);
-			PRIV(dev)->stats.tx_dropped++;
+			clip_priv->stats.tx_dropped++;
 		}
 		return 0;
 	}
@@ -401,15 +420,33 @@
 		((u16 *) here)[3] = skb->protocol;
 	}
 	atomic_add(skb->truesize,&vcc->tx_inuse);
-	if (!atm_may_send(vcc,0))
-		netif_stop_queue(dev);
 	ATM_SKB(skb)->iovcnt = 0;
 	ATM_SKB(skb)->atm_options = vcc->atm_options;
 	entry->vccs->last_use = jiffies;
 	DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n",skb,vcc,vcc->dev);
-	PRIV(dev)->stats.tx_packets++;
-	PRIV(dev)->stats.tx_bytes += skb->len;
+	old = xchg(&entry->vccs->xoff,1); /* assume XOFF ... */
+	if (old) {
+		printk(KERN_WARNING "clip_start_xmit: XOFF->XOFF transition\n");
+		return 0;
+	}
+	clip_priv->stats.tx_packets++;
+	clip_priv->stats.tx_bytes += skb->len;
 	(void) vcc->dev->ops->send(vcc,skb);
+	if (atm_may_send(vcc,0)) {
+		entry->vccs->xoff = 0;
+		return 0;
+	}
+	if (old) return 0;
+	spin_lock(&clip_priv->xoff_lock);
+	netif_stop_queue(dev); /* XOFF -> throttle immediately */
+	barrier();
+	if (!entry->vccs->xoff)
+		netif_start_queue(dev);
+		/* Oh, we just raced with clip_pop. netif_start_queue should be
+		   good enough, because nothing should really be asleep because
+		   of the brief netif_stop_queue. If this isn't true or if it
+		   changes, use netif_wake_queue instead. */
+	spin_unlock(&clip_priv->xoff_lock);
 	return 0;
 }
 
@@ -434,6 +471,7 @@
 	clip_vcc->vcc = vcc;
 	vcc->user_back = clip_vcc;
 	clip_vcc->entry = NULL;
+	clip_vcc->xoff = 0;
 	clip_vcc->encap = 1;
 	clip_vcc->last_use = jiffies;
 	clip_vcc->idle_timeout = timeout*HZ;
@@ -523,7 +561,7 @@
 	dev->hard_header_len = RFC1483LLC_LEN;
 	dev->mtu = RFC1626_MTU;
 	dev->addr_len = 0;
-	dev->tx_queue_len = 100; /* "normal" queue */
+	dev->tx_queue_len = 100; /* "normal" queue (packets) */
 	    /* When using a "real" qdisc, the qdisc determines the queue */
 	    /* length. tx_queue_len is only used for the default case, */
 	    /* without any more elaborate queuing. 100 is a reasonable */
@@ -538,6 +576,7 @@
 int clip_create(int number)
 {
 	struct net_device *dev;
+	struct clip_priv *clip_priv;
 	int error;
 
 	if (number != -1) {
@@ -554,16 +593,18 @@
 	    GFP_KERNEL); 
 	if (!dev) return -ENOMEM;
 	memset(dev,0,sizeof(struct net_device)+sizeof(struct clip_priv));
-	dev->name = PRIV(dev)->name;
+	clip_priv = PRIV(dev);
+	dev->name = clip_priv->name;
 	sprintf(dev->name,"atm%d",number);
 	dev->init = clip_init;
-	PRIV(dev)->number = number;
+	spin_lock_init(&clip_priv->xoff_lock);
+	clip_priv->number = number;
 	error = register_netdev(dev);
 	if (error) {
 		kfree(dev);
 		return error;
 	}
-	PRIV(dev)->next = clip_devs;
+	clip_priv->next = clip_devs;
 	clip_devs = dev;
 	DPRINTK("registered (net:%s)\n",dev->name);
 	return number;
diff -u --recursive --new-file v2.3.47/linux/net/atm/lec.c linux/net/atm/lec.c
--- v2.3.47/linux/net/atm/lec.c	Thu Feb 10 17:11:23 2000
+++ linux/net/atm/lec.c	Mon Feb 21 16:32:27 2000
@@ -184,9 +184,7 @@
 {
         struct lec_priv *priv = (struct lec_priv *)dev->priv;
         
-        dev->tbusy = 0;
-        dev->start = 1;
-        dev->interrupt = 1;
+	netif_start_queue(dev);
         memset(&priv->stats,0,sizeof(struct net_device_stats));
         
         return 0;
@@ -214,165 +212,148 @@
         if (!priv->lecd) {
                 printk("%s:No lecd attached\n",dev->name);
                 priv->stats.tx_errors++;
-                dev->tbusy = 1;
+                netif_stop_queue(dev);
                 return -EUNATCH;
         } 
-        if (dev->tbusy) {
-                /*
-                 * If we get here, some higher level has decided we are broken.
-                 * There should really be a "kick me" function call instead.
-                 */
-                printk("%s: transmit timed out\n", dev->name);
-                dev->tbusy = 0;
-        }
-
-        /*
-         * Block a timer-based transmit from overlapping. This could better be
-         * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
-         */
 
-        if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
-                printk(KERN_WARNING "%s: Transmitter access conflict.\n", 
-                       dev->name);
-        } else {
-                DPRINTK("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
-                        (long)skb->head, (long)skb->data, (long)skb->tail,
-                        (long)skb->end);
+        DPRINTK("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
+                (long)skb->head, (long)skb->data, (long)skb->tail,
+                (long)skb->end);
 #ifdef CONFIG_BRIDGE
-                if (skb->pkt_bridged == IS_BRIDGED)
-                        handle_bridge(skb, dev);
+        if (skb->pkt_bridged == IS_BRIDGED)
+                handle_bridge(skb, dev);
 #endif /* CONFIG_BRIDGE */
 
-                /* Make sure we have room for lec_id */
-                if (skb_headroom(skb) < 2) {
+        /* Make sure we have room for lec_id */
+        if (skb_headroom(skb) < 2) {
 
-                        DPRINTK("lec_send_packet: reallocating skb\n");
-                        skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
-                        kfree_skb(skb);
-                        if (skb2 == NULL) return 0;
-                        skb = skb2;
-                }
-                skb_push(skb, 2);
-
-                /* Put le header to place, works for TokenRing too */
-                lec_h = (struct lecdatahdr_8023*)skb->data;
-                lec_h->le_header = htons(priv->lecid); 
+                DPRINTK("lec_send_packet: reallocating skb\n");
+                skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
+                kfree_skb(skb);
+                if (skb2 == NULL) return 0;
+                skb = skb2;
+        }
+        skb_push(skb, 2);
+
+        /* Put le header to place, works for TokenRing too */
+        lec_h = (struct lecdatahdr_8023*)skb->data;
+        lec_h->le_header = htons(priv->lecid); 
 
 #ifdef CONFIG_TR
-                /* Ugly. Use this to realign Token Ring packets for
-                 * e.g. PCA-200E driver. */
-                if (priv->is_trdev) {
-                        skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
-                        kfree_skb(skb);
-                        if (skb2 == NULL) return 0;
-                        skb = skb2;
-                }
+        /* Ugly. Use this to realign Token Ring packets for
+         * e.g. PCA-200E driver. */
+        if (priv->is_trdev) {
+                skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
+                kfree_skb(skb);
+                if (skb2 == NULL) return 0;
+                skb = skb2;
+        }
 #endif
 
 #if DUMP_PACKETS > 0
-                printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name,
-                        skb->len, priv->lecid);
+        printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name,
+               skb->len, priv->lecid);
 #if DUMP_PACKETS >= 2
-                for(i=0;i<skb->len && i <99;i++) {
-                        sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]);
-                }
+        for(i=0;i<skb->len && i <99;i++) {
+                sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]);
+        }
 #elif DUMP_PACKETS >= 1
-                for(i=0;i<skb->len && i < 30;i++) {
-                        sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]);
-                }
+        for(i=0;i<skb->len && i < 30;i++) {
+                sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]);
+        }
 #endif /* DUMP_PACKETS >= 1 */
-                if (i==skb->len)
-                        printk("%s\n",buf);
-                else
-                        printk("%s...\n",buf);
+        if (i==skb->len)
+                printk("%s\n",buf);
+        else
+                printk("%s...\n",buf);
 #endif /* DUMP_PACKETS > 0 */
 
-                /* Minimum ethernet-frame size */
-                if (skb->len <62) {
-                        if (skb->truesize < 62) {
-                                printk("%s:data packet %d / %d\n",
-                                       dev->name,
-                                       skb->len,skb->truesize);
-                                nb=(unsigned char*)kmalloc(64, GFP_ATOMIC);
-                                memcpy(nb,skb->data,skb->len);
-                                kfree(skb->head);
-                                skb->head = skb->data = nb;
-                                skb->tail = nb+62;
-                                skb->end = nb+64;
-                                skb->len=62;
-                                skb->truesize = 64;
-                        } else {
-                                skb->len = 62;
-                        }
+        /* Minimum ethernet-frame size */
+        if (skb->len <62) {
+                if (skb->truesize < 62) {
+                        printk("%s:data packet %d / %d\n",
+                               dev->name,
+                               skb->len,skb->truesize);
+                        nb=(unsigned char*)kmalloc(64, GFP_ATOMIC);
+                        memcpy(nb,skb->data,skb->len);
+                        kfree(skb->head);
+                        skb->head = skb->data = nb;
+                        skb->tail = nb+62;
+                        skb->end = nb+64;
+                        skb->len=62;
+                        skb->truesize = 64;
+                } else {
+                        skb->len = 62;
                 }
-
-                /* Send to right vcc */
-                is_rdesc = 0;
-                dst = lec_h->h_dest;
+        }
+        
+        /* Send to right vcc */
+        is_rdesc = 0;
+        dst = lec_h->h_dest;
 #ifdef CONFIG_TR
-                if (priv->is_trdev) {
-                        dst = get_tr_dst(skb->data+2, rdesc);
-                        if (dst == NULL) {
-                                dst = rdesc;
-                                is_rdesc = 1;
-                        }
+        if (priv->is_trdev) {
+                dst = get_tr_dst(skb->data+2, rdesc);
+                if (dst == NULL) {
+                        dst = rdesc;
+                        is_rdesc = 1;
                 }
+        }
 #endif
-                entry = NULL;
-                send_vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry);
-                DPRINTK("%s:send_vcc:%p vcc_flags:%x, entry:%p\n", dev->name,
-                        send_vcc, send_vcc?send_vcc->flags:0, entry);
-                if (!send_vcc || !(send_vcc->flags & ATM_VF_READY)) {    
-                        if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
-                                DPRINTK("%s:lec_send_packet: queuing packet, ", dev->name);
-                                DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
-                                       lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
-                                       lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
-                                skb_queue_tail(&entry->tx_wait, skb);
-                        } else {
-                                DPRINTK("%s:lec_send_packet: tx queue full or no arp entry, dropping, ", dev->name);
-                                DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
-                                       lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
-                                       lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
-                                priv->stats.tx_dropped++;
-                                dev_kfree_skb(skb);
-                        }
-                        dev->tbusy=0;
-                        return 0;
+        entry = NULL;
+        send_vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry);
+        DPRINTK("%s:send_vcc:%p vcc_flags:%x, entry:%p\n", dev->name,
+                send_vcc, send_vcc?send_vcc->flags:0, entry);
+        if (!send_vcc || !(send_vcc->flags & ATM_VF_READY)) {    
+                if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
+                        DPRINTK("%s:lec_send_packet: queuing packet, ", dev->name);
+                        DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+                                lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
+                                lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
+                        skb_queue_tail(&entry->tx_wait, skb);
+                } else {
+                        DPRINTK("%s:lec_send_packet: tx queue full or no arp entry, dropping, ", dev->name);
+                        DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+                                lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
+                                lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
+                        priv->stats.tx_dropped++;
+                        dev_kfree_skb(skb);
                 }
+                return 0;
+        }
                 
 #if DUMP_PACKETS > 0                    
-                printk("%s:sending to vpi:%d vci:%d\n", dev->name,
-                       send_vcc->vpi, send_vcc->vci);       
+        printk("%s:sending to vpi:%d vci:%d\n", dev->name,
+               send_vcc->vpi, send_vcc->vci);       
 #endif /* DUMP_PACKETS > 0 */
                 
-                while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
-                        DPRINTK("lec.c: emptying tx queue, ");
-                        DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
-                               lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
-                        ATM_SKB(skb2)->vcc = send_vcc;
-                        atomic_add(skb2->truesize, &send_vcc->tx_inuse);
-                        ATM_SKB(skb2)->iovcnt = 0;
-                        ATM_SKB(skb2)->atm_options = send_vcc->atm_options;
-                        DPRINTK("%s:sending to vpi:%d vci:%d\n", dev->name,
-                               send_vcc->vpi, send_vcc->vci);       
-                        priv->stats.tx_packets++;
-                        priv->stats.tx_bytes += skb2->len;
-                        send_vcc->dev->ops->send(send_vcc, skb2);
-                }
-
-                ATM_SKB(skb)->vcc = send_vcc;
-                atomic_add(skb->truesize, &send_vcc->tx_inuse);
-                ATM_SKB(skb)->iovcnt = 0;
-                ATM_SKB(skb)->atm_options = send_vcc->atm_options;
+        while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
+                DPRINTK("lec.c: emptying tx queue, ");
+                DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+                        lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
+                        lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
+                ATM_SKB(skb2)->vcc = send_vcc;
+                atomic_add(skb2->truesize, &send_vcc->tx_inuse);
+                ATM_SKB(skb2)->iovcnt = 0;
+                ATM_SKB(skb2)->atm_options = send_vcc->atm_options;
+                DPRINTK("%s:sending to vpi:%d vci:%d\n", dev->name,
+                        send_vcc->vpi, send_vcc->vci);       
                 priv->stats.tx_packets++;
-                priv->stats.tx_bytes += skb->len;
-                send_vcc->dev->ops->send(send_vcc, skb);
+                priv->stats.tx_bytes += skb2->len;
+                send_vcc->dev->ops->send(send_vcc, skb2);
         }
+
+        ATM_SKB(skb)->vcc = send_vcc;
+        atomic_add(skb->truesize, &send_vcc->tx_inuse);
+        ATM_SKB(skb)->iovcnt = 0;
+        ATM_SKB(skb)->atm_options = send_vcc->atm_options;
+        priv->stats.tx_packets++;
+        priv->stats.tx_bytes += skb->len;
+        send_vcc->dev->ops->send(send_vcc, skb);
+
+#if 0
         /* Should we wait for card's device driver to notify us? */
         dev->tbusy=0;
-        
+#endif        
         return 0;
 }
 
@@ -380,8 +361,7 @@
 static int 
 lec_close(struct net_device *dev) 
 {
-        dev->tbusy = 1;
-        dev->start = 0;
+        netif_stop_queue(dev);
         return 0;
 }
 
@@ -530,9 +510,7 @@
         priv->lecd = NULL;
         /* Do something needful? */
 
-        dev->tbusy = 1;
-        dev->start = 0;
-
+        netif_stop_queue(dev);
         lec_arp_destroy(priv);
 
         if (skb_peek(&vcc->recvq))
@@ -698,7 +676,7 @@
 
                 if (!(dst[0]&0x01) &&   /* Never filter Multi/Broadcast */
                     !priv->is_proxy &&  /* Proxy wants all the packets */
-                    memcmp(dst, dev->dev_addr, sizeof(dev->dev_addr))) {
+		    memcmp(dst, dev->dev_addr, dev->addr_len)) {
                         dev_kfree_skb(skb);
                         return;
                 }
@@ -814,8 +792,7 @@
         priv->path_switching_delay = (6*HZ);
 
         if (dev_lec[i]->flags & IFF_UP) {
-                dev_lec[i]->tbusy = 0;
-                dev_lec[i]->start = 1;
+                netif_start_queue(dev_lec[i]);
         }
         MOD_INC_USE_COUNT;
         return i;
diff -u --recursive --new-file v2.3.47/linux/net/atm/mpoa_proc.c linux/net/atm/mpoa_proc.c
--- v2.3.47/linux/net/atm/mpoa_proc.c	Thu Feb 10 17:11:23 2000
+++ linux/net/atm/mpoa_proc.c	Sat Feb 26 20:33:10 2000
@@ -45,13 +45,6 @@
 	write:		proc_mpc_write,
 };
 
-/*
- *   Define allowed INODE OPERATIONS
- */
-static struct inode_operations mpc_inode_operations = {
-        &mpc_file_operations,
-};
-
 static int print_header(char *buff,struct mpoa_client *mpc){
         if(mpc != NULL){
 	        return sprintf(buff,"\nInterface %d:\n\n",mpc->dev_num);  
@@ -330,7 +323,7 @@
                 printk(KERN_ERR "Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME);
                 return -ENOMEM;
         }
-	p->ops = &mpc_inode_operations;
+	p->proc_fops = &mpc_file_operations;
 	return 0;
 }
 
diff -u --recursive --new-file v2.3.47/linux/net/atm/proc.c linux/net/atm/proc.c
--- v2.3.47/linux/net/atm/proc.c	Thu Feb 10 17:11:24 2000
+++ linux/net/atm/proc.c	Sat Feb 26 20:33:10 2000
@@ -63,15 +63,6 @@
 	read:		proc_spec_atm_read,
 };
 
-static struct inode_operations proc_dev_atm_inode_operations = {
-	&proc_dev_atm_operations,	/* default ATM directory file-ops */
-};
-
-static struct inode_operations proc_spec_atm_inode_operations = {
-	&proc_spec_atm_operations,	/* default ATM directory file-ops */
-};
-
-
 static void add_stats(char *buf,const char *aal,
   const struct atm_aal_stats *stats)
 {
@@ -563,7 +554,7 @@
 	if (!dev->proc_entry)
 		goto fail0;
 	dev->proc_entry->data = dev;
-	dev->proc_entry->ops = &proc_dev_atm_inode_operations;
+	dev->proc_entry->proc_fops = &proc_dev_atm_operations;
 	return 0;
 	kfree(dev->proc_entry);
 fail0:
@@ -584,7 +575,7 @@
     name = create_proc_entry(#name,0,atm_proc_root); \
     if (!name) goto cleanup; \
     name->data = atm_##name##_info; \
-    name->ops = &proc_spec_atm_inode_operations
+    name->proc_fops = &proc_spec_atm_operations
 
 
 int __init atm_proc_init(void)
diff -u --recursive --new-file v2.3.47/linux/net/atm/raw.c linux/net/atm/raw.c
--- v2.3.47/linux/net/atm/raw.c	Thu Feb 10 17:11:24 2000
+++ linux/net/atm/raw.c	Mon Feb 21 16:32:27 2000
@@ -1,6 +1,6 @@
 /* net/atm/raw.c - Raw AAL0 and AAL5 transports */
 
-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */
+/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
 
 
 #include <linux/module.h>
@@ -38,7 +38,7 @@
 {
 	DPRINTK("APopR (%d) %d -= %d\n",vcc->vci,vcc->tx_inuse,skb->truesize);
 	atomic_sub(skb->truesize+ATM_PDU_OVHD,&vcc->tx_inuse);
-	dev_kfree_skb(skb);
+	dev_kfree_skb_irq(skb);
 	wake_up(&vcc->wsleep);
 }
 
diff -u --recursive --new-file v2.3.47/linux/net/bridge/br_device.c linux/net/bridge/br_device.c
--- v2.3.47/linux/net/bridge/br_device.c	Sun Feb 20 21:12:40 2000
+++ linux/net/bridge/br_device.c	Thu Feb 24 22:48:39 2000
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_device.c,v 1.1 2000/02/18 16:47:11 davem Exp $
+ *	$Id: br_device.c,v 1.2 2000/02/24 19:48:06 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -116,12 +116,10 @@
 	return 0;
 }
 
-#ifdef CONFIG_NET_FASTROUTE
 static int br_dev_accept_fastpath(struct net_device *dev, struct dst_entry *dst)
 {
 	return -1;
 }
-#endif
 
 void br_dev_setup(struct net_device *dev)
 {
@@ -133,9 +131,7 @@
 	dev->open = br_dev_open;
 	dev->set_multicast_list = br_dev_set_multicast_list;
 	dev->stop = br_dev_stop;
-#ifdef CONFIG_NET_FASTROUTE
 	dev->accept_fastpath = br_dev_accept_fastpath;
-#endif
-
 	dev->tx_queue_len = 0;
+	dev->set_mac_address = NULL;
 }
diff -u --recursive --new-file v2.3.47/linux/net/bridge/br_fdb.c linux/net/bridge/br_fdb.c
--- v2.3.47/linux/net/bridge/br_fdb.c	Sun Feb 20 21:12:40 2000
+++ linux/net/bridge/br_fdb.c	Thu Feb 24 10:30:25 2000
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_fdb.c,v 1.1 2000/02/18 16:47:12 davem Exp $
+ *	$Id: br_fdb.c,v 1.4 2000/02/24 06:16:45 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -14,9 +14,9 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/spinlock.h>
 #include <linux/if_bridge.h>
 #include <asm/atomic.h>
-#include <asm/spinlock.h>
 #include <asm/uaccess.h>
 #include "br_private.h"
 
@@ -216,6 +216,7 @@
 			struct __fdb_entry ent;
 			int err;
 			struct net_bridge_fdb_entry *g;
+			struct net_bridge_fdb_entry **pp; 
 
 			if (has_expired(br, f)) {
 				f = f->next_hash;
@@ -236,13 +237,13 @@
 			read_lock_bh(&br->hash_lock);
 
 			g = f->next_hash;
+			pp = f->pprev_hash;
 			br_fdb_put(f);
 
 			if (err)
 				goto out_fault;
 
-			if (f->next_hash == NULL &&
-			    f->pprev_hash == NULL)
+			if (g == NULL && pp == NULL)
 				goto out_disappeared;
 
 			num++;
diff -u --recursive --new-file v2.3.47/linux/net/bridge/br_forward.c linux/net/bridge/br_forward.c
--- v2.3.47/linux/net/bridge/br_forward.c	Sun Feb 20 21:12:40 2000
+++ linux/net/bridge/br_forward.c	Mon Feb 21 17:35:06 2000
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_forward.c,v 1.1 2000/02/18 16:47:12 davem Exp $
+ *	$Id: br_forward.c,v 1.2 2000/02/21 15:51:33 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
diff -u --recursive --new-file v2.3.47/linux/net/bridge/br_if.c linux/net/bridge/br_if.c
--- v2.3.47/linux/net/bridge/br_if.c	Sun Feb 20 21:12:40 2000
+++ linux/net/bridge/br_if.c	Mon Feb 21 17:35:06 2000
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_if.c,v 1.1 2000/02/18 16:47:12 davem Exp $
+ *	$Id: br_if.c,v 1.2 2000/02/21 15:51:34 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
diff -u --recursive --new-file v2.3.47/linux/net/bridge/br_input.c linux/net/bridge/br_input.c
--- v2.3.47/linux/net/bridge/br_input.c	Sun Feb 20 21:12:40 2000
+++ linux/net/bridge/br_input.c	Thu Feb 24 22:48:39 2000
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_input.c,v 1.1 2000/02/18 16:47:12 davem Exp $
+ *	$Id: br_input.c,v 1.3 2000/02/24 19:48:06 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -23,21 +23,15 @@
 
 static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb)
 {
-	if (br->dev.flags & IFF_UP) {
-		br->statistics.rx_packets++;
-		br->statistics.rx_bytes += skb->len;
-
-		skb->dev = &br->dev;
-		skb->pkt_type = PACKET_HOST;
-		skb->mac.raw = skb->data;
-		skb_pull(skb, skb->nh.raw - skb->data);
-		skb->protocol = eth_type_trans(skb, &br->dev);
-		netif_rx(skb);
+	br->statistics.rx_packets++;
+	br->statistics.rx_bytes += skb->len;
 
-		return;
-	}
-
-	kfree_skb(skb);
+	skb->dev = &br->dev;
+	skb->pkt_type = PACKET_HOST;
+	skb->mac.raw = skb->data;
+	skb_pull(skb, skb->nh.raw - skb->data);
+	skb->protocol = eth_type_trans(skb, &br->dev);
+	netif_rx(skb);
 }
 
 static void __br_handle_frame(struct sk_buff *skb)
@@ -46,17 +40,44 @@
 	unsigned char *dest;
 	struct net_bridge_fdb_entry *dst;
 	struct net_bridge_port *p;
+	int passedup;
 
 	skb->nh.raw = skb->mac.raw;
 	dest = skb->mac.ethernet->h_dest;
 
 	p = skb->dev->br_port;
 	br = p->br;
+	passedup = 0;
+
+	if (!(br->dev.flags & IFF_UP) ||
+	    p->state == BR_STATE_DISABLED)
+		goto freeandout;
 
-	if (p->state == BR_STATE_DISABLED ||
-	    skb->mac.ethernet->h_source[0] & 1)
+	if (br->dev.flags & IFF_PROMISC) {
+		struct sk_buff *skb2;
+
+		skb2 = skb_clone(skb, GFP_ATOMIC);
+		if (skb2) {
+			passedup = 1;
+			br_pass_frame_up(br, skb2);
+		}
+	}
+
+	if (skb->mac.ethernet->h_source[0] & 1)
 		goto freeandout;
 
+	if (!passedup &&
+	    (dest[0] & 1) &&
+	    (br->dev.flags & IFF_ALLMULTI || br->dev.mc_list != NULL)) {
+		struct sk_buff *skb2;
+
+		skb2 = skb_clone(skb, GFP_ATOMIC);
+		if (skb2) {
+			passedup = 1;
+			br_pass_frame_up(br, skb2);
+		}
+	}
+
 	if (!memcmp(dest, bridge_ula, 5) && !(dest[5] & 0xF0))
 		goto handle_special_frame;
 
@@ -71,14 +92,16 @@
 
 	if (dest[0] & 1) {
 		br_flood(br, skb, 1);
-		br_pass_frame_up(br, skb);
+		if (!passedup)
+			br_pass_frame_up(br, skb);
 		return;
 	}
 
 	dst = br_fdb_get(br, dest);
 
 	if (dst != NULL && dst->is_local) {
-		br_pass_frame_up(br, skb);
+		if (!passedup)
+			br_pass_frame_up(br, skb);
 		br_fdb_put(dst);
 		return;
 	}
diff -u --recursive --new-file v2.3.47/linux/net/bridge/br_ioctl.c linux/net/bridge/br_ioctl.c
--- v2.3.47/linux/net/bridge/br_ioctl.c	Sun Feb 20 21:12:40 2000
+++ linux/net/bridge/br_ioctl.c	Mon Feb 21 17:35:06 2000
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_ioctl.c,v 1.1 2000/02/18 16:47:12 davem Exp $
+ *	$Id: br_ioctl.c,v 1.2 2000/02/21 15:51:34 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
diff -u --recursive --new-file v2.3.47/linux/net/bridge/br_notify.c linux/net/bridge/br_notify.c
--- v2.3.47/linux/net/bridge/br_notify.c	Sun Feb 20 21:12:40 2000
+++ linux/net/bridge/br_notify.c	Mon Feb 21 17:35:06 2000
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_notify.c,v 1.1 2000/02/18 16:47:12 davem Exp $
+ *	$Id: br_notify.c,v 1.2 2000/02/21 15:51:34 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
diff -u --recursive --new-file v2.3.47/linux/net/bridge/br_stp.c linux/net/bridge/br_stp.c
--- v2.3.47/linux/net/bridge/br_stp.c	Sun Feb 20 21:12:40 2000
+++ linux/net/bridge/br_stp.c	Mon Feb 21 17:35:06 2000
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_stp.c,v 1.1 2000/02/18 16:47:13 davem Exp $
+ *	$Id: br_stp.c,v 1.2 2000/02/21 15:51:34 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
diff -u --recursive --new-file v2.3.47/linux/net/bridge/br_stp_bpdu.c linux/net/bridge/br_stp_bpdu.c
--- v2.3.47/linux/net/bridge/br_stp_bpdu.c	Sun Feb 20 21:12:40 2000
+++ linux/net/bridge/br_stp_bpdu.c	Mon Feb 21 17:35:06 2000
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_stp_bpdu.c,v 1.1 2000/02/18 16:47:13 davem Exp $
+ *	$Id: br_stp_bpdu.c,v 1.2 2000/02/21 15:51:34 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
diff -u --recursive --new-file v2.3.47/linux/net/bridge/br_stp_if.c linux/net/bridge/br_stp_if.c
--- v2.3.47/linux/net/bridge/br_stp_if.c	Sun Feb 20 21:12:40 2000
+++ linux/net/bridge/br_stp_if.c	Mon Feb 21 17:35:06 2000
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_stp_if.c,v 1.1 2000/02/18 16:47:13 davem Exp $
+ *	$Id: br_stp_if.c,v 1.2 2000/02/21 15:51:34 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
diff -u --recursive --new-file v2.3.47/linux/net/bridge/br_stp_timer.c linux/net/bridge/br_stp_timer.c
--- v2.3.47/linux/net/bridge/br_stp_timer.c	Sun Feb 20 21:12:40 2000
+++ linux/net/bridge/br_stp_timer.c	Mon Feb 21 17:35:06 2000
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_stp_timer.c,v 1.1 2000/02/18 16:47:13 davem Exp $
+ *	$Id: br_stp_timer.c,v 1.2 2000/02/21 15:51:35 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
diff -u --recursive --new-file v2.3.47/linux/net/core/dev.c linux/net/core/dev.c
--- v2.3.47/linux/net/core/dev.c	Sun Feb 20 21:12:40 2000
+++ linux/net/core/dev.c	Tue Feb 22 22:34:34 2000
@@ -933,20 +933,19 @@
 void (*br_handle_frame_hook)(struct sk_buff *skb) = NULL;
 #endif
 
-#define HANDLE_BRIDGE(SKB, PT_PREV)					\
-do {									\
-	if ((SKB)->dev->br_port != NULL &&				\
-	    br_handle_frame_hook != NULL) {				\
-		if (PT_PREV)						\
-			if (!(PT_PREV->data))				\
-				deliver_to_old_ones(PT_PREV, SKB, 1);	\
-			else						\
-				pt_prev->func(SKB, SKB->dev, PT_PREV);	\
-									\
-		br_handle_frame_hook(SKB);				\
-		continue;						\
-	}								\
-} while(0)
+static void __inline__ handle_bridge(struct sk_buff *skb,
+				     struct packet_type *pt_prev)
+{
+	if (pt_prev)
+		deliver_to_old_ones(pt_prev, skb, 0);
+	else {
+		atomic_inc(&skb->users);
+		pt_prev->func(skb, skb->dev, pt_prev);
+	}
+
+	br_handle_frame_hook(skb);
+}
+
 
 static void net_rx_action(struct softirq_action *h)
 {
@@ -999,7 +998,11 @@
 			}
 
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-			HANDLE_BRIDGE(skb, pt_prev);
+			if (skb->dev->br_port != NULL &&
+			    br_handle_frame_hook != NULL) {
+				handle_bridge(skb, pt_prev);
+				continue;
+			}
 #endif
 
 			for (ptype=ptype_base[ntohs(type)&15];ptype;ptype=ptype->next) {
@@ -1856,6 +1859,14 @@
 		*dp = dev;
 		dev_hold(dev);
 		write_unlock_bh(&dev_base_lock);
+
+		/*
+		 *	Default initial state at registry is that the
+		 *	device is present.
+		 */
+
+		set_bit(__LINK_STATE_PRESENT, &dev->state);
+
 		return 0;
 	}
 
diff -u --recursive --new-file v2.3.47/linux/net/decnet/af_decnet.c linux/net/decnet/af_decnet.c
--- v2.3.47/linux/net/decnet/af_decnet.c	Sat Feb 12 11:22:11 2000
+++ linux/net/decnet/af_decnet.c	Thu Feb 24 22:14:47 2000
@@ -1837,7 +1837,8 @@
 	scp->persist_fxn = dn_nsp_xmit_timeout;
 
 	while(sent < size) {
-		if ((err = sock_error(sk) != 0))
+		err = sock_error(sk);
+		if (err)
 			goto out;
 
 		if (signal_pending(current)) {
diff -u --recursive --new-file v2.3.47/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v2.3.47/linux/net/ipv4/af_inet.c	Sun Feb 20 21:12:40 2000
+++ linux/net/ipv4/af_inet.c	Mon Feb 21 17:35:06 2000
@@ -5,7 +5,7 @@
  *
  *		PF_INET protocol family socket handler.
  *
- * Version:	$Id: af_inet.c,v 1.107 2000/02/18 16:47:20 davem Exp $
+ * Version:	$Id: af_inet.c,v 1.108 2000/02/21 16:25:59 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -135,7 +135,9 @@
 int (*dlci_ioctl_hook)(unsigned int, void *) = NULL;
 #endif
 
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 int (*br_ioctl_hook)(unsigned long) = NULL;
+#endif
 
 /* New destruction routine */
 
@@ -837,13 +839,14 @@
 			return(devinet_ioctl(cmd,(void *) arg));
 		case SIOCGIFBR:
 		case SIOCSIFBR:
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 #ifdef CONFIG_KMOD
 			if (br_ioctl_hook == NULL)
 				request_module("bridge");
 #endif
 			if (br_ioctl_hook != NULL)
 				return br_ioctl_hook(arg);
-
+#endif
 			return -ENOPKG;
 			
 		case SIOCADDDLCI:
diff -u --recursive --new-file v2.3.47/linux/net/ipv4/igmp.c linux/net/ipv4/igmp.c
--- v2.3.47/linux/net/ipv4/igmp.c	Thu Feb 10 17:11:24 2000
+++ linux/net/ipv4/igmp.c	Sat Feb 26 21:33:30 2000
@@ -8,7 +8,7 @@
  *	the older version didn't come out right using gcc 2.5.8, the newer one
  *	seems to fall out with gcc 2.6.2.
  *
- *	Version: $Id: igmp.c,v 1.37 2000/02/09 11:16:40 davem Exp $
+ *	Version: $Id: igmp.c,v 1.38 2000/02/27 01:20:02 davem Exp $
  *
  *	Authors:
  *		Alan Cox <Alan.Cox@linux.org>
@@ -93,6 +93,7 @@
 #include <net/route.h>
 #include <net/sock.h>
 #include <net/checksum.h>
+#include <linux/netfilter_ipv4.h>
 #ifdef CONFIG_IP_MROUTE
 #include <linux/mroute.h>
 #endif
@@ -185,6 +186,11 @@
 
 #define IGMP_SIZE (sizeof(struct igmphdr)+sizeof(struct iphdr)+4)
 
+static inline int igmp_send_report2(struct sk_buff *skb)
+{
+	return skb->dst->output(skb);
+}
+
 static int igmp_send_report(struct net_device *dev, u32 group, int type)
 {
 	struct sk_buff *skb;
@@ -242,7 +248,8 @@
 	ih->group=group;
 	ih->csum=ip_compute_csum((void *)ih, sizeof(struct igmphdr));
 
-	return skb->dst->output(skb);
+	return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+		       igmp_send_report2);
 }
 
 
diff -u --recursive --new-file v2.3.47/linux/net/ipv4/ipconfig.c linux/net/ipv4/ipconfig.c
--- v2.3.47/linux/net/ipv4/ipconfig.c	Sun Feb 20 21:12:40 2000
+++ linux/net/ipv4/ipconfig.c	Mon Feb 21 17:35:06 2000
@@ -1,5 +1,5 @@
 /*
- *  $Id: ipconfig.c,v 1.26 2000/01/29 07:42:08 davem Exp $
+ *  $Id: ipconfig.c,v 1.27 2000/02/21 15:51:41 davem Exp $
  *
  *  Automatic Configuration of IP -- use BOOTP or RARP or user-supplied
  *  information to configure own IP address and routes.
diff -u --recursive --new-file v2.3.47/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- v2.3.47/linux/net/ipv4/tcp_output.c	Sun Feb 20 21:12:40 2000
+++ linux/net/ipv4/tcp_output.c	Mon Feb 21 17:35:06 2000
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_output.c,v 1.121 2000/02/08 21:27:19 davem Exp $
+ * Version:	$Id: tcp_output.c,v 1.122 2000/02/21 15:51:41 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
diff -u --recursive --new-file v2.3.47/linux/net/irda/ircomm/ircomm_tty.c linux/net/irda/ircomm/ircomm_tty.c
--- v2.3.47/linux/net/irda/ircomm/ircomm_tty.c	Fri Jan  7 19:13:23 2000
+++ linux/net/irda/ircomm/ircomm_tty.c	Tue Feb 22 22:29:00 2000
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 21:00:56 1999
- * Modified at:   Tue Jan  4 14:12:06 2000
+ * Modified at:   Wed Feb 23 00:09:02 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       serial.c and previous IrCOMM work by Takahide Higuchi
  * 
@@ -1079,6 +1079,9 @@
 					   "(), CTS tx start...\n");
 				tty->hw_stopped = 0;
 				
+				/* Wake up processes blocked on open */
+				wake_up_interruptible(&self->open_wait);
+
 				queue_task(&self->tqueue, &tq_immediate);
 				mark_bh(IMMEDIATE_BH);
 				return;
diff -u --recursive --new-file v2.3.47/linux/net/netsyms.c linux/net/netsyms.c
--- v2.3.47/linux/net/netsyms.c	Sun Feb 20 21:12:40 2000
+++ linux/net/netsyms.c	Mon Feb 21 17:35:06 2000
@@ -507,9 +507,6 @@
 #endif
 EXPORT_SYMBOL(dev_ioctl);
 EXPORT_SYMBOL(dev_queue_xmit);
-#ifdef CONFIG_NET_FASTROUTE
-EXPORT_SYMBOL(dev_fastroute_stat);
-#endif
 #ifdef CONFIG_NET_HW_FLOWCONTROL
 EXPORT_SYMBOL(netdev_register_fc);
 EXPORT_SYMBOL(netdev_unregister_fc);
diff -u --recursive --new-file v2.3.47/linux/net/packet/af_packet.c linux/net/packet/af_packet.c
--- v2.3.47/linux/net/packet/af_packet.c	Sun Feb 20 21:12:40 2000
+++ linux/net/packet/af_packet.c	Mon Feb 21 17:35:06 2000
@@ -5,7 +5,7 @@
  *
  *		PACKET - implements raw packet sockets.
  *
- * Version:	$Id: af_packet.c,v 1.31 2000/02/18 16:47:23 davem Exp $
+ * Version:	$Id: af_packet.c,v 1.32 2000/02/21 16:25:55 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -1438,12 +1438,14 @@
 
 		case SIOCGIFBR:
 		case SIOCSIFBR:
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 #ifdef CONFIG_KMOD
 			if (br_ioctl_hook == NULL)
 				request_module("bridge");
 #endif
 			if (br_ioctl_hook != NULL)
 				return br_ioctl_hook(arg);
+#endif
 
 			return -ENOPKG;
 			
diff -u --recursive --new-file v2.3.47/linux/net/sched/sch_atm.c linux/net/sched/sch_atm.c
--- v2.3.47/linux/net/sched/sch_atm.c	Thu Feb 10 17:11:25 2000
+++ linux/net/sched/sch_atm.c	Mon Feb 21 16:32:27 2000
@@ -6,6 +6,7 @@
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/interrupt.h>
 #include <linux/atmdev.h>
 #include <linux/atmclip.h>
 #include <linux/netdevice.h>
@@ -20,7 +21,7 @@
 						   __inline__ in socket.c */
 
 
-#if 1 /* control */
+#if 0 /* control */
 #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
 #else
 #define DPRINTK(format,args...)
@@ -64,6 +65,7 @@
 	struct tcf_proto	*filter_list;
 	struct atm_vcc		*vcc;		/* VCC; NULL if VCC is closed */
 	void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); /* chaining */
+	struct atm_qdisc_data	*parent;	/* parent qdisc */
 	struct socket		*sock;		/* for closing */
 	u32			classid;	/* x:y type ID */
 	int			ref;		/* reference count */
@@ -79,6 +81,7 @@
 	struct atm_flow_data	link;		/* unclassified skbs go here */
 	struct atm_flow_data	*flows;		/* NB: "link" is also on this
 						   list */
+	struct tasklet_struct	task;		/* requeue tasklet */
 };
 
 
@@ -153,6 +156,18 @@
 }
 
 
+static void destroy_filters(struct atm_flow_data *flow)
+{
+	struct tcf_proto *filter;
+
+	while ((filter = flow->filter_list)) {
+		DPRINTK("destroy_filters: destroying filter %p\n",filter);
+		flow->filter_list = filter->next;
+		filter->ops->destroy(filter);
+	}
+}
+
+
 /*
  * atm_tc_put handles all destructions, including the ones that are explicitly
  * requested (atm_tc_destroy, etc.). The assumption here is that we never drop
@@ -164,7 +179,6 @@
 	struct atm_qdisc_data *p = PRIV(sch);
 	struct atm_flow_data *flow = (struct atm_flow_data *) cl;
 	struct atm_flow_data **prev;
-	struct tcf_proto *filter;
 
 	DPRINTK("atm_tc_put(sch %p,[qdisc %p],flow %p)\n",sch,p,flow);
 	if (--flow->ref) return;
@@ -178,14 +192,10 @@
 	*prev = flow->next;
 	DPRINTK("atm_tc_put: qdisc %p\n",flow->q);
 	qdisc_destroy(flow->q);
-	while ((filter = flow->filter_list)) {
-		DPRINTK("atm_tc_put: destroying filter %p\n",filter);
-		flow->filter_list = filter->next;
-		DPRINTK("atm_tc_put: filter %p\n",filter);
-		filter->ops->destroy(filter);
-	}
+	destroy_filters(flow);
 	if (flow->sock) {
-		DPRINTK("atm_tc_put: f_count %d\n",file_count(flow->sock->file));
+		DPRINTK("atm_tc_put: f_count %d\n",
+		    file_count(flow->sock->file));
 		flow->vcc->pop = flow->old_pop;
 		sockfd_put(flow->sock);
 	}
@@ -200,8 +210,11 @@
 
 static void sch_atm_pop(struct atm_vcc *vcc,struct sk_buff *skb)
 {
+	struct atm_qdisc_data *p = VCC2FLOW(vcc)->parent;
+
+	D2PRINTK("sch_atm_pop(vcc %p,skb %p,[qdisc %p])\n",vcc,skb,p);
 	VCC2FLOW(vcc)->old_pop(vcc,skb);
-	mark_bh(NET_BH); /* may allow to send more */
+	tasklet_schedule(&p->task);
 }
 
 
@@ -302,6 +315,7 @@
 	flow->vcc->user_back = flow;
         DPRINTK("atm_tc_change: vcc %p\n",flow->vcc);
 	flow->old_pop = flow->vcc->pop;
+	flow->parent = p;
 	flow->vcc->pop = sch_atm_pop;
 	flow->classid = classid;
 	flow->ref = 1;
@@ -440,21 +454,31 @@
 }
 
 
-static struct sk_buff *atm_tc_dequeue(struct Qdisc *sch)
+/*
+ * Dequeue packets and send them over ATM. Note that we quite deliberately
+ * avoid checking net_device's flow control here, simply because sch_atm
+ * uses its own channels, which have nothing to do with any CLIP/LANE/or
+ * non-ATM interfaces.
+ */
+
+
+static void sch_atm_dequeue(unsigned long data)
 {
+	struct Qdisc *sch = (struct Qdisc *) data;
 	struct atm_qdisc_data *p = PRIV(sch);
 	struct atm_flow_data *flow;
 	struct sk_buff *skb;
 
-	D2PRINTK("atm_tc_dequeue(sch %p,[qdisc %p])\n",sch,p);
+	D2PRINTK("sch_atm_dequeue(sch %p,[qdisc %p])\n",sch,p);
 	for (flow = p->link.next; flow; flow = flow->next)
 		/*
 		 * If traffic is properly shaped, this won't generate nasty
-		 * little bursts. Otherwise, it may ... @@@
+		 * little bursts. Otherwise, it may ... (but that's okay)
 		 */
 		while ((skb = flow->q->dequeue(flow->q))) {
 			if (!atm_may_send(flow->vcc,skb->truesize)) {
-				flow->q->ops->requeue(skb,flow->q);
+				if (flow->q->ops->requeue(skb,flow->q))
+					sch->q.qlen--;
 				break;
 			}
 			sch->q.qlen--;
@@ -469,7 +493,7 @@
 				if (!new) continue;
 				skb = new;
 			}
-			D2PRINTK("atm_tc_dequeue: ip %p, data %p\n",
+			D2PRINTK("sch_atm_dequeue: ip %p, data %p\n",
 			    skb->nh.iph,skb->data);
 			ATM_SKB(skb)->vcc = flow->vcc;
 			memcpy(skb_push(skb,flow->hdr_len),flow->hdr,
@@ -479,6 +503,16 @@
 			/* atm.atm_options are already set by atm_tc_enqueue */
 			(void) flow->vcc->dev->ops->send(flow->vcc,skb);
 		}
+}
+
+
+static struct sk_buff *atm_tc_dequeue(struct Qdisc *sch)
+{
+	struct atm_qdisc_data *p = PRIV(sch);
+	struct sk_buff *skb;
+
+	D2PRINTK("atm_tc_dequeue(sch %p,[qdisc %p])\n",sch,p);
+	tasklet_schedule(&p->task);
 	skb = p->link.q->dequeue(p->link.q);
 	if (skb) sch->q.qlen--;
 	return skb;
@@ -530,6 +564,7 @@
 	p->link.classid = sch->handle;
 	p->link.ref = 1;
 	p->link.next = NULL;
+	tasklet_init(&p->task,sch_atm_dequeue,(unsigned long) sch);
 	MOD_INC_USE_COUNT;
 	return 0;
 }
@@ -554,6 +589,7 @@
 	DPRINTK("atm_tc_destroy(sch %p,[qdisc %p])\n",sch,p);
 	/* races ? */
 	while ((flow = p->flows)) {
+		destroy_filters(flow);
 		if (flow->ref > 1)
 			printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow,
 			    flow->ref);
@@ -565,6 +601,7 @@
 			break;
 		}
 	}
+	tasklet_kill(&p->task);
 	MOD_DEC_USE_COUNT;
 }
 
diff -u --recursive --new-file v2.3.47/linux/net/sched/sch_cbq.c linux/net/sched/sch_cbq.c
--- v2.3.47/linux/net/sched/sch_cbq.c	Sun Feb 20 21:12:40 2000
+++ linux/net/sched/sch_cbq.c	Mon Feb 21 16:32:27 2000
@@ -878,7 +878,7 @@
 
 		/* Start round */
 		do {
-			struct cbq_class *borrow = NULL;
+			struct cbq_class *borrow = cl;
 
 			if (cl->q->q.qlen &&
 			    (borrow = cbq_under_limit(cl)) == NULL)
diff -u --recursive --new-file v2.3.47/linux/net/sched/sch_dsmark.c linux/net/sched/sch_dsmark.c
--- v2.3.47/linux/net/sched/sch_dsmark.c	Tue Feb  1 01:35:44 2000
+++ linux/net/sched/sch_dsmark.c	Mon Feb 21 16:32:27 2000
@@ -278,10 +278,16 @@
 
 static int dsmark_requeue(struct sk_buff *skb,struct Qdisc *sch)
 {
+	int ret;
 	struct dsmark_qdisc_data *p = PRIV(sch);
 
 	D2PRINTK("dsmark_requeue(skb %p,sch %p,[qdisc %p])\n",skb,sch,p);
-	return p->q->ops->requeue(skb,p->q);
+        if ((ret = p->q->ops->requeue(skb, p->q)) == 0) {
+		sch->q.qlen++;
+		return 0;
+	}
+	sch->stats.drops++;
+	return ret;
 }
 
 
diff -u --recursive --new-file v2.3.47/linux/net/wanrouter/wanproc.c linux/net/wanrouter/wanproc.c
--- v2.3.47/linux/net/wanrouter/wanproc.c	Thu Feb 10 17:11:25 2000
+++ linux/net/wanrouter/wanproc.c	Sat Feb 26 20:33:10 2000
@@ -95,25 +95,11 @@
 
 static struct inode_operations router_inode =
 {
-	&router_fops,
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* truncate */
-	router_proc_perms,	/* permission */
-	NULL			/* revalidate */
+	permission:	router_proc_perms,
 };
 
 /*
- *	/proc/net/router/<device> file and inode operations
+ *	/proc/net/router/<device> file operations
  */
 
 static struct file_operations wandev_fops =
@@ -122,25 +108,6 @@
 	ioctl:		wanrouter_ioctl,
 };
 
-static struct inode_operations wandev_inode =
-{
-	&wandev_fops,
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* truncate */
-	router_proc_perms,	/* permission */
-	NULL			/* revalidate */
-};
-
 /*
  *	/proc/net/router 
  */
@@ -175,12 +142,14 @@
 	p = create_proc_entry("config",0,proc_router);
 	if (!p)
 		goto fail_config;
-	p->ops = &router_inode;
+	p->proc_fops = &router_fops;
+	p->proc_iops = &router_inode;
 	p->get_info = config_get_info;
 	p = create_proc_entry("status",0,proc_router);
 	if (!p)
 		goto fail_stat;
-	p->ops = &router_inode;
+	p->proc_fops = &router_fops;
+	p->proc_iops = &router_inode;
 	p->get_info = status_get_info;
 	return 0;
 fail_stat:
@@ -214,7 +183,8 @@
 	wandev->dent = create_proc_entry(wandev->name, 0, proc_router);
 	if (!wandev->dent)
 		return -ENOMEM;
-	wandev->dent->ops	= &wandev_inode;
+	wandev->dent->proc_fops	= &wandev_fops;
+	wandev->dent->proc_iops	= &router_inode;
 	wandev->dent->get_info	= wandev_get_info;
 	wandev->dent->data	= wandev;
 	return 0;
